API

Errors & versioning

The API fails loudly and consistently: machine-readable JSON bodies, conventional status codes, and an explicit version header on every request so behaviour never shifts under you.

Error shape

Errors return a JSON object with an error message:

{
  "error": "Authentication required"
}

Some endpoints add detail alongside the message, for example the list of supported versions on a version error, or field-level information on validation failures. The error key is always present; treat everything else as advisory.

Status codes

Status Meaning Typical cause
400 Bad Request The request itself is malformed Missing or unsupported X-Api-Version header
401 Unauthorized No valid credential Missing session, or an invalid, revoked, or expired API key
403 Forbidden Authenticated but not allowed Missing permission key, no access to the app, or a scoped API key acting outside its scopes
404 Not Found No such resource in this workspace Wrong id, or a resource that belongs to another workspace (indistinguishable by design)
415 Unsupported Media Type Wrong body encoding POST, PUT, or PATCH without Content-Type: application/json
422 Unprocessable Entity The body failed schema validation A missing required field, a value out of range, a wrong type
429 Too Many Requests Rate limited Too many attempts against a sensitive endpoint; retry after the Retry-After header
500 Internal Server Error The platform failed Report it; these are logged and paged on our side

Two behaviours worth designing around:

  • 404 is also an isolation answer. Asking for a resource that exists in a different workspace returns the same 404 as a resource that does not exist at all. Clients must not infer existence from status codes.
  • Validation runs before your handler is reached. Endpoints declare pytastic schemas, so a 422 means the request never touched application logic. Fix the payload and retry; nothing was partially applied.

Versioning

Every request must carry the X-Api-Version header:

X-Api-Version: 2026-03-15
Accepted value Meaning
2026-03-15 The current version, pinned to a release date
2026-03 The month alias of the same version

Requests without a supported version receive:

{
  "error": "Missing or unsupported X-Api-Version header",
  "supported": ["2026-03-15", "2026-03"]
}

The header exists so the platform can ship breaking changes behind a new date while your integration keeps the behaviour it was built against. Pin the full date form in production code. When a new version is published, its changes are documented and the previous version keeps working through a deprecation window announced ahead of time.

Retries

  • 429 responses include a Retry-After header in seconds; honour it.
  • 5xx responses are safe to retry for idempotent requests (GET, PUT, DELETE). For POST, check whether the resource was created before retrying.
  • 4xx responses other than 429 will not succeed on retry without changing the request.

The interactive reference

Every endpoint, schema, and response is browsable in the live reference at api.saaslivery.com/docs, generated from the same schemas that validate requests in production.