Backbone LabDocs
Concepts

Rate limits

Authenticated API requests have separate read, write and upload budgets per API key. Reads and writes use fixed 60-second windows; uploads use a token bucket. The limits protect the control plane only — they say nothing about how many orders can be processing at once.

The limits

BucketLimitApplies to
Reads300 requests / minuteAuthenticated GET and HEAD requests, excluding SSE streams.
Writes60 requests / minuteMutations outside /v1/assets: order and batch submission/cancellation, key management (including DELETE), and WebSocket ticket creation.
UploadsBurst of 200, refilling at 10 / secondAsset declaration, upload confirmation and export requests, including repeated export polling.

Declaring and confirming one uploaded file uses two upload tokens. Sending bytes to the signed storage URL does not consume this budget. Export requests share the upload budget; asset status polling uses the read budget. Limits are counted per key — two keys of the same workspace have independent budgets. Submitting a batch counts as one write regardless of its scene count.

SSE streams and WebSocket messages do not consume these request budgets. Creating a WebSocket ticket with POST /v1/ws-ticket counts as a write. Prefer streaming over tight polling loops.

Response headers

Requests that reach the rate limiter carry the following headers, including on a 429 response. Public endpoints, SSE streams and requests rejected by authentication do not carry these counters.

HeaderMeaning
X-RateLimit-LimitWindow limit, or capacity of the upload bucket.
X-RateLimit-RemainingRequests or whole upload tokens remaining.
X-RateLimit-ResetUnix timestamp (seconds) when the window resets, or the upload bucket would be full if no further requests consume tokens.

Handling 429

When a request's budget is exhausted, the API answers 429 with a Retry-After header (in seconds) and the standard error envelope. Wait at least that long before retrying. For uploads, this is the wait for the next token, not for the bucket to refill completely:

HTTP/1.1 429 Too Many Requests
Retry-After: 12

{ "error": { "status": 429, "reason": "rate limit exceeded — slow down" } }