Errors

All errors follow a consistent envelope: machine-readable error code, human-readable message, and a trace_id for support.

Error envelope

402 Payment Required
{
  "error": "insufficient_credits",
  "message": "Your account has 2 credits remaining but this operation requires 10.",
  "trace_id": "afa-3f8a9e2b",
  "_meta": {
    "credits_remaining": 2,
    "latency_ms": 4
  }
}

Status codes

StatusError codeMeaningFix
400bad_requestMalformed requestCheck params against reference
400missing_idRequired path param missingInclude the ID in the URL
401unauthorizedInvalid or missing API keyCheck Authorization: Bearer header
402insufficient_creditsCredit balance too lowTop up credit pack or upgrade plan
404track_not_foundNo match in any catalogCheck spelling, try ISRC instead
429rate_limit_exceededToo many requests this minuteBack off using X-RateLimit-Reset
429concurrency_exceededToo many concurrent requestsQueue requests to match plan concurrency
500internal_errorUnexpected server errorRetry with exponential backoff; report trace_id to support
503service_unavailableTemporary capacity issueRetry after 1–2 seconds

Retry strategy

Retry 429, 500, and 503 with exponential backoff. Do NOT retry 400, 401, 402, or 404 — those won't succeed on retry.

python retry helper
import time, requests

def call_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        r = requests.get(url, headers=headers)
        if r.status_code < 400:
            return r.json()
        if r.status_code in (429, 500, 503):
            wait = 2 ** attempt  # 1s, 2s, 4s
            time.sleep(wait)
            continue
        # Do not retry on 400/401/402/404
        r.raise_for_status()
    raise Exception("max retries exceeded")

Reporting issues

Every response carries an _meta.trace_id. If you need help debugging, include the trace ID when contacting support — we can pull the full request log and response from it.