How to handle API errors
Parse and act on RFC 7807 error responses from the UrbanFox API
Before you start
The UrbanFox API returns structured errors following the RFC 7807 standard. This guide shows you how to parse these responses and take the correct action for each error type.
- An authenticated integration making requests to the UrbanFox API
Check the error shape
Every error response follows RFC 7807 Problem Details:
{
"title": "Application Error",
"status": 404,
"type": "item-not-found",
"detail": "Case not found",
"errors": null
}Parse the response
Use the same flow in any HTTP client:
- Check the HTTP status code.
- For
4xxor5xxresponses, parse the JSON response body. - Use the
typefield for programmatic handling. - Use the
detailanderrorsfields for logs, support messages, or user-facing validation feedback.
Handle by status code
Use the status code and type field for the first routing decision:
| Status | Type | Action |
|---|---|---|
400 | bad-request | Malformed request; check the body and parameters |
401 | unauthorized | Token is invalid or expired; re-authenticate |
403 | access-denied | Missing permission or tenant mismatch; check credentials |
404 | item-not-found | The resource does not exist; verify the ID |
409 | item-already-exists | Resource already exists; use a different ID or fetch the existing one |
409 | item-version-conflict | The item changed after you read it; read it again, decide whether your update still applies, and only then resend it with the current_version the response carries |
409 | operation-idempotency-conflict | You reused an Idempotency-Key with a different body; use a new key for a new update |
409 | transaction-contended | A concurrent write got there first and the API applied nothing; read again and retry |
422 | validation-error | Request body failed schema validation; see field errors |
428 | precondition-required | The update needs case_version in the body; read the item and send the version you read |
500 | internal-error | Retry with exponential backoff; report if persistent |
502 | bad-gateway | Upstream dependency failed; retry after a short delay |
A 400 with type set to invalid-operation-id means the Idempotency-Key header is missing
or does not fit the accepted shape: it must be 1 to 255 characters from letters, digits, ., _, :, ~, + and -.
Retry a case update safely
A case status update (PUT /cases/{case_id}) requires two things from you. Other writes, such as
end-user account updates, use neither:
case_versionin the body: the version you last read. If the item changed in between, you get409item-version-conflictwith the current version, and the API applies nothing.Idempotency-Keyheader: one value per update you intend. The API accepts any 1 to 255 characters from letters, digits,.,_,:,~,+and-; use a UUID v7, which is unique without coordination and sorts by time; the API also takes any other UUID version. Send the same value when you retry that update after a timeout or a lost response, and the API answers with the result of the first attempt instead of applying it again. A new update gets a new key. If you recover from a version conflict, the body changes, so use a new key for that too.
The case status update guide shows a complete request.
Handle validation errors
For 422 responses, the errors array contains one entry per invalid field:
{
"title": "Validation Error",
"status": 422,
"type": "validation-error",
"detail": "Request validation failed",
"errors": [{ "field": "email", "message": "Invalid email format" }]
}Iterate over errors[] to surface field-specific messages to users or logs. For other error types, use detail as the operational message.
If it's not working
| Symptom | Action |
|---|---|
| Response body is not JSON | Check you are calling the correct base URL |
errors array is null on a 400 | Not all 400 responses are validation errors; use type to distinguish |
See also
- API Reference for per-endpoint error codes and complete response schemas
- How to authenticate with the UrbanFox API
- How to investigate and close a case for a versioned, retry-safe update end to end