code field to decide what to do next, and keep the requestId for support requests. The catalog below covers the most common codes and is not exhaustive, so handle unknown codes gracefully.
Error response
ErrorResponse
interface ErrorResponse {
requestId: string
timestamp: string
path: string
status: number
code: string
message: string
validationErrors?: { param: string; message: string }[]
}
Example
{
"requestId": "9f6f9741-4c65-4e0b-a48f-16d5b34d9e2f",
"timestamp": "2026-07-31T10:30:45.123Z",
"path": "/transactions/on-ramp",
"status": 403,
"code": "KYC_NOT_APPROVED",
"message": "KYC/B is not approved for this customer"
}
| Field | Description |
|---|---|
requestId | Unique request ID. Include it when contacting support. |
timestamp | ISO 8601 time the error was generated. |
path | Path of the request that failed. |
status | HTTP status code. |
code | Machine-readable error code. Match on this field. |
message | Human-readable description. |
validationErrors | Field-level details. Only present on VALIDATION_ERROR. |
Handle errors by
code and not by message. The message is subject to changes. On any 5xx response the message is always "An unexpected error occurred.", while the code stays specific.Validation errors
When the request body fails validation, the response is a400 with code VALIDATION_ERROR and one entry per invalid field in validationErrors.
Response
{
"requestId": "9f6f9741-4c65-4e0b-a48f-16d5b34d9e2f",
"timestamp": "2026-07-31T10:30:45.123Z",
"path": "/customers",
"status": 400,
"code": "VALIDATION_ERROR",
"message": "The request body contains invalid parameters.",
"validationErrors": [
{ "param": "taxId", "message": "taxId must be a string" }
]
}
Error codes
General
| Code | Status | When it happens |
|---|---|---|
VALIDATION_ERROR | 400 | Request body failed validation. Details in validationErrors. |
BAD_REQUEST | 400 | Request is invalid without a more specific code. |
UNAUTHORIZED | 401 | API key is missing, invalid, or inactive. |
FORBIDDEN | 403 | API key lacks the scope required by the route. |
RESOURCE_PROJECT_MISMATCH | 403 | Resource exists but belongs to another project. |
NOT_FOUND | 404 | Resource does not exist. |
CONFLICT | 409 | Request conflicts with the current resource state. |
RESOURCE_ALREADY_EXISTS | 409 | A resource with the same unique value already exists. |
UNPROCESSABLE_ENTITY | 422 | Request violates a business rule. |
TOO_MANY_REQUESTS | 429 | Rate limit exceeded. |
INTERNAL_SERVER_ERROR | 500 | Unexpected server error. |
NOT_IMPLEMENTED | 501 | Operation not supported by the active provider. |
Customers
| Code | Status | When it happens |
|---|---|---|
CUSTOMER_NOT_FOUND | 404 | Customer does not exist. |
CUSTOMER_LIMIT_REACHED | 403 | Project reached its maximum number of customers. |
CUSTOMER_UPDATE_FAILED | 500 | Customer update failed. |
WALLET_CREATION_FAILED | 500 | Wallet creation failed. |
WALLET_NOT_FOUND | 404 | Customer has no wallet on the requested blockchain. |
KYC_NOT_APPROVED | 403 | Customer identity verification (KYC/KYB) is not approved. |
INVALID_OR_EXPIRED_TOKEN | 401 | Terms of service token is invalid or expired. |
Accounts
| Code | Status | When it happens |
|---|---|---|
ACCOUNT_NOT_FOUND | 404 | Account does not exist. |
ACCOUNT_NOT_ACTIVE | 409 | Account is not in a usable state. |
ACCOUNT_ALREADY_EXISTS | 409 | Customer already has an account in that currency. |
ACCOUNT_CREATION_FAILED | 500 | Account creation failed. |
ACCOUNT_CUSTOMER_MISMATCH | 400 | Account does not belong to the given customer. |
NO_SOURCE_ACCOUNT_TO_PROVISION | 404 | No existing account to use as the provisioning source. |
Destinations
| Code | Status | When it happens |
|---|---|---|
DESTINATION_NOT_FOUND | 404 | Destination does not exist. |
RAIL_NOT_ENABLED | 403 | Rail is not enabled for this project. |
HOLDER_TYPE_MISMATCH | 403 | holderType differs from the customer type on SELF destinations. |
HOLDER_TAX_ID_MISMATCH | 403 | holderTaxId differs from the customer tax ID on SELF destinations. |
Transactions
| Code | Status | When it happens |
|---|---|---|
TRANSACTION_NOT_FOUND | 404 | Transaction does not exist. |
INSUFFICIENT_BALANCE | 422 | Balance is too low for the operation. |
TRANSACTION_LIMIT_EXCEEDED | 422 | Exceeds the customer’s single, daily, or monthly limit. |
PERSONAL_ACCOUNT_RELATIONSHIP_REQUIRED | 400 | Personal transactions require a SELF bank account. |
TRANSACTION_CREATION_FAILED | 500 | Transaction creation failed. |
INSOLVENT_TRADE | 422 | Trade cannot be settled at the moment. |
INVALID_PAYMENT_DESTINATION | 400 | Payment destination is invalid. |
INVALID_TAX_ID | 400 | Tax ID was rejected by bank validation. |
INVALID_AMOUNT | 400 | Amount was rejected by bank validation. |
Exchange rates
| Code | Status | When it happens |
|---|---|---|
EXCHANGE_RATE_NOT_FOUND | 404 | Exchange rate does not exist. |
EXCHANGE_RATE_EXPIRED | 422 | Locked rate has expired. |
EXCHANGE_RATE_ALREADY_USED | 422 | Rate was already consumed by another transaction. |
EXCHANGE_RATE_CURRENCY_MISMATCH | 422 | Rate currency does not match the transaction type. |
MINIMUM_AMOUNT_NOT_MET | 422 | Amount is below the supported minimum for the currency. |
EXCHANGE_RATE_FETCH_FAILED | 500 | Fetching or locking the rate failed. |
NO_LIQUIDITY_PROVIDER | 422 | No liquidity available for this trade. |
Autoconversion
| Code | Status | When it happens |
|---|---|---|
AUTOCONVERSION_RULE_NOT_FOUND | 404 | Autoconversion rule does not exist. |
INVALID_AUTOCONVERSION_RULE | 400 | Autoconversion rule is invalid. |
NO_DEPOSIT_HANDLER | 400 | No deposit handler matches the rule. |
Partner fees
| Code | Status | When it happens |
|---|---|---|
PARTNER_FEE_NOT_FOUND | 404 | Partner fee does not exist. |
INVALID_WALLET_ADDRESS | 400 | Partner wallet address is invalid for the blockchain. |
Idempotency
| Code | Status | When it happens |
|---|---|---|
IDEMPOTENCY_KEY_CONFLICT | 409 | Same Idempotency-Key reused with a different body. |
IDEMPOTENCY_KEY_IN_FLIGHT | 409 | A request with that key is still processing. |
Service availability
| Code | Status | When it happens |
|---|---|---|
UPSTREAM_SERVICE_ERROR | 500 or 502 | An internal dependency failed. |
TIMEOUT_ERROR | 503 | Provider call timed out. Safe to retry. |
NETWORK_ERROR | 503 | Network failure reaching the provider. Safe to retry. |
SERVICE_UNAVAILABLE | 503 | Provider is unavailable. Safe to retry. |
INVALID_REQUEST | 400 | Provider rejected the request data. Not retryable. |