DEVELOPER DOCUMENTATION / API v1
Errors and recovery
Interpret Can You Just API problem responses, HTTP statuses, machine codes and trace IDs, with practical recovery guidance.
A machine-readable problem
API errors use application/problem+json with type, title, status, code and traceId. Branch on HTTP status and machine code; title is human-readable context, not a stable state identifier. Keep the fictional trace ID format below separate from your application’s business IDs.
{
"type": "about:blank",
"title": "Planning data changed. Read the task again.",
"status": 412,
"code": "stale_update",
"traceId": "example-trace-001"
}
Status and code reference
| HTTP status | Machine codes | Client recovery |
|---|---|---|
| 400 | validation_failed | Fix malformed JSON, binding/types, duplicate members, missing typed fields or an invalid action/decision shape. |
| 401 | authentication_failed | Obtain/fix the credential and inspect its client, sponsor, organisation and resource validity. |
| 403 | permission_denied, task_not_owned | Correct scope or assignment. Do not treat denial as a transient retry. |
| 404 | route_not_found, task_not_found, request_not_found, incoming_not_found | Check route and the correct owned identity. Assistance-stage and Incoming IDs differ. Cross-organisation IDs remain unavailable. |
| 405 | method_not_allowed | Use the documented method; inspect the Allow response header. |
| 409 | task_blocked, task_completed, task_not_runnable, request_completed, dependency_conflict | Inspect current task, prerequisites, request lifecycle and scheduler eligibility before deciding a new operation. |
| 409 | task_claimed, claim_expired | Do not execute with an unavailable/expired lease. Reconcile and obtain a usable claim. |
| 409 | idempotency_conflict | The key belongs to another operation/body/target. Inspect the stored logical request; never force a duplicate effect with a new key. |
| 409 | incoming_state_conflict, source_context_changed | Re-read the relevant Incoming/source context and reconcile before activation or a new action. |
| 412 | stale_update | Re-read current task/Incoming state, reconcile intent and supply the correct exact precondition. |
| 413 | request_too_large | Reduce JSON below 131072 bytes; do not retry the oversized body unchanged. |
| 415 | unsupported_media_type | Use application/json or a supported application/*+json content type. |
| 422 | validation_failed, invalid_field, human_assignee_invalid, idempotency_key_required | Correct task/domain fields, the active human target, or the required retry-key syntax. |
| 428 | precondition_required | Read and supply the required task ETag or Incoming revision in If-Match. |
| 429 | rate_limited | Wait for Retry-After, then back off with jitter and preserve logical retry identity. |
| 500 | internal_error | Retain traceId for support. Do not interpret it as business state or blindly repeat uncertain effects. |
| 503 | source_unavailable, temporarily_unavailable | Retry cautiously or select other work, following operation-specific receipt and reconciliation rules. |
Recover from stale updates #
A 412 may follow an unrelated planning change elsewhere in the workspace. An Incoming action instead protects its own revision. Fetch the correct state, compare the intended change and retry only when still appropriate. See exact preconditions; do not swap a claim token into If-Match.
Recover from throttling
Read Retry-After from the 429 response and wait. Rotate credentials for security, not to evade a client-scoped limit. See service protection.
Transient and uncertain outcomes
On a transport failure, 500 or 503, distinguish “request failed before a successful receipt” from “response was lost after success”. Use same-key recovery and inspect the resulting state. External side effects still need reconciliation. Source activation failure creates no claim; an expired replayed lease is still unusable.
Related guides: authentication, permissions, leases and operation reference.