Response envelope
Every API response follows one of three shapes. Switch on code, never on HTTP status.
Successful list
{
"code": 0,
"message": "success",
"contacts": [ { … }, { … } ],
"page_context": {
"per_page": 50,
"has_more_page": true,
"next_cursor": "eyJpZCI6Im…"
}
}The data array lives under the resource plural — contacts, invoices, bills, etc. — never under a generic data key.
Successful single resource
{
"code": 0,
"message": "success",
"contact": { … }
}Single-resource responses key on the resource singular. Same rule for POST / PUT — the created or updated object comes back under its own name.
Error
{
"code": "not_found.resource",
"message": "Invoice 'inv-abc' not found in this org.",
"field": "invoice_id"
}Errors are flat — no nested error wrapper. The string code is the contract; the message is for humans. See Errors for the full code catalog.