Developers

Errors, Pagination, and Limits

The error envelope, every status code the API returns, why 404 means 'not visible to this key', pagination, and rate limits.

Intermediate, 6 minUpdated October 2026

Read firstAuthenticating with an API Key

Branch on the HTTP status first and the code field second. Never match on the error text; it is for humans and may change.

The Envelope

Every error is a JSON object with a message and, on most responses, a stable code. Validation failures add a per-field map.

{
  "error": "Validation failed",
  "code": "VALIDATION_ERROR",
  "errors": { "filename": ["Required"] }
}

Status Codes

StatusMeaningcode
400Malformed JSON, a missing id, or a body that fails validationVALIDATION_ERROR
401No key, or an invalid, revoked, or expired keynone
403The project is not accessible to this key, or a required scope is missingnone
403A refusal decided by the operation itself, such as a download that must be watermarkedFORBIDDEN
403Uploads blocked by the organization's billing stateUPLOAD_RESTRICTED
404The resource does not exist, or is not visible to this keyNOT_FOUND
409The request clashes with current state: a second upload-complete for the same asset, a filename and type already taken, a folder name already in use, or revoking or resending an upload link that is no longer activeCONFLICT
422The organization's storage limit would be exceededSTORAGE_LIMIT_EXCEEDED
429The key's rate limit, or a per-resource cooldown such as resending an upload link more than once a minuteRATE_LIMITED
429The organization's hourly approval email limitEMAIL_BUDGET_EXCEEDED
500Anything unexpectedINTERNAL_ERROR

401 and 403 from the authentication layer carry a message but no code; the status is the signal. A 403 says either Access denied (the project is not reachable with this key) or Missing permission: <scope> (the key or its creator lacks that scope). An archived project refuses writes with Project is archived. Per-file upload problems (FILE_TOO_LARGE, UNSUPPORTED_TYPE, CONFLICT) are reported inside the presign response, not as a status; see Uploading Files.

403 Versus 404

The two are deliberate and worth getting right in your client.

  • 403 is about the project. An unknown project id, a project the key's creator is not a member of, and a missing scope all return 403. The API never confirms whether a project exists.
  • 404 is about a resource inside a project you can reach. A deleted asset, an asset in another project, a hidden asset when the key lacks viewHiddenAssets, and a draft when the creator may only see published assets all return the same 404 with the same body. "Not found" means "not found for this key".

Treat a 404 on a by-id route as "not mine to see" rather than "deleted".

Pagination

Lists that can grow large (assets, tags, collections, and a collection's assets) take page (1-based, default 1) and pageSize (default 50, maximum 100; larger values are clamped, not rejected) and return this shape:

{ "items": [], "page": 1, "pageSize": 50, "total": 1234, "hasMore": true }

Loop while hasMore is true. total can be approximate; use hasMore, not arithmetic on total, to decide when to stop. There are no cursors in v1.

Short lists (folders, approvals, upload links, collection members) are returned whole, under their own key, with no paging fields.

Rate Limits

Each key may make 600 requests per minute. Past that, requests are rejected with 429 and RATE_LIMITED. Every 429 carries a Retry-After header with the number of seconds to wait; wait that long, then retry.

Each organization may send 200 approval emails an hour, one per recipient, reminders and resends included. A request that would go over returns 429 with EMAIL_BUDGET_EXCEEDED and a Retry-After, and nothing is created or changed.

Signed URLs have their own clocks: download URLs last one hour, upload URLs thirty minutes. Request them when you are about to use them, not in advance.

What's Next

Tell us what you're shooting next.

Start with one title. Upload a shoot, bring its metadata in from a CSV, and confirm the cast. Then decide.

A person on our team reads it and writes back.