API Reference
Error Codes
All HTTP errors returned by the xchangr8 API, with causes and fixes.
HTTP Status Codes
| Status | Code | Message | Cause | Fix |
|---|---|---|---|---|
| 400 | invalid_base | Invalid base currency | Unknown currency code in base param |
Use a valid 3-letter ISO code |
| 400 | invalid_symbols | Invalid symbols | Unknown currency code in symbols |
Check supported currencies |
| 400 | invalid_date | Invalid date format | Date not in YYYY-MM-DD | Use ISO 8601 date format |
| 400 | invalid_amount | Invalid amount | Non-numeric or negative amount | Provide a positive number |
| 401 | missing_key | Missing API key | No X-API-Key header or apikey param | Add your API key |
| 401 | invalid_key | Invalid API key | Key not found or revoked | Check dashboard for valid key |
| 403 | plan_limit | Feature not available on your plan | e.g. timeseries on Free plan | Upgrade to Starter or Pro |
| 429 | rate_limited | Rate limit exceeded | Too many requests per minute (burst) | Implement backoff, or upgrade |
| 429 | quota_exceeded | Monthly quota exceeded | Over monthly request limit | Upgrade or wait for reset |
| 500 | server_error | Internal server error | Unexpected server issue | Retry with exponential backoff |
| 503 | upstream_unavailable | Upstream data unavailable | All data sources temporarily down | Retry in 30–60 seconds |
Error Response Shape
All errors return a consistent JSON envelope regardless of status code.
JSON
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 15 seconds.",
"retry_after": 15
}
}
Rate Limit Headers
Every response includes the following rate limit headers so you can monitor usage and react before hitting limits.
HTTP Headers
X-RateLimit-Limit: 333 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1749340920 Retry-After: 15
Tip:
X-RateLimit-Reset is a Unix timestamp (UTC). Subtract Date.now() / 1000 from it to calculate exact seconds remaining.
Handling Errors — Code Example
The pattern below handles rate limits, respects Retry-After, and surfaces readable error messages.
JavaScript
const res = await fetch('https://api.xchangr8.com/v1/latest', { headers: { 'X-API-Key': 'xc8_live_YOUR_KEY' } }) if (!res.ok) { const { error } = await res.json() if (res.status === 429) { // Respect Retry-After header const retryAfter = res.headers.get('Retry-After') || 60 await sleep(retryAfter * 1000) } throw new Error(`xchangr8: ${error.code} — ${error.message}`) }