This page documents the wire contract - what the REST API itself returns. You’ll mostly meet it translated: the SDKs turn the envelope into typed errors and auto-paginate for you (SDK errors & pagination), and the CLI maps it onto exit codes and JSON output (machine contract). Read this page to understand what those layers are built on - and because
errorCode values and rate-limit behavior are identical everywhere.Pagination
List endpoints take two query parameters and return a consistent envelope:offset + items.length >= totalCount. Both SDKs auto-paginate internally - their list-style methods return the complete array.
Error envelope
Every non-2xx response carries the same JSON body - including credential rejections and unmatched routes:details appears only on field-level validation failures (400, errorCode: "VALIDATION_ERROR").
Error codes
Branch onerrorCode rather than parsing message - messages may be reworded, codes are contract. The ones you’re most likely to handle:
New codes may be added over time - treat an unrecognized
errorCode as a generic failure of its HTTP status rather than erroring out.
Every response also carries an
x-request-id header, echoed in the body’s requestId. Quote it when contacting support - it’s the fastest way for us to find your exact request.POST /v1/tools/{toolSlug}/execute is special: tool-runtime failures (the downstream API errored) return 200 with isSuccess: false and an errorMessage - not the error envelope. Branch on isSuccess, not just the HTTP status.Rate limits
Limits are enforced per account with two budgets that must both pass: a per-second burst and a sustained hourly window. Search-backed discovery calls (GET /v1/tools or GET /v1/applications with a non-empty ?search=) have their own, stricter budget because they trigger semantic search.
On 429, honor the Retry-After response header (seconds): 1 when the burst window tripped, 3600 when the hourly window tripped. Back off and retry - don’t hammer.