Errors
Errors return a structured JSON body alongside a conventional HTTP status code. Include the requestId when filing a support ticket. Every request emits one; we log them server-side.
◆ Status codes
| Status | Code | Meaning | Retry |
|---|---|---|---|
| 400 | invalid_request | A query parameter or body field is malformed (wrong type, out-of-range value, unknown enum). | Don't retry. Fix the request. |
| 401 | unauthorized | The Authorization header is missing, malformed, or carries a revoked key. | Don't retry. Verify the key in the dashboard. |
| 403 | tier_required | The endpoint or feature is gated behind a tier you're not on (e.g. webhooks on Standard). | Don't retry. Upgrade or use a covered endpoint. |
| 404 | not_found | No resource matches the path parameter (event id, coin slug, webhook id). | Don't retry. Verify the identifier. |
| 429 | rate_limit_exceeded | You've exceeded your daily request quota or a short-term burst limit. | Retry after the timestamp in the Retry-After header. Backoff exponentially. |
| 500 | internal_error | Unexpected server-side failure. Always carries a requestId; include it in support tickets. | Retry once after a few seconds. If it persists, contact support with the requestId. |
| 503 | service_unavailable | Temporary outage or scheduled maintenance. | Retry with exponential backoff (e.g. 1s, 2s, 4s, capped at 30s). |
◆ Response shape
{ "error": { "code": "rate_limit_exceeded", "message": "You have exceeded your daily request quota.", "requestId": "req_9e3779b1", "docs": "https://coinmarketcal.com/developer/docs/rate-limits" } }
◆ Retry strategy
- 4xx are not transient. Don't retry. Fix the request, the credential, or the tier.
- 429 carries Retry-After. Honor it. Most clients hitting 429 need to add backoff or a token-bucket limiter, not just retry.
- 5xx with exponential backoff. 1s → 2s → 4s → 8s, capped at 30s. Give up after 5 attempts and surface the failure.