Error Handling
The API uses standard HTTP status codes and returns detailed error information in the response body.
HTTP Status Codes
| Code | Description |
|---|
200 | Success |
201 | Created |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid or missing API key |
403 | Forbidden - Insufficient permissions |
404 | Not Found - Resource doesn’t exist |
409 | Conflict - Resource already exists |
422 | Unprocessable Entity - Validation failed |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error |
{
"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
| Code | Description |
|---|
INVALID_API_KEY | The API key is invalid or revoked |
MISSING_API_KEY | No API key provided in request |
API_KEY_EXPIRED | The API key has expired |
Validation Errors
| Code | Description |
|---|
VALIDATION_ERROR | Request parameters failed validation |
INVALID_CURRENCY | Unsupported currency code |
INVALID_AMOUNT | Amount is out of allowed range |
INVALID_WALLET_ADDRESS | Wallet address format is invalid |
Resource Errors
| Code | Description |
|---|
QUOTE_NOT_FOUND | Quote ID doesn’t exist |
QUOTE_EXPIRED | Quote has expired |
ORDER_NOT_FOUND | Order ID doesn’t exist |
CUSTOMER_NOT_FOUND | Customer doesn’t exist |
WALLET_NOT_FOUND | Wallet doesn’t exist |
Business Logic Errors
| Code | Description |
|---|
KYC_REQUIRED | Customer must complete KYC |
KYC_PENDING | KYC verification in progress |
KYC_REJECTED | Customer KYC was rejected |
WALLET_BLOCKED | Wallet failed AML screening |
LIMIT_EXCEEDED | Transaction limit exceeded |
INSUFFICIENT_FUNDS | Not enough funds for transaction |
Rate Limiting
| Code | Description |
|---|
RATE_LIMIT_EXCEEDED | Too 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.