Errors, idempotency & limits
When you automate against the Comwit Cloud API, two questions come up fast: “what does the API tell me when something goes wrong?” and “is it safe to run this request again?” This page answers both. It covers the error model (HTTP status codes plus problem-detail bodies), which operations you can safely retry today, and what idempotency and pagination support is still on the roadmap.
If you have not authenticated yet, start with Authentication. For the big picture of the API, see the API overview.
The error model
Section titled “The error model”Every error is an HTTP status code paired with a generated problem-detail body. The status code tells you the class of the problem; the body gives you details. You almost always branch your automation on the status code.
Status codes
Section titled “Status codes”| Status | Meaning | Typical cause |
|---|---|---|
400 | Caller mistake — bad input | You sent something the API can’t accept, for example an environment variable with secret: true where that flag isn’t allowed |
403 | Forbidden | Your token is out of scope, you’re not a member of the project, or you hit an operator-only route with a cwt_ user token |
404 | Not found | The project, database, app, domain, or record you referenced doesn’t exist (or isn’t visible to you) |
409 | Conflict | The request collides with existing state, for example a conflicting DNS record |
501 | Not implemented / feature disabled | A capability the route depends on is turned off on this deployment — for example project domain management, which is disabled by default |
502 | Upstream control-plane failure | An internal dependency (Louhi or brrrd) failed, or a required control-plane URL is unset, while the API was orchestrating your request |
What error bodies never contain
Section titled “What error bodies never contain”Error bodies are deliberately sanitized. Upstream detail from Louhi and brrrd is logged server-side, not echoed back to you. The following never appear in a public error body:
- secret values (such as the contents of secret environment variables),
- operator or server tokens,
- internal tenant headers,
- CloudFront tenant references.
So if an upstream system fails, you’ll get a clean 502 rather than a stack
trace full of internal identifiers. When you need to debug a 502, the
server-side logs hold the upstream detail — your error body intentionally
doesn’t.
Idempotency: which requests are safe to retry
Section titled “Idempotency: which requests are safe to retry”The API is synchronous wherever the upstream control plane is synchronous — when a call returns, the work is done (or it failed). There’s no generic “submit and poll” model yet (see Planned below), so the practical question is: which specific operations can I safely run twice?
Today’s retry-safe spots:
- Create a project domain — if the domain already exists, the create call returns the existing domain instead of failing.
- Create a hosted zone — uses a deterministic caller reference, so repeating the request doesn’t create a duplicate zone.
- Delete a DNS record — “already gone” is treated as success, so a repeated delete won’t error out.
- Attach / finalize an app domain and delete an app — these are re-entrant, so running them again converges on the same end state.
Planned: idempotency and pagination
Section titled “Planned: idempotency and pagination”Because lists are unpaginated today, a single list call returns the full set. If you’re scripting against very large accounts, keep an eye out for the pagination parameters above once they go live.
Operator routes vs. user routes
Section titled “Operator routes vs. user routes”One common source of 403 errors is hitting a route your token isn’t meant to
reach. The API has two tiers:
- User routes —
cwt_tokens reach project-scoped routes according to their scopes and your project membership. This is what your CLI and automation use. - Operator-only routes — these require the platform’s operator/server token
and reject
cwt_user tokens with a403. They include the platform status route and the non-project database family, plus some hidden legacy aliases that aren’t part of the public spec.
Where to go next
Section titled “Where to go next”- API overview — base URL, the live OpenAPI spec, and how requests and responses are shaped.
- Authentication —
cwt_token classes, scopes, and membership. - Limits — platform limits to design your automation around.