Errors

Errors use the same envelope as successes, with a machine-readable code, a human-readable message, and a matching HTTP status:

{
  "success": false,
  "error": {
    "code": "rate_limited",
    "message": "Per-minute rate limit exceeded. Retry after 23s.",
    "status": 429
  }
}

All error codes

CodeHTTPMeaning & handling
invalid_key401Missing, malformed, or revoked API key. Check the Authorization header.
rate_limited429Per-minute limit exceeded. Honor the Retry-After header and back off.
quota_exceeded429Monthly quota exhausted. /quota still works so you can monitor; resets on the 1st.
plan_required403The endpoint isn't included in your plan (e.g. /convert on Free). Upgrade to use it.
invalid_params400A parameter is missing or malformed — the message says exactly which.
unsupported_currency400A currency code isn't supported. GET /api/v1/currencies lists what is.
date_out_of_plan_range403The requested date is older than your plan's history window.
no_data404No rates stored for the requested date or range.
internal_error500Something went wrong on our side. Safe to retry with backoff.

Retry guidance

  • 429 rate_limited: wait for Retry-After seconds, then retry.
  • 429 quota_exceeded: don't retry — the quota resets monthly. Upgrade or reduce volume.
  • 500 internal_error: retry with exponential backoff (e.g. 1s, 2s, 4s).
  • • 4xx errors other than 429: fix the request; retrying the same request returns the same error.