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

# API error codes

> HTTP status codes and errorCode values returned when a request itself fails.

Zerocash uses standard HTTP status codes. For client errors (`4xx`) and server errors (`5xx`), the
response body carries a specific `errorCode` and a descriptive `message`.

```json Example error response theme={null}
{
  "success": false,
  "message": "External reference already in use.",
  "errorCode": "DUPLICATE_EXTERNAL_REFERENCE"
}
```

<Tip>
  Branch your error handling on `errorCode`, not on `message`. Messages are written for humans and
  may be reworded; codes are stable.
</Tip>

<Note>
  These are errors with the **request**. A request that succeeds can still produce a transaction
  that later fails — those reasons are on the
  [transaction error codes](/guides/errors/transaction-error-codes) page.
</Note>

## Common errors

Returned by multiple endpoints.

| HTTP | Error code                     | Description                                                                                  |
| :--- | :----------------------------- | :------------------------------------------------------------------------------------------- |
| 403  | `USER_NOT_ONBOARDED`           | Your account has not completed the onboarding or approval process required for this feature. |
| 409  | `DUPLICATE_EXTERNAL_REFERENCE` | The `externalReference` has already been used. It must be unique per transaction.            |
| 422  | `INSUFFICIENT_FUNDS`           | Your wallet balance is too low to complete the debit.                                        |
| 503  | `FX_RATE_UNAVAILABLE`          | A currency conversion rate could not be retrieved. Usually safe to retry.                    |
| 500  | `INTERNAL_SERVER_ERROR`        | An unexpected error on our side. Report it if it persists.                                   |

<Warning>
  A `409 DUPLICATE_EXTERNAL_REFERENCE` is a safety feature, not a bug. It means the transaction
  already exists — look it up with
  [Get Transaction](/api-reference/endpoint/get-transaction) using that reference rather than
  retrying with a new one, or you risk paying twice.
</Warning>

## Payout errors

| HTTP | Error code                     | Description                                                                                          |
| :--- | :----------------------------- | :--------------------------------------------------------------------------------------------------- |
| 403  | `CURRENCY_NOT_ENABLED`         | That currency is not enabled for payouts on your account.                                            |
| 404  | `PAYOUT_PROVIDER_NOT_FOUND`    | No provider could be found for that currency and destination.                                        |
| 422  | `DEBIT_CURRENCY_NOT_SUPPORTED` | The `debitCurrency` / `currency` combination is not allowed, e.g. debiting NGN for a non-NGN payout. |
| 422  | `MOMO_CODE_REQUIRED`           | A `payoutMethod.code` operator code is required for mobile money payouts in this region.             |

## Collection errors

| HTTP | Error code                      | Description                                                                                       |
| :--- | :------------------------------ | :------------------------------------------------------------------------------------------------ |
| 400  | `MOMO_OPERATOR_ID_REQUIRED`     | The provider requires a `momoOperatorId` but none was supplied.                                   |
| 403  | `CURRENCY_NOT_ENABLED`          | That currency is not enabled for collections on your account.                                     |
| 403  | `METHOD_NOT_ENABLED`            | That method is not enabled for that currency on your account.                                     |
| 404  | `PROVIDER_NOT_FOUND`            | No collection provider matches the currency, method, operator, country, and amount.               |
| 404  | `COUNTRY_CODE_NOT_FOUND`        | The phone number prefix does not match a supported XOF country.                                   |
| 422  | `UNSUPPORTED_CURRENCY`          | The currency is not supported for collections.                                                    |
| 422  | `MOMO_CODE_REQUIRED`            | The charge method does not support the selected currency, e.g. bank transfer for TZS.             |
| 422  | `WALLET_CURRENCY_NOT_SUPPORTED` | The `walletCurrency` / `chargeCurrency` combination is not supported for cross-currency deposits. |

## Handling errors well

<AccordionGroup>
  <Accordion title="Which errors are worth retrying" icon="rotate">
    | Retryable               | Not retryable                                |
    | :---------------------- | :------------------------------------------- |
    | `FX_RATE_UNAVAILABLE`   | `USER_NOT_ONBOARDED`                         |
    | `INTERNAL_SERVER_ERROR` | `DUPLICATE_EXTERNAL_REFERENCE`               |
    | 503 responses generally | `CURRENCY_NOT_ENABLED`, `METHOD_NOT_ENABLED` |
    |                         | `UNSUPPORTED_CURRENCY`, `PROVIDER_NOT_FOUND` |

    Retry the first group with exponential backoff. The second group will fail identically no
    matter how many times you send them — fix the request or your account configuration instead.
  </Accordion>

  <Accordion title="Retry with the same externalReference" icon="fingerprint">
    When you do retry, reuse the original `externalReference`. That is what makes the retry safe:
    if the first attempt actually landed, you get a `409` instead of a second transaction.
  </Accordion>

  <Accordion title="Validate before you send" icon="circle-check">
    Most `403` and `422` errors are avoidable. Check
    [supported countries & limits](/guides/supported-countries), fetch operator and bank codes from
    the reference endpoints, and resolve accounts with
    [Account Resolver](/api-reference/endpoint/account-resolver) first.
  </Accordion>

  <Accordion title="Check service health" icon="heart-pulse">
    Before assuming an integration bug, check
    [Currency Uptime](/api-reference/endpoint/currency-uptime-checker) — a corridor may simply be
    degraded.
  </Accordion>
</AccordionGroup>
