Error handling
Status codes
Section titled “Status codes”| Status | Meaning | Retry? |
|---|---|---|
400 |
Malformed request | No — fix the request |
401 |
Token present but invalid | No — fix the token |
403 |
No Authorization header, or method not allowed on this path |
No |
404 |
Unknown form_slug or slug |
No — check both |
406 |
Cannot satisfy the Accept header |
No |
415 |
Unsupported media type | No — send application/json |
422 |
Validation failed | No — fix the payload |
429 |
Throttled | Yes — exponential backoff |
431 |
Header fields too large | No |
461 |
Insufficient workspace credit | No — alert and top up |
500 |
Server error | Yes — up to 3× with backoff, then alert |
Response envelopes
Section titled “Response envelopes”Most errors use one shape:
{ "error": { "status_code": 401, "message": "Unauthorized", "detail": "No permission -- see authorization schemes" }}On 422, error.detail is an object keyed by question_key instead of a string.
Three responses use a different shape:
| Where | Shape |
|---|---|
422 from .../submit/ |
Flat {"field": ["message"]} — no error wrapper |
404 from .../hook-submit/ |
{"detail": "No AppliedForm matches the given query."} |
461 from .../create/ |
{"detail": "Insufficient Credit", "code": "InsufficientCredit"} |
Branch on the HTTP status first, then read whichever shape that status uses.
461 — insufficient credit
Section titled “461 — insufficient credit”{ "detail": "Insufficient Credit", "code": "InsufficientCredit" }Retry policy
Section titled “Retry policy”400 / 401 / 403 -> do not retry; fix the request or the token404 -> do not retry; check form_slug and slug422 -> do not retry; fix the payload429 -> retry with exponential backoff461 -> do not retry; alert and top up workspace credit5xx -> retry up to 3x with backoff, then alertIntegration checklist
Section titled “Integration checklist”- API token stored server-side only, never shipped to a client.
-
slugpersisted against your own record at create time. -
slugandform_urltreated as secrets — out of logs and analytics. - Pre-filled personal data kept to the minimum.
- Webhook receiver validates the
Authorizationheader. - Idempotency keyed on
slug+submitted_at, not onnounce. - Receiver returns
2xxwithin 30 seconds. - Signed images fetched within 15 minutes and copied to your own storage.
- Receiver size-tested against a sanctions-match payload.
- Status values compared case-insensitively, with fallbacks for renamed columns.
- Every response envelope handled, including the flat
422and the461body. - Alerting on
429,461and5xx. - Desktop visitors shown a QR code, not a dead redirect.
Getting help
Section titled “Getting help”When contacting UpPass support, include:
form_slug |
the flow |
| Application number | application.no, e.g. COK00100001 |
slug |
the application |
event.nounce |
for a webhook issue |
| Timestamp (UTC) | application.submitted_at |