Thoughtful finds. Delivered to Nigeria.Delivery, made clear
DEELINE.
Reference

Errors & retries

Every non-2xx response returns a JSON body with ok: false and an error string. Rate limits add retryAfterSec.

Error response shape

{
  "ok": false,
  "error": "Invalid or missing API key."
}

Error codes

StatusMeaningWhat to do
400Bad request — invalid params, payload too large, or wrong content-type.Fix the request; do not retry.
401Missing, invalid, or revoked API key.Check Authorization header; if revoked, request a new key.
403Key valid but lacks permission.Contact support — key needs the reseller role.
404Endpoint does not exist.Check the URL.
429Rate limit exceeded.Read retryAfterSec and wait before retrying.
500Server error.Retry with exponential backoff; report if persistent.
503Service temporarily unavailable.Retry with backoff.

Retrying safely

Retry only on 429, 500, and 503. Use exponential backoff with a small random jitter, and respect retryAfterSec if present.

JavaScript

async function requestWithRetry(url, options, maxAttempts = 3) {
  let attempt = 0;
  while (attempt < maxAttempts) {
    const res = await fetch(url, options);
    if (res.ok) return res.json();

    const data = await res.json().catch(() => ({}));

    if (res.status === 429 && data.retryAfterSec) {
      await new Promise((r) => setTimeout(r, data.retryAfterSec * 1000));
    } else if (res.status >= 500) {
      await new Promise((r) => setTimeout(r, 1000 * 2 ** attempt + Math.random() * 500));
    } else {
      throw new Error(data.error || `HTTP ${res.status}`);
    }
    attempt++;
  }
  throw new Error("Max retries exceeded");
}

Python

import time, random, requests

def request_with_retry(url, headers, params=None, max_attempts=3):
    for attempt in range(max_attempts):
        r = requests.get(url, headers=headers, params=params, timeout=30)
        if r.ok:
            return r.json()

        try:
            data = r.json()
        except Exception:
            data = {}

        if r.status_code == 429 and "retryAfterSec" in data:
            time.sleep(data["retryAfterSec"])
        elif r.status_code >= 500:
            time.sleep(2 ** attempt + random.random() * 0.5)
        else:
            raise Exception(data.get("error", f"HTTP {r.status_code}"))

    raise Exception("Max retries exceeded")

Related