Errors
All errors return a consistent JSON structure:
json
{
"status": 400,
"error": "Bad Request",
"message": "Human-readable description of what went wrong",
"timestamp": "2026-04-04T14:30:00Z"
}Error codes
| HTTP | Error | Meaning | Resolution |
|---|---|---|---|
| 400 | Bad Request | Invalid parameters or malformed request | Check request body and parameters |
| 400 | INVALID_ADDRESS | Address format not recognized for chain | Verify address format matches chain (e.g., 0x... for EVM, T... for TRON) |
| 400 | CHAIN_NOT_SUPPORTED | Chain not in supported list | See supported chains |
| 401 | Unauthorized | Missing or invalid API key | Check X-API-Key header |
| 402 | Payment Required | Monthly credit limit reached | Purchase credits or upgrade plan |
| 402 | UPGRADE_REQUIRED | Feature requires higher tier | Upgrade at app.cryptachain.com/billing |
| 404 | Not Found | Resource does not exist | Verify the endpoint path and resource ID |
| 429 | Too Many Requests | Rate limit exceeded | See rate limits — back off and retry |
| 500 | Internal Server Error | Unexpected server error | Retry after a few seconds; contact support if persistent |
| 503 | Service Unavailable | Data source temporarily unavailable | Retry after Retry-After seconds (header included) |
| 504 | Gateway Timeout | Query took too long | Try a narrower date range or smaller page size |
Handling errors
typescript
try {
const res = await fetch(url, { headers: { 'X-API-Key': key } });
if (!res.ok) {
const err = await res.json();
switch (res.status) {
case 429:
// Rate limited — retry with backoff
const retryAfter = parseInt(res.headers.get('Retry-After') || '1');
await sleep(retryAfter * 1000);
return retry();
case 402:
// Credit limit — notify user
console.error('Credit limit reached:', err.message);
break;
default:
console.error(`API error ${res.status}:`, err.message);
}
}
} catch (e) {
// Network error — retry with backoff
}