Reference
Errors
A failed call is problem details with a stable code. A skip is not a success.
A failed /api/v1/x call returns application/problem+json. The body includes status, title, and code. A 403 for a role includes requiredPermission. A 403 for an API token scope includes requiredScope.
One failure is not problem details. 409 publish_blocked returns the same { result, catalogVersion } shape as a save, with HTTP 409. The draft id is result.id. result.code is publish_blocked. The draft is already stored. Publish it in the designer, where a person can see the warning. A client that treats every 409 as “nothing was saved” will miss that id.
{ "result": { "id": "6f1c2a40-1b7e-4d7a-9c3e-2a8b0d5e1f44", "code": "publish_blocked" }, "catalogVersion": "605ce0b5b5191683"}Success is never a body that says the action was skipped. If the call was accepted, the write happened or the draft was stored.
| HTTP | Code | When |
|---|---|---|
| 400 | unknown_entity | The record type is not a catalog key, or a quick-action type has no sparkle |
| 400 | unknown_field | The field key is not on that record, or the body names tenantId |
| 400 | invalid_field | The value, the options, or the name shape is wrong |
| 400 | invalid_parameter | A query parameter is unknown, or the catalog type is not readable on this API yet |
| 400 | automation_invalid | The automation tree is wrong. errors[] lists the nodes |
| 400 | form_invalid | The form version is wrong, or the body asks for a system form |
| 401 | The token is missing or rejected. The body may be empty | |
| 403 | permission_denied | The role lacks the permission that call needs |
| 403 | scope_denied | The API token does not include the scope that call needs |
| 403 | token_route | An API token called a route outside /api/v1/x |
| 404 | not_found | The id is not in this firm. Another firm’s id looks the same |
| 409 | possible_duplicates | A company or person matches an existing record. matches lists the ids. Send acknowledgeDuplicates: true to create it anyway |
| 409 | catalog_conflict | expectedCatalogVersion does not match. Nothing is written |
| 409 | publish_blocked | The automation is high-impact. The draft is kept. The body is { result: { id, code }, catalogVersion }, not problem details |
| 409 | not_a_draft | That automation version is already published |
| 409 | idempotency_conflict | This Idempotency-Key was already used for a different POST |
| 409 | idempotency_in_progress | The same key and body are still running. Wait and send that POST again |
| 412 | version_conflict | If-Match is not the record’s current version. Nothing is written |
| 429 | rate_limited | The API token sent more than 300 calls in a minute. Retry-After is the wait in seconds |
403 means forbidden. 400 means the payload is not a real field or a real type. Read the catalog and retry a 400.
A 409 is not one retry. catalog_conflict: read the catalog and retry. idempotency_conflict: send the original body, or use a new key. idempotency_in_progress: send the same POST again. publish_blocked: the draft is stored; a person publishes that id in the designer. not_a_draft: that version is already published. Do not retry it. version_conflict: read the record, decide whether the patch is still right, then send it with the new version. Sending the old body with only the version changed can overwrite the newer edit.