Skip to main content
Send JSON, send ids as UUIDs, and keep a body under 1,000,000 bytes. A request that breaks one of these gets a 400 or 413 with the standard error envelope.

Version in the path

Every route sits under /v1. A path without a version, or with a version that doesn’t exist, gets a 404 that names the supported version.

Lists and paging

  • A list route returns { "data": [...], "has_more": false }.
  • A route that pages takes limit (default 100, up to 500) and cursor (a row offset, default 0).
  • A route that doesn’t page returns its whole result with has_more set to false.
  • While has_more is true, call again with cursor set to the previous cursor plus limit.
  • A bulk array accepts up to 500 items.

Ids and field types

Send each id as a UUID and each field as the type the reference gives. On a create, null counts as not sent. A list scoped to an id answers 404 when the id isn’t yours, so an empty data means the list is empty.

Content-Type and body parsing

  • A request with a Content-Type header that is present and isn’t application/json gets 400 with Content-Type must be application/json, before any other validation runs.
  • A request with no Content-Type at all is still parsed as JSON.
  • A body that is present but doesn’t parse as valid JSON gets its own 400 (Request body is not valid JSON), distinct from the “field is required” error an empty body produces.
  • A body larger than 1,000,000 bytes gets 413 with error_code: INVALID_INPUT.