> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zapyd.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error codes

> Every err_code the API returns, what it means and how to fix it.

Every error response carries an `err_code`. Branch on it, not on `message`. When a field is wrong, `errors` names it.

```json theme={"theme":{"light":"css-variables","dark":"css-variables"}}
{
  "status": false,
  "message": "Bad Request",
  "data": null,
  "err_code": "REQ_FIELD_MISSING",
  "errors": { "customer_id": ["This field is required."] }
}
```

<Columns cols={3}>
  <Card title="Fix and resend" icon="pen-to-square">
    Most `400` and `401` codes. Sending the same request again won't help.
  </Card>

  <Card title="Retry with backoff" icon="rotate-right">
    `429`, `500`, `503` and `NET_TIMEOUT`. Wait 1s, double each time, stop after 3 to 5 tries.
  </Card>

  <Card title="Stop and escalate" icon="hand">
    `RISK_AML_FAILED`, or a `5xx` that keeps coming back. Contact [support@zapyd.com](mailto:support@zapyd.com).
  </Card>
</Columns>

For retry timing and what to show users, see [Error handling](/guides/development-and-testing/error-handling).

## General

Any endpoint can return these.

| Code | HTTP | Meaning | What to do |
| - | - | - | - |
| `AUTH_MISSING_HEADERS` | 401 | Missing authentication headers | Send `X-API-KEY`, `X-TIMESTAMP` and `X-SIGNATURE` on every request. |
| `AUTH_INVALID_SIGNATURE` | 401 | Invalid signature | Rebuild the signature from the API key, timestamp and canonical body. GET requests sign `{}`. See [Authentication](/api-reference-exchange/overview/authentication). |
| `AUTH_UNAUTHORIZED` | 401 | Unauthorized | Check the API key is active and belongs to this environment (sandbox or production). |
| `NOT_FOUND` | 404 | Not found | Check the path, including the module prefix such as `/cms/api/v1`. |
| `TOO_MANY_REQUESTS` | 429 | Too many requests | Back off and retry. |
| `NET_TIMEOUT` | 400 | Request timed out | Retry with backoff. Before retrying an initiate call, check the order history so you don't create the order twice. |
| `UNKNOWN_ERROR` | 400 | Unknown error | Retry once. If it repeats, contact support with the request time. |
| `SYS_INTERNAL_ERROR` | 500 | Internal server error | Retry with backoff. If it persists, contact support with the request time. |
| `SYS_SERVICE_UNAVAILABLE` | 503 | Service unavailable | Retry with backoff. |

## Request validation

Every code from here down returns HTTP `400`.

| Code | Meaning | What to do |
| - | - | - |
| `REQ_FIELD_MISSING` | Mandatory field is missing | `errors` lists the missing fields. Add them. |
| `INPUT_MALFORMED` | Malformed input | `errors` lists the fields with a blank, badly formatted or too-long value. |
| `INPUT_MALFORMED_ADDITIONAL_INFO` | Malformed `additional_info` | Fix the shape of the `additional_info` object. |
| `INPUT_INVALID_DATE_FORMAT` | Invalid date format | Send dates in the format the endpoint documents. |
| `INPUT_INVALID_PARAMETER` | Invalid user ID | Check the `customer_id` you sent. |
| `REQ_INVALID_COUNTRY` | Invalid country code | Send an ISO 3166 alpha-3 code, such as `IND`. |
| `REQ_INVALID_RESIDENCE_COUNTRY` | Invalid residence country code | Send an ISO 3166 alpha-3 code for the country of residence. |
| `REQ_NON_RESIDENT_UNSUPPORTED` | Non-residents not supported | The customer must live in the country they onboard in. |

## Customers

| Code | Meaning | What to do |
| - | - | - |
| `USR_NOT_FOUND` | Customer not found | Check the `customer_id`. |
| `AUTH_ORG_MISMATCH` | Customer belongs to another organization | Use IDs created with your own API key, in the same environment. |
| `USR_DUPLICATE_CONTACT` | Phone or email is linked to another customer | Look up the existing customer, or use different contact details. |
| `USR_UNVERIFIED` | Customer is unverified | Finish [KYC](/guides/customers/overview) first. The customer must be `VERIFIED`. |

## KYC

| Code | Meaning | What to do |
| - | - | - |
| `KYC_INVALID_AADHAAR_INPUT` | Aadhaar input is incomplete | Send both `document_front_image_url` and `document_back_image_url`, or `aadhaar_json` inside `additional_data`. |
| `KYC_INVALID_DOC_TYPE` | Document type not supported for the country | Pick a type from [Fetch KYC Configuration](/api-reference-exchange/endpoint/kyc/configuration-\{customer_id}). |
| `KYC_IN_USE` | These KYC details belong to another customer | Each identity can verify only one customer. |
| `KYC_UPDATE_LIMIT_EXCEEDED` | KYC update limit reached | Contact support to update this customer again. |

## Bank accounts

| Code | Meaning | What to do |
| - | - | - |
| `BANK_DUPLICATE_ACCOUNT` | UPI ID or account number is already in use | An account can belong to one customer only. |
| `BANK_LIMIT_REACHED` | 3 accounts already added | A customer can have 3 active accounts per rail. [Delete one](/api-reference-exchange/endpoint/bank/delete) first. |
| `BANK_NOT_FOUND` | Bank account not found, or not this customer's | Check the `bank_id` belongs to this `customer_id`. |
| `BANK_ACCOUNT_UNVERIFIED` | Bank account is unverified | Wait for the `BANK` webhook. In sandbox, use [Mock Bank Verification](/api-reference-exchange/endpoint/bank/mock-bank-verification). |
| `BANK_MODE_MISMATCH` | Bank account doesn't match the payment method | Use a bank account on the same rail as `payment_method`. |

## Orders

Payins and payouts share these codes with a `PAYIN_` or `PAYOUT_` prefix.

| Code | Meaning | What to do |
| - | - | - |
| `PAYIN_AMOUNT_ZERO_OR_NEGATIVE`<br />`PAYOUT_AMOUNT_ZERO_OR_NEGATIVE` | Amount is zero or negative | Send a positive amount. |
| `PAYIN_AMOUNT_BELOW_MIN`<br />`PAYOUT_AMOUNT_BELOW_MIN` | Amount is below the minimum | Read the minimum from the configuration endpoint. |
| `PAYIN_AMOUNT_ABOVE_MAX`<br />`PAYOUT_AMOUNT_ABOVE_MAX` | Amount is above the maximum | Read the maximum from the configuration endpoint, or split the order. |
| `PAYIN_DUPLICATE_CLIENT_REF_ID`<br />`PAYOUT_DUPLICATE_CLIENT_REF_ID` | `client_reference_id` already exists | The order already exists. Fetch it from history instead of creating it again. |
| `PAYIN_QUOTATION_NOT_FOUND`<br />`PAYOUT_QUOTATION_NOT_FOUND` | Quotation not found | Check the `quotation_id`. |
| `PAYIN_QUOTATION_LINKED`<br />`PAYOUT_QUOTATION_LINKED` | Quotation is linked to another order | Each quotation backs one order. Create a new quotation. |
| `PAYIN_QUOTATION_EXPIRED`<br />`PAYOUT_QUOTATION_EXPIRED` | Quotation has expired | Create a new quotation and initiate before its `expiry_time`. |
| `PAYOUT_INVALID_PAYOUT_ID` | Invalid payout ID | Check the `payout_id`. |
| `PAYIN_DUPLICATE_UTR` | UTR is linked to another payin | Each bank transfer reference can fund one payin. |
| `PAYIN_INVALID_UTR_FORMAT` | Invalid UTR format | See [Understanding UTR](/guides/country-guides/india/understanding-utr) for the format per rail. |

## Risk and compliance

| Code | Meaning | What to do |
| - | - | - |
| `RISK_EDD_REQUIRED` | Enhanced due diligence required | Submit EDD, then retry once it's approved. See [Limits and EDD](/guides/payments/limits-and-edd). |
| `RISK_DAILY_LIMIT_EXCEEDED` | Daily limit exhausted | Check the customer's limits endpoint, and try again the next day. |
| `RISK_IP_CHECK_FAILED` | IP address check failed | Send the end user's own IP address in `risk_parameters`. |
| `RISK_AML_FAILED` | AML screening failed | The customer can't transact. Don't retry. Contact support if you think this is wrong. |

## By endpoint

Every endpoint can also return the [general](#general) codes, including `SYS_INTERNAL_ERROR`.

<AccordionGroup>
  <Accordion title="Customers" icon="user">
    | Endpoint | Codes |
    | - | - |
    | `POST /customer/create` | [`REQ_INVALID_COUNTRY`](#request-validation), [`REQ_NON_RESIDENT_UNSUPPORTED`](#request-validation), [`REQ_INVALID_RESIDENCE_COUNTRY`](#request-validation), [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`USR_DUPLICATE_CONTACT`](#customers) |
    | `GET /customer/{customer_id}` | [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers) |
    | `GET /customer/list` | [`INPUT_INVALID_DATE_FORMAT`](#request-validation) |
  </Accordion>

  <Accordion title="KYC" icon="id-card">
    | Endpoint | Codes |
    | - | - |
    | `GET /kyc/configuration/{customer_id}` | [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers) |
    | `POST /kyc/add-kyc-data` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers), [`KYC_INVALID_AADHAAR_INPUT`](#kyc), [`KYC_INVALID_DOC_TYPE`](#kyc), [`KYC_IN_USE`](#kyc), [`INPUT_MALFORMED_ADDITIONAL_INFO`](#request-validation) |
    | `PATCH /kyc/update-tax-info` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers), [`KYC_IN_USE`](#kyc) |
    | `PATCH /kyc/update-document-info` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers), [`KYC_IN_USE`](#kyc), [`KYC_INVALID_AADHAAR_INPUT`](#kyc), [`KYC_INVALID_DOC_TYPE`](#kyc) |
    | `PATCH /kyc/update-selfie-info` | [`REQ_FIELD_MISSING`](#request-validation), [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers), [`INPUT_MALFORMED_ADDITIONAL_INFO`](#request-validation), [`KYC_UPDATE_LIMIT_EXCEEDED`](#kyc) |
  </Accordion>

  <Accordion title="Bank accounts" icon="building-columns">
    | Endpoint | Codes |
    | - | - |
    | `POST /bank/create` | [`REQ_FIELD_MISSING`](#request-validation), [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers), [`USR_UNVERIFIED`](#customers), [`BANK_DUPLICATE_ACCOUNT`](#bank-accounts), [`BANK_LIMIT_REACHED`](#bank-accounts) |
    | `GET /bank/{customer_id}/{bank_id}` | [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers), [`BANK_NOT_FOUND`](#bank-accounts) |
    | `GET /bank/list/{customer_id}` | [`USR_NOT_FOUND`](#customers), [`AUTH_ORG_MISMATCH`](#customers) |
  </Accordion>

  <Accordion title="Payouts" icon="arrow-trend-down">
    | Endpoint | Codes |
    | - | - |
    | `GET /payout/configuration` | General codes only |
    | `GET /payout/limits/{customer_id}` | [`USR_UNVERIFIED`](#customers) |
    | `GET /payout/fetch-rate` | [`REQ_FIELD_MISSING`](#request-validation) |
    | `POST /payout/quotation` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`USR_UNVERIFIED`](#customers), [`PAYOUT_AMOUNT_ZERO_OR_NEGATIVE`](#orders), [`PAYOUT_AMOUNT_BELOW_MIN`](#orders), [`PAYOUT_AMOUNT_ABOVE_MAX`](#orders), [`RISK_AML_FAILED`](#risk-and-compliance), [`RISK_IP_CHECK_FAILED`](#risk-and-compliance), [`RISK_DAILY_LIMIT_EXCEEDED`](#risk-and-compliance), [`RISK_EDD_REQUIRED`](#risk-and-compliance), [`BANK_ACCOUNT_UNVERIFIED`](#bank-accounts), [`BANK_NOT_FOUND`](#bank-accounts), [`SYS_SERVICE_UNAVAILABLE`](#general) |
    | `GET /payout/quotation/{quotation_id}` | [`REQ_FIELD_MISSING`](#request-validation) |
    | `POST /payout/initiate` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`PAYOUT_DUPLICATE_CLIENT_REF_ID`](#orders), [`PAYOUT_QUOTATION_NOT_FOUND`](#orders), [`PAYOUT_QUOTATION_LINKED`](#orders), [`PAYOUT_QUOTATION_EXPIRED`](#orders) |
    | `GET /payout/{payout_id}` | [`REQ_FIELD_MISSING`](#request-validation), [`PAYOUT_INVALID_PAYOUT_ID`](#orders) |
    | `GET /payout/history` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `POST /payout/edd/save` | [`USR_UNVERIFIED`](#customers), [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `GET /payout/edd/list` | [`INPUT_INVALID_PARAMETER`](#request-validation) |
  </Accordion>

  <Accordion title="Payins" icon="arrow-trend-up">
    | Endpoint | Codes |
    | - | - |
    | `GET /payin/configuration` | General codes only |
    | `GET /payin/limits/{customer_id}` | [`USR_UNVERIFIED`](#customers) |
    | `GET /payin/fetch-rate` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `POST /payin/quotation` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`USR_UNVERIFIED`](#customers), [`PAYIN_AMOUNT_ZERO_OR_NEGATIVE`](#orders), [`PAYIN_AMOUNT_BELOW_MIN`](#orders), [`PAYIN_AMOUNT_ABOVE_MAX`](#orders), [`RISK_AML_FAILED`](#risk-and-compliance), [`RISK_IP_CHECK_FAILED`](#risk-and-compliance), [`RISK_DAILY_LIMIT_EXCEEDED`](#risk-and-compliance), [`RISK_EDD_REQUIRED`](#risk-and-compliance), [`BANK_ACCOUNT_UNVERIFIED`](#bank-accounts), [`BANK_NOT_FOUND`](#bank-accounts), [`BANK_MODE_MISMATCH`](#bank-accounts), [`SYS_SERVICE_UNAVAILABLE`](#general) |
    | `GET /payin/quotation/{quotation_id}` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `POST /payin/initiate` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation), [`PAYIN_DUPLICATE_CLIENT_REF_ID`](#orders), [`PAYIN_QUOTATION_NOT_FOUND`](#orders), [`PAYIN_QUOTATION_LINKED`](#orders), [`PAYIN_QUOTATION_EXPIRED`](#orders), [`PAYIN_DUPLICATE_UTR`](#orders), [`PAYIN_INVALID_UTR_FORMAT`](#orders) |
    | `GET /payin/{payin_id}` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `GET /payin/history` | [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `POST /payin/edd/save` | [`USR_UNVERIFIED`](#customers), [`REQ_FIELD_MISSING`](#request-validation), [`INPUT_MALFORMED`](#request-validation) |
    | `GET /payin/edd/list` | [`INPUT_INVALID_PARAMETER`](#request-validation) |
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.