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
404as 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
422means 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
429responses include aRetry-Afterheader in seconds; honour it.5xxresponses are safe to retry for idempotent requests (GET,PUT,DELETE). ForPOST, check whether the resource was created before retrying.4xxresponses other than429will 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.