Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.alterscope.org/llms.txt

Use this file to discover all available pages before exploring further.

Networks fail, limiters trip, and upstreams hiccup. A resilient client retries the failures that are worth retrying — and only those. This page is standard, vendor-neutral guidance for building that client against the Alterscope API. It does not replace the per-code reference in Errors; it tells you what to do with each code.

Retry only what’s safe to retry

Branch on the HTTP status and the error envelope’s code, never on the human-readable message.
StatusRetry?What to do
429 Too Many RequestsYesHonor Retry-After (seconds), then back off. See Rate limits.
409 idempotency in-flightYesA request with the same X-Idempotency-Key is still running. Honor Retry-After, then retry the same key.
503 / 504 / 5xxYesTransient server or gateway condition. Back off with jitter and a cap.
Network error / timeoutYesConnection reset, DNS failure, read timeout. Treat as transient and back off.
400, 401, 403, 404No — fix firstMalformed request, bad/expired/revoked key, missing scope, wrong path. Retrying the identical call won’t change the outcome.
Other 4xx validationNo — fix firstCorrect the request body or parameters, then send once.
None of these cases call for a new idempotency key. A retry should reuse the same key so the server can deduplicate it — see Idempotency keys are safe to reuse below.
For 401/403, the fix is in your key or scopes — see Authentication and Scopes. For 429, see Rate limits.

Honor Retry-After when present

Two responses carry a Retry-After header (in seconds), and you should wait at least that long before retrying:
  • 429 Too Many Requests — the per-minute limiter. The response also carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
  • 409 idempotency in-flight — a concurrent request with the same X-Idempotency-Key is still executing. Wait the suggested interval, then retry the same key.
When Retry-After is present, treat it as a floor: wait at least that long, then apply your normal backoff for any subsequent attempts.

Exponential backoff with jitter

For transient failures without a Retry-After, back off exponentially and add jitter so that many clients retrying after the same outage don’t synchronize into a thundering herd. Cap both the per-attempt delay and the total number of attempts.
const RETRYABLE = new Set([429, 503, 504]);

async function withRetry<T>(
  fn: () => Promise<Response>,
  maxAttempts = 5,
  baseMs = 200,
  capMs = 20_000,
): Promise<Response> {
  let attempt = 0;
  for (;;) {
    let res: Response;
    try {
      res = await fn();
    } catch (err) {
      // Network error / timeout — retryable.
      if (++attempt >= maxAttempts) throw err;
      await sleep(backoff(attempt, baseMs, capMs));
      continue;
    }

    if (res.ok || (res.status >= 400 && res.status < 500 && !RETRYABLE.has(res.status))) {
      // Success, or a client error you must fix — don't retry.
      return res;
    }

    if (++attempt >= maxAttempts) return res;

    // Honor Retry-After (seconds) when the server sends it.
    const retryAfter = res.headers.get("Retry-After");
    const waitMs = retryAfter
      ? Math.max(Number(retryAfter) * 1000, backoff(attempt, baseMs, capMs))
      : backoff(attempt, baseMs, capMs);
    await sleep(waitMs);
  }
}

function backoff(attempt: number, baseMs: number, capMs: number): number {
  const exp = Math.min(capMs, baseMs * 2 ** (attempt - 1));
  return Math.random() * exp; // full jitter
}

const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
The official SDKs (TypeScript @alterscope/sdk, Python alterscope) apply backoff for you; reach for the patterns above when you’re calling the API directly or generating a client from the OpenAPI spec.

Set sensible timeouts

A retry loop is only as good as the timeouts under it. Without them, a single stalled connection blocks the whole loop.
  • Per-attempt timeout — bound each request so a hung connection fails fast and frees the slot for a retry rather than hanging indefinitely.
  • Total deadline — cap the wall-clock time across all attempts. Once the deadline passes, stop retrying and surface the error.
  • Connect vs. read — a short connect timeout catches unreachable hosts quickly; a longer read timeout accommodates heavier analytical endpoints.
Tune the read timeout to the endpoint: a webhook subscription returns in milliseconds, while a portfolio analysis or Monte-Carlo run is heavier. Keep a generous total deadline so a brief outage doesn’t fail a request you’d otherwise recover.

Idempotency keys are safe to reuse

Mutation endpoints accept an X-Idempotency-Key header. When you retry, send the same key — that’s what makes the retry safe:
  • A replay of a completed request returns the original cached response (within a 24-hour window) with an X-Idempotency-Replayed: true header, instead of executing the side effect again.
  • If the original request is still in flight, the retry receives 409 with Retry-After; wait and retry the same key.
A retry never needs a new key. Mint a new X-Idempotency-Key only for a genuinely new operation, never to “force through” a failed one — a new key bypasses deduplication and can double-execute the side effect. See Idempotency for the full contract.
Many mutation endpoints touch live, money-moving operations. When in doubt, retry with the same idempotency key and let the server deduplicate. Never generate a fresh key to retry a request that may have already taken effect.

Checklist

  • Retry 429, 409 in-flight, 503/504/5xx, and network/timeout errors. Don’t retry 400/401/403/404 or other validation failures — fix the request first.
  • Honor Retry-After (seconds) on 429 and 409 before backing off.
  • Use exponential backoff with full jitter, a per-attempt delay cap, and a capped attempt count.
  • Set per-attempt timeouts and a total deadline.
  • Retry with the same X-Idempotency-Key; never mint a new one to force a retry.

Idempotency

Make mutations safe to retry with X-Idempotency-Key.

Errors

The error envelope, status codes, and per-code retry guidance.

Rate limits

Per-tier limits and 429 retry behavior.

Authentication

Fix 401/403 failures at the key and scope level.