Error Format
All error responses include a request_id for correlation with support and a structured error object:
{
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"error": {
"status": 404,
"type": "not_found",
"message": "Deal with id 999 not found",
"details": {}
}
}| Field | Type | Description |
|---|---|---|
status | integer | HTTP status code mirrored in the envelope for convenience |
type | string | Short machine-readable error type (see Status Codes below) |
message | string | Human-readable description |
details | object | Additional context; always present but may be empty |
prerequisites | array | (optional) Actions required before the request can succeed |
upgrade_url | string | (optional) URL to upgrade the account when the error is tier-gated |
The request_id matches the value logged in usage tracking, so it can be referenced when contacting support.
Status Codes
| Code | type | Meaning |
|---|---|---|
200 | — | OK — successful read or update |
201 | — | Created — successful resource creation |
400 | bad_request | Invalid request body, missing required fields, malformed query parameters |
401 | unauthorized | Missing, invalid, or expired authentication token |
403 | forbidden | Valid token but insufficient permissions |
404 | not_found | Resource doesn't exist or isn't accessible to the authenticated user |
409 | conflict | Idempotency conflict (different request body with same idempotency key) |
422 | validation_error | Valid JSON but semantically invalid (e.g., invalid enum value) |
429 | rate_limit_exceeded | Rate limit exceeded |
500 | internal_error | Unexpected server error |
Common Errors
Missing authentication
{
"request_id": "...",
"error": {
"status": 401,
"type": "unauthorized",
"message": "Authentication required",
"details": {}
}
}Resource not found
Returns 404 both when a resource doesn't exist and when the authenticated user doesn't have access to it. This prevents information leakage about resource existence.
{
"request_id": "...",
"error": {
"status": 404,
"type": "not_found",
"message": "Deal with id 999 not found",
"details": {}
}
}Validation error
{
"request_id": "...",
"error": {
"status": 422,
"type": "validation_error",
"message": "Invalid value for field 'loan_type': must be one of [construction, heavy_bridge, light_bridge, permanent, land, predevelopment, tbd]",
"details": {}
}
}Rate limited
{
"request_id": "...",
"error": {
"status": 429,
"type": "rate_limit_exceeded",
"message": "Rate limit exceeded. Retry after 30 seconds.",
"details": {}
}
}