Responses and errors
Successful response envelope
Successful endpoints return a JSON object with data and meta:
{
"data": {
"id": "CUS-0087",
"name": "Asha Mushi",
"phone": "+255 712 345 678",
"owner_sub": "account_subject"
},
"meta": {
"request_id": "req_...",
"timestamp": "2026-10-11T08:00:00Z"
}
}timestamp is generated in UTC using RFC 3339 with subsecond precision when available. The data value is an object for item/create/update operations and an array for list operations.
List metadata
List endpoints include pagination details in meta.pagination:
{
"data": [],
"meta": {
"request_id": "req_...",
"timestamp": "2026-10-11T08:00:00Z",
"pagination": {
"page": 1,
"page_size": 20,
"total": 0,
"total_pages": 0
}
}
}page defaults to 1 and page_size defaults to 20. Invalid or less-than-one values use those defaults. A page size above 100 is capped at 100. An empty collection endpoint reports total: 0 and total_pages: 0. The derived /payments endpoint is a special case: its fixed metadata reports total_pages: 1, even when it contains no rows.
Error envelope
Errors use this shape:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "name is required"
},
"meta": {
"request_id": "req_...",
"timestamp": "2026-10-11T08:00:00Z"
}
}Some not-found errors include error.details with the collection and requested ID. Treat code as the stable programmatic value; the message is intended for diagnosis and may become more descriptive.
The health endpoint uses a health-shaped data object rather than a collection record. Delete responses also return a small data result. /payments returns calculated ledger rows; its method can be null if the source order has no method.
HTTP status and error codes
| HTTP | Code | Meaning / client action |
|---|---|---|
400 | INVALID_JSON | Request body could not be decoded as one JSON object. Correct the body and retry. |
401 | UNAUTHORIZED | Missing or invalid Camel Accounts bearer token; refresh or sign in again. |
404 | NOT_FOUND | Unknown endpoint/resource or record unavailable to this account. |
405 | METHOD_NOT_ALLOWED | Method is not supported; inspect the endpoint method list and Allow header. |
422 | VALIDATION_ERROR | Required fields or positive amount checks failed. Correct the payload. |
500 | STORAGE_ERROR | SQLite could not create, update, or delete the row. Do not blindly repeat writes if you cannot confirm whether a prior operation completed. |
503 | AUTH_UNAVAILABLE | Camel Accounts userinfo could not be reached. Retry with backoff. |
The route checks authentication before looking up protected resources. Therefore an unauthenticated request to a misspelled protected path returns 401; after successful authentication, the same path returns 404. OPTIONS is separate: it returns 204 without JSON, authentication, or a request ID.
Unknown paths return 404; unsupported methods return 405. Invalid JSON bodies are limited to 1 MiB and must contain exactly one JSON object.
Request IDs
Send an optional X-Request-ID header to correlate a request with caller logs. If omitted, the API creates a random ID. For normal JSON responses, the value is echoed in the response header and in meta.request_id, including errors. Generated IDs are included in API access logs; caller-supplied values are omitted from those logs. OPTIONS preflight replies are an exception: they return 204 before request ID generation and have no JSON metadata. A caller-provided ID is echoed as given; use a unique, non-sensitive value.
Retry guidance
- Safe to retry: health checks, list/item reads, and requests rejected before mutation (such as
400,401,404, and422). - Retry
503after a short exponential backoff; the unavailable service is Camel Accounts. - For a timeout while creating or updating a record, first list/find by your own business key or check the response/request ID. The API does not yet support idempotency keys.