Conventions
Learn these once and every endpoint gets easier, which is the entire argument for having conventions at all.
The envelope
Section titled “The envelope”Every response has the same outer shape:
{ "success": true, "data": { }, "meta": { }}On failure, success is false and the payload carries a stable error code.
This means your client needs exactly one place that understands success and
failure, rather than one per endpoint. It also means you should check success
rather than inferring it from the HTTP status. The two usually agree. Usually is
not a word you want load-bearing in an error path.
Pagination
Section titled “Pagination”List endpoints are cursor-paginated. You get a page of results and a cursor; pass the cursor back for the next page. Keep going until there is no cursor left.
Cursors are opaque. They encode position in a way that survives items being added while you are reading, which offset-based paging does not. Do not parse one, do not construct one, and do not store one and use it a week later.
Identifiers
Section titled “Identifiers”Most objects are addressed by an id. Some are also addressable by a handle or slug, which is friendlier in a URL and in a support conversation.
Watch the level. Workspace-scoped and app-scoped identifiers look similar and are not interchangeable, and passing one where the other is expected produces a “not found” that is technically honest and completely unhelpful.
Rate limits
Section titled “Rate limits”Limits are per token. When you hit one you get a failure with a rate-limit error code rather than a silent slowdown.
Back off exponentially and add jitter. Retrying immediately, in a tight loop, from every one of your workers at once is how a rate limit becomes an outage. The limit is doing its job; help it.
Idempotency
Section titled “Idempotency”Anything that creates or charges should be safe to retry. If a request times out, you do not know whether it landed, and the honest answer to “did that work” is to ask rather than to guess by trying again.