Errors
Every failure is an RFC 9457 problem with a stable machine-readable code, a human message, the right HTTP status, a request id and field-level errors[].
Every error answers application/problem+json (RFC 9457) with the same shape:
{
"type": "https://developers.processcart.com/errors#validation_failed",
"title": "Validation failed",
"status": 422,
"detail": "The request body failed validation.",
"code": "validation_failed",
"requestId": "req_1f3c…",
"errors": [
{ "field": "amount", "code": "unparseable", "message": "Enter a number." }
]
}codeis the stable, machine-readable reason — branch on it, never ondetail. Every code is listed below and is the anchor itstypeURL points at.typeis this page plus the code;titleis constant per code;detailis a human sentence that may change.statusrepeats the HTTP status. The code's default status is listed below; a few codes can appear under more than one status where noted.requestIdis the same value as theX-Request-Idheader. Quote it to support.errors[]appears when the problem is field-level: each entry names thefield(a body member such asnameor a dotted path such astarget.fieldKey, a query parameter, a header name, or — for a field value — the field's key, as above), acodefrom the vocabulary below and amessage. A top-level code can also appear as anerrors[].codewhen it concerns one field (task_completedon a field of a completed task); it is described under Error codes.- Request bodies are strict: a key an operation does not take is refused with
unrecognized_keysonbody(ontargetfor one inside a file upload'starget; the message names the key) instead of being dropped.enabledin a webhook, schedule or rule body answersunknown_keyonenabledinstead, and its message names the operations that turn the resource on and off. A map keyed by field or task keys answers its own code too:PATCH /v1/runs/{id}/fields(whose whole body is that map) and a schedule'spresetValuesrefuse a key that names no field asunknown_fieldon that key, and a schedule'sassignmentOverridesa key that names no task asunknown_task. - A 404
not_foundmeans the key may not see the thing, not only that it does not exist: an id that is not a uuid or belongs to another workspace, a task or field key the run's version does not define, a private saved view, a webhook outside the key's allowlist. The answer never says which, so it reveals nothing about other workspaces. A run in Trash is not a 404: it can still be read, and a write to it answers 409run_trashed. - A 409
revision_mismatchcarries one extension member,currentRevision: the run's revision now. Read the run again, merge, and retry withExpected-Revision: <currentRevision>(Concurrency). - A request that carries
If-Matchis refused with 422validation_failed(errors[].field: "If-Match") on every authenticated operation: the API's concurrency header isExpected-Revision. Some hosting layers answer such a request with412 Precondition Failedbefore it reaches the API; both mean "sendExpected-Revisioninstead".
Everything under /api answers this way — an unknown path is a 404 problem, a wrong verb a 405 problem with an Allow header, a non-JSON body a 415. The code vocabulary is open: new codes may be added without a version bump, so treat an unknown code as its HTTP status would suggest.
Error codes
| Code | Status | Title |
|---|---|---|
unauthorized |
401 | Authentication required |
invalid_api_key |
401 | Invalid API key |
key_revoked |
401 | API key revoked |
insufficient_scope |
403 | Insufficient scope |
read_only_key |
403 | Read-only key |
not_allowed_for_key |
403 | Not allowed for this key |
rate_limited |
429 | Too many requests |
idempotency_key_reused |
422 | Idempotency key reused |
idempotency_in_progress |
409 | Request in progress |
validation_failed |
422 | Validation failed |
unsupported_media_type |
415 | Unsupported media type |
payload_too_large |
413 | Payload too large |
method_not_allowed |
405 | Method not allowed |
not_found |
404 | Not found |
revision_mismatch |
409 | Revision mismatch |
run_archived |
409 | Run is archived |
run_trashed |
409 | Run is in Trash |
task_locked |
409 | Task is locked |
task_hidden |
409 | Task is hidden |
task_completed |
409 | Task already completed |
field_not_writable |
422 | Field is not writable |
required_fields_unsatisfied |
422 | Required fields unsatisfied |
workflow_not_published |
409 | Workflow not published |
workflow_not_runnable |
403 | Workflow not runnable |
approver_only |
403 | Approver only |
workflow_trashed |
409 | Workflow is in Trash |
wrong_task_kind |
409 | Wrong task kind |
task_not_configured |
409 | Task not configured |
upload_incomplete |
409 | Upload incomplete |
webhook_disabled |
409 | Webhook disabled |
delivery_not_terminal |
409 | Delivery not finished |
schedule_ended |
409 | Schedule ended |
internal_error |
500 | Internal error |
unavailable |
503 | Service unavailable |
unauthorized
401 Authentication required. No credential was sent, or Authorization and X-API-Key carried two different values. Send the key as Authorization: Bearer <key>. The response carries WWW-Authenticate: Bearer realm="processcart".
invalid_api_key
401 Invalid API key. The key is not recognized — malformed, or not one this deployment issued. Check for stray whitespace and that the whole secret was copied.
key_revoked
401 API key revoked. The key was revoked in Settings → API, or it was rotated and its 24-hour grace period has ended. Switch to the replacement key.
insufficient_scope
403 Insufficient scope. The key does not hold the scope the operation needs; detail names it. Mint a key with that scope (see Scopes).
read_only_key
403 Read-only key. A read-only key sent a request other than GET / HEAD. Read-only keys may only read, whatever scopes they hold.
not_allowed_for_key
403 Not allowed for this key. The workflow (or its folder) is outside the key's allowlist. Also answers: a folder-restricted key on the webhook routes; a webhook whose workflowIds is not a non-empty subset of a workflow-restricted key's list; deleting a comment's file through the API; a view write by a key whose creator is no longer a Builder or Admin; an automation rule for every workflow (workflowId: null) used by a key with an allowlist.
rate_limited
429 Too many requests. More than 600 requests in the key's current 60-second window. Wait Retry-After seconds (RateLimit-Reset says the same) and retry.
idempotency_key_reused
422 Idempotency key reused. The same Idempotency-Key arrived with a different method, path, body or Expected-Revision — or from a different API key. Use a fresh key for every distinct request; nothing was changed.
idempotency_in_progress
409 Request in progress. A request with this Idempotency-Key is still running. Retry after Retry-After seconds; the stored answer is then replayed.
validation_failed
422 Validation failed. The query, body or a header failed validation — a malformed Expected-Revision, or any If-Match header (the API refuses it; send Expected-Revision). errors[] lists every problem with its field and a code from the vocabulary below; nothing was changed.
unsupported_media_type
415 Unsupported media type. The request body is not application/json (the Content-Type header decides).
payload_too_large
413 Payload too large. The request body exceeds 1,048,576 bytes, or a file exceeds 25 MB.
method_not_allowed
405 Method not allowed. The path exists but not for this verb; the Allow header lists the verbs it supports.
not_found
404 Not found. No such resource in your workspace: an id that is not a uuid, a run or workflow of another workspace, a task or field key the run's version does not define, a private saved view, a workflow or run outside what the key may see. The API never reveals whether the id exists elsewhere.
revision_mismatch
409 Revision mismatch. Expected-Revision named a revision the run no longer has. The problem body's currentRevision (and its detail) carry the current revision — read the run again, merge, and retry with Expected-Revision: <currentRevision>.
run_archived
409 Run is archived. The run is archived. Only a status change (PATCH /v1/runs/{id} with status) is accepted until it is active again.
run_trashed
409 Run is in Trash. The run is in Trash. Restore it (POST /v1/runs/{id}/restore) before writing to it.
task_locked
409 Task is locked. The task sits behind an incomplete stop task, or behind an approval that sent it back. Finish the earlier work first.
task_hidden
409 Task is hidden. A visibility rule hides the task right now; it cannot be acted on until the rule's condition changes.
task_completed
409 Task already completed. The task is already done: a field of a completed task was written, or an approval already approved was approved again. Reopen the task first (/reopen).
field_not_writable
422 Field is not writable. The field cannot be written through the API: a formula, file or Display Text field, a field a formula computes, or a hidden field carrying a formula. errors[] names each such field with the reason as its code (computed, file, display_text — or field_not_writable itself). Files go through POST /v1/runs/{id}/files.
required_fields_unsatisfied
422 Required fields unsatisfied. Completing the task would leave a required field blank, or keep a value its format rules refuse (out of bounds, a failed pattern): errors[] lists every offender with code: "required". Starting a run (POST /v1/runs) answers it when a required kickoff field is missing: errors[] lists each missing one as required and, in the same response, every kickoff value its rules refuse as invalid_value (refused values alone at start are 422 validation_failed).
workflow_not_published
409 Workflow not published. The workflow has no published version yet; publish it in the builder before starting runs, reading its schema, scheduling it (create, resume or run a schedule now, or change a schedule's presets or assignment overrides) or naming its tasks and fields in an automation rule.
workflow_not_runnable
403 Workflow not runnable. The workflow is archived, so a schedule cannot start runs of it: creating a schedule of it, changing a schedule's presets or assignment overrides, resuming one or running one now answers this. Unarchive the workflow first. (A workflow outside the key's allowlist answers 403 not_allowed_for_key instead.)
approver_only
403 Approver only. Deciding (or reopening) an approval needs the approvals:decide scope; the key does not hold it.
workflow_trashed
409 Workflow is in Trash. The workflow is in Trash: restore it in the app before restoring its runs; before creating, resuming or running a schedule of it, or changing a schedule's presets or assignment overrides; or before creating, changing or turning on an automation rule of it.
wrong_task_kind
409 Wrong task kind. The verb does not fit the task's kind: approve / reject on a standard task, complete on an approval task.
task_not_configured
409 Task not configured. The task cannot be completed through the API as configured — an email task with no send configuration.
upload_incomplete
409 Upload incomplete. Finalize was called before the file's bytes reached the upload URL. PUT the bytes first (see Tasks, approvals & files).
webhook_disabled
409 Webhook disabled. The webhook is disabled; enable it (POST /v1/webhooks/{id}/enable) before sending a test event or redelivering.
delivery_not_terminal
409 Delivery not finished. The delivery is still pending or mid-retry; only a delivered, failed or exhausted delivery can be redelivered.
schedule_ended
409 Schedule ended. The schedule's end date has passed, so it has no future runs to resume; change its recurrence (a later end date, or none) before resuming.
internal_error
500 Internal error. Something failed on our side. Retry once; if it persists, quote the requestId to support.
unavailable
503 Service unavailable. A dependency did not answer — the database (the answer then carries Retry-After), storage signing a download link, or the encryption key a webhook secret needs. Retry with backoff; the status page shows whether a wider incident is open.
The errors[].code vocabulary
errors[].code |
Meaning |
|---|---|
required |
A required value is missing (a body, a field, a comment, a group list). |
invalid_json |
The request body is not valid JSON. |
invalid |
A header or body value is malformed (Expected-Revision, Idempotency-Key, a filter, a webhook body), or a header this API refuses (If-Match). |
invalid_value |
The value is the right type but not acceptable (an impossible date, an out-of-bounds number, a failing custom rule). |
invalid_input |
The input is not acceptable as a whole (a comment body that is empty or too large). |
unknown_parameter |
A query parameter this endpoint does not take; the message suggests the camelCase spelling. |
unknown_key |
A body key that belongs to another operation: enabled on a webhook, schedule or rule body (the message names the operations that turn it on and off). |
invalid_cursor |
The cursor is not one this API handed out (or it was altered). |
cursor_mismatch |
The cursor belongs to a different filter or sort than this request. |
conflicts_with_updated_since |
updated forces updated ascending; an explicit conflicting sort / order is refused. |
unsupported_sort |
This list cannot be sorted by that key. |
viewer_relative |
A viewer-relative filter ("me") has no meaning for an API key. |
too_many_rows |
The export would exceed its row cap; narrow the filter. |
unknown_field |
No field with this key exists on the run's workflow version. |
field_not_writable |
The field cannot be written through this endpoint. |
computed |
The field is a formula; its value is computed, never written. |
file |
A File field is written through the files endpoints, not set-fields. |
too_large |
The stored file is empty or over the 25 MB limit; PUT the bytes again, or upload a smaller file. |
display_text |
A Display Text field holds no value. |
hidden |
The field is hidden by the workflow's rules right now. |
wrong_type |
The JSON type does not match the field (a string where a number belongs, …). |
unparseable |
The text could not be parsed in the field's format (a date, a phone number, …). |
not_finite |
A number must be finite. |
too_long |
The text exceeds the field's maximum length. |
not_a_choice |
The value is not one of the field's choices. |
not_an_item |
The value names a checklist item the field does not have. |
not_a_member |
The user id is not a member of this workspace. |
unknown_task |
No task with this key exists on the run. |
unknown_label |
A label id is not in the workspace's status-label set. |
unknown_workflow |
A workflow id is not in this workspace. |
unknown_folder |
No folder with this id is in the workspace. |
unknown_group |
No group with this id is in the workspace. |
unknown_webhook |
No webhook with this id is in the workspace. |
not_a_date_field |
The Key Date field must be date-typed. |
invalid_template |
The template JSON does not match the portable template format. |
unsupported_version |
The template's format / engine is not one this API reads. |
publish_gate |
The template fails the publish checks a hand-built workflow must pass. |
duplicate_key |
The template repeats a section, task or field key; keys must be unique within a workflow. |
limit_reached |
A workspace or per-person maximum is reached (saved views per creator, schedules or enabled rules per workspace); delete or disable one first. |
url_policy |
The webhook URL is refused (https only; no private, loopback or own-host addresses). |
invalid_type |
The JSON type is wrong for this member (or a required member is missing). |
invalid_string |
The string fails its format (a uuid, an instant, a date shape, an email, a pattern). |
invalid_enum_value |
The value is not one of the allowed values. |
invalid_literal |
The value must be one exact constant. |
invalid_union |
The value matches none of the allowed shapes. |
invalid_union_discriminator |
The discriminator member names no known variant. |
invalid_date |
Not a valid date. |
too_small |
Below the minimum (length, count or value). |
too_big |
Above the maximum (length, count or value). |
not_multiple_of |
The number is not a multiple of the required step. |
unrecognized_keys |
The body carries a key this endpoint does not take. |
custom |
The value fails a rule this endpoint applies (the message says which). |
Getting help
Every response — success or failure — carries X-Request-Id. The same id is in the request log under Settings → API, so an Admin can see what the key did. Include it when you write to support.