AArtery
On this page

Error Codes

Every Artery error response carries a structured envelope plus an X-Request-Id header. Branch your client code on error.code, not on HTTP status — the status can change (e.g. validation_failed is 400 or 422 depending on layer) but the code is stable.

Envelope

jsonc{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded for tier \"free\" (10000/month)",
    "requestId": "req_5a6604f3-7c32-42da-ba70-3df3ca864cfc"
  }
}
FieldMeaning
error.codeStable Artery enum (see table below) — branch on this
error.messageHuman-readable summary, safe to surface to end-users
error.requestIdPer-request id, mirrored on the X-Request-Id response header
error.provider(Upstream errors only) Which adapter raised the error
error.upstream.status(Upstream errors only) HTTP status returned by the provider
error.upstream.body(Upstream errors only) Raw provider error body

Code reference

StatusCodeMeaningHow to fix
400bad_requestGeneric validation failure (malformed JSON, bad query)Inspect error.message — it carries the field path
400/422validation_failedZod schema violation on body / queryMatch the message's field.path to your payload and fix the offending field
401unauthenticatedMissing or malformed Authorization headerSet Authorization: Bearer art_live_<key> or pass ?token=... on the WS upgrade
403forbidden_scopeKey lacks the required scopeMint a new key with the missing scope (read / stream / admin)
404not_foundEvent / wallet / webhook id does not existVerify the id; for events, call GET /v1/events first
409conflictIdempotency / uniqueness violation (e.g. duplicate wallet binding)Re-read the resource — it likely already exists
429rate_limitedArtery quota exceededHonor Retry-After; see limits for tier thresholds
429upstream_rate_limitedUpstream provider rate-limited Artery (transient)Artery already retries GETs with backoff — surface to user only after retry exhaustion
401/403upstream_unauthorizedProvider rejected your provider credentials (planned)Re-upload Polymarket / Kalshi / HL creds; check expiration
500internal_errorArtery bug — please file with requestIdRetry after a short delay; if it persists, include X-Request-Id in your bug report
502/503/504upstream_unavailableProvider 5xx or timeoutRetry idempotent calls; for trades, the client decides

Examples

401 unauthenticated

bashcurl -i "https://api.artery.questflow.ai/v1/events"
httpHTTP/1.1 401 Unauthorized
Content-Type: application/json
X-Request-Id: req_5a6604f3-...
 
{ "error": { "code": "unauthenticated", "message": "Missing Authorization header", "requestId": "req_5a6604f3-..." } }

403 forbidden_scope

bash# A `read`-only key trying to mint a webhook (admin scope required)
curl -i -H "Authorization: Bearer art_live_readonly..." \
  -X POST "https://api.artery.questflow.ai/v1/webhooks" \
  -d '{}'
httpHTTP/1.1 403 Forbidden
{ "error": { "code": "forbidden_scope", "message": "Required scope: admin", "requestId": "req_..." } }

429 rate_limited

httpHTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1780822653
 
{ "error": { "code": "rate_limited", "message": "Rate limit exceeded for tier \"free\" (10000/month)", "requestId": "req_..." } }
Tip

Retry-After is in seconds, not milliseconds. Most HTTP clients honor it automatically (e.g. axios-retry, Python requests with urllib3.Retry).

404 not_found

bashcurl -i -H "Authorization: Bearer art_live_<your-key>" \
  "https://api.artery.questflow.ai/v1/events/evt_does_not_exist"
httpHTTP/1.1 404 Not Found
{ "error": { "code": "not_found", "message": "event evt_does_not_exist not found", "requestId": "req_..." } }

502 upstream_unavailable

jsonc// Polymarket Polygon RPC returned 504
{
  "error": {
    "code": "upstream_unavailable",
    "message": "Polymarket /book request failed after 5 attempts",
    "provider": "polymarket",
    "upstream": { "status": 504, "body": "gateway timeout" },
    "requestId": "req_..."
  }
}

Request id propagation

Every response carries X-Request-Id. If you send your own X-Request-Id header (non-empty string ≤128 chars) Artery echoes it back unchanged — useful for stitching distributed traces:

bashcurl -i -H "Authorization: Bearer art_live_<your-key>" \
     -H "X-Request-Id: my-trace-abc-123" \
     "https://api.artery.questflow.ai/v1/events"
# → X-Request-Id: my-trace-abc-123

Retry policy

Artery's transport layer retries idempotent calls (GET) on network errors and 5xx automatically:

AttemptDelay
10 ms
2100 ms ± 20%
3250 ms ± 20%
4500 ms ± 20%
51000 ms ± 20%

After attempt 5 the error surfaces with code: upstream_unavailable. POST and DELETE are not retried — the caller decides idempotency.

See also

Edit this page on GitHubLast updated
Error Codes · Artery API Docs