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.

When a request fails, the API returns a non-2xx HTTP status and a JSON body wrapping a single error object. The API does not use the RFC 9457 application/problem+json shape — it returns the envelope below with Content-Type: application/json.

Error envelope

{
  "error": {
    "code": "insufficient_scope",
    "message": "The API key does not have the required scope for this operation",
    "details": { "...": "optional, context-specific" },
    "request_id": "req_…",
    "documentation_url": "https://docs.alterscope.org/errors/insufficient_scope"
  }
}
FieldAlways presentMeaning
codeYesA stable, machine-readable error code (branch on this, not the message).
messageYesA human-readable description. May change; do not parse it.
request_idYesUnique per request. Quote it in support tickets. Also returned in the X-Request-ID response header.
detailsNoOptional structured context for the error.
documentation_urlNoLink to this page’s section for the code, when available. Resolves to https://docs.alterscope.org/errors/<code>, i.e. the matching anchor on this page.
The documentation_url is emitted for the authentication and request-level error codes (the Status codes table below). Some specialized surfaces — feature-gated endpoints and the events replay endpoint — return their own error shapes documented under Feature-gated and endpoint-specific errors. In every case, branch on code, never on the HTTP status or message alone.

Status codes

Each row’s code is also a section anchor on this page, so https://docs.alterscope.org/errors/<code> deep-links here.
CodeHTTPWhenRemediation
missing_auth401No Authorization: Bearer header was sent.Send Authorization: Bearer sk_live_…. See Authentication.
unauthenticated401Authentication is required and was not satisfied.Provide a valid key. Browser WebSocket clients pass it via ?token=.
invalid_key401The API key is malformed or not recognized.Re-issue a key in the Developer Portal and replace the value.
expired_key401The API key has expired.Mint a new key and rotate. See Rotation and revocation.
revoked_key401The API key has been revoked.Mint a new key; the revoked one fails closed permanently.
insufficient_scope403The key is valid but lacks the scope for this operation.Mint a key with the required scope (details.required_scope names it).
forbidden403The key may not access this resource.Confirm the resource belongs to your organization.
invalid_request400The request was malformed (bad JSON, wrong method, missing path parameter).Fix the request shape, then retry.
validation_failed400The request parsed but failed field validation.Read message/details for the offending field and correct it.
not_found404The requested resource does not exist.Check the path and resource ID. Do not retry blindly.
conflict409The request conflicts with current state (e.g. the resource already exists).Reconcile state — fetch the existing resource or change the identifier. See also idempotency for the in-flight 409.
rate_limit_exceeded429Too many requests for your tier’s per-minute limit.Wait for Retry-After, then retry. See Rate-limit responses.
rate_limited429Rate limit exceeded (returned by the authentication layer).Same as rate_limit_exceeded: honour Retry-After and back off.
risk_dependency_unavailable503A risk data dependency (VaR, protocol risk, liquidity, correlation) is temporarily unavailable.Retry with backoff; the upstream data source is transiently down.
unavailable503The endpoint or a backing service is temporarily unavailable.Retry with backoff per Retries.
internal_error500An unexpected server error.Safe to retry with backoff. Quote request_id if it persists.

Rate-limit responses

A 429 from the per-minute limiter additionally sets:
Retry-After: 60
X-RateLimit-Limit: <burst>
X-RateLimit-Remaining: 0
X-RateLimit-Reset: <unix timestamp>
The error.code is rate_limit_exceeded. Wait for the Retry-After period (seconds) before retrying. The X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers are returned on every response, not just 429s, so you can pace yourself before you hit the limit. See Rate limits for per-tier limits.

Feature-gated and endpoint-specific errors

A few endpoints enforce plan tiers, monthly quotas, or a tier-scoped data window. These return codes specific to the endpoint. They are not general status codes — only the listed endpoints emit them.

Plan-gated and quota codes

These appear on the exit Monte Carlo (/v2/liquidity/{id}/exit-monte-carlo) and simulator (/v2/simulator/...) endpoints.
CodeHTTPWhenRemediation
MC_TIER_REQUIRED403Exit Monte Carlo requires a higher plan tier.Upgrade your plan. See Rate limits for tier details.
MC_MONTHLY_QUOTA_EXCEEDED429Your monthly exit Monte Carlo run quota is exhausted.Wait for the next billing cycle or upgrade.
SIMULATOR_TIER_REQUIRED403Simulator runs require a higher plan tier.Upgrade your plan. details.required_plans lists the eligible tiers.
SIMULATOR_MONTHLY_QUOTA_EXCEEDED429Your monthly simulator run quota is exhausted.Wait for the next billing cycle or upgrade.
SIMULATOR_SCENARIO_NOT_FOUND404The requested simulator scenario does not exist.Check the scenario ID against the scenario catalogue.
The plan-gated and quota codes use UPPER_SNAKE_CASE and carry context in details (for example details.required_plans, details.limit, details.upgrade_url). They do not set documentation_url. Tier names are always one of Free / Analyst / Team / Enterprise / Custom — see Rate limits for per-tier limits.

Events replay errors

The events replay endpoint (GET /v2/events/replay) enforces a tier-scoped replay window. Its error body is a flat shape — {"error": "<CODE>", "message": "…", "details": { … }} — rather than the nested error.code envelope above. Branch on the top-level error string.
CodeHTTPWhenRemediation
REPLAY_NOT_AVAILABLE404Event replay is not available on your tier (the tier’s replay window is zero).Upgrade to a tier that includes replay.
REPLAY_WINDOW_EXPIRED410The since_event_id cursor is older than your tier’s replay window.Start from a more recent cursor, or upgrade for a longer window. details.window_days names the window.
INVALID_CURSOR400since_event_id is not a valid ULID.Pass a ULID cursor from a prior response’s next_cursor.
INVALID_EVENT_TYPE400The type filter is not a recognized event type.Use a valid event type. See Webhooks for the event catalogue.

Idempotency in-flight (409)

Endpoints protected by idempotency accept an X-Idempotency-Key header. If a request with the same key is still being processed by another worker, the API responds with 409 Conflict and a Retry-After: 1 header. The body is a flat {"error": "duplicate request in flight; retry after a brief delay"}.
  • A replay of a completed request (same key, within the cache window) returns the original cached response with an X-Idempotency-Replayed: true header — not a 409.
  • An in-flight duplicate returns the 409 above. Wait the Retry-After interval, then retry with the same key.
See Idempotency for the full contract.

Retry guidance

  • 429 — back off for the Retry-After interval, then retry. For idempotent writes, reuse the same X-Idempotency-Key.
  • 500 and other 5xx (including 503 unavailable / risk_dependency_unavailable) — retry with exponential backoff and a capped number of attempts.
  • 400, 401, 403, 404 — do not retry blindly; fix the request, key, scope, or path first.
  • 409 — for an idempotency in-flight conflict, retry after the short Retry-After. For a resource conflict, reconcile state before retrying.
Always log request_id (or the X-Request-ID header) so support can trace a specific failed call.