Skip to main content

Error Handling

The API uses standard HTTP status codes and returns detailed error information in the response body.

HTTP Status Codes

CodeDescription
200Success
201Created
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found - Resource doesn’t exist
409Conflict - Resource already exists
422Unprocessable Entity - Validation failed
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Error Response Format

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": [
      {
        "field": "fieldName",
        "message": "Field-specific error"
      }
    ],
    "requestId": "req_abc123"
  }
}

Common Error Codes

Authentication Errors

CodeDescription
INVALID_API_KEYThe API key is invalid or revoked
MISSING_API_KEYNo API key provided in request
API_KEY_EXPIREDThe API key has expired

Validation Errors

CodeDescription
VALIDATION_ERRORRequest parameters failed validation
INVALID_CURRENCYUnsupported currency code
INVALID_AMOUNTAmount is out of allowed range
INVALID_WALLET_ADDRESSWallet address format is invalid

Resource Errors

CodeDescription
QUOTE_NOT_FOUNDQuote ID doesn’t exist
QUOTE_EXPIREDQuote has expired
ORDER_NOT_FOUNDOrder ID doesn’t exist
CUSTOMER_NOT_FOUNDCustomer doesn’t exist
WALLET_NOT_FOUNDWallet doesn’t exist

Business Logic Errors

CodeDescription
KYC_REQUIREDCustomer must complete KYC
KYC_PENDINGKYC verification in progress
KYC_REJECTEDCustomer KYC was rejected
WALLET_BLOCKEDWallet failed AML screening
LIMIT_EXCEEDEDTransaction limit exceeded
INSUFFICIENT_FUNDSNot enough funds for transaction

Rate Limiting

CodeDescription
RATE_LIMIT_EXCEEDEDToo many requests

Handling Errors

JavaScript Example

async function createOrder(quoteId) {
  try {
    const response = await fetch('/v1/orders', {
      method: 'POST',
      headers: {
        'X-API-Key': apiKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ quoteId }),
    });

    const data = await response.json();

    if (!data.success) {
      switch (data.error.code) {
        case 'QUOTE_EXPIRED':
          // Fetch a new quote
          return refreshQuoteAndRetry();
        case 'KYC_REQUIRED':
          // Redirect to KYC flow
          return redirectToKyc();
        case 'WALLET_BLOCKED':
          // Show wallet blocked message
          return showWalletBlockedError();
        default:
          throw new Error(data.error.message);
      }
    }

    return data.data;
  } catch (error) {
    console.error('API Error:', error);
    throw error;
  }
}

Retry Strategy

For transient errors (5xx, network issues), implement exponential backoff:
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);

      if (response.status >= 500) {
        throw new Error('Server error');
      }

      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;

      const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}
Always include the requestId from error responses when contacting support.