Response format#
🔴 The most important chapter in this manual. Read it before writing a parser.
Two different shapes#
Reads and writes return different structures
A read has no success field. A write has one. A single parser keyed on
success is not possible.
Reading a collection#
{
"items": [
{ "id": { "id": 5 } },
{ "id": { "id": 6 } }
],
"totalCount": 42,
"_references": {
"App\\UI\\Api\\Blog\\Models\\Entities\\Article": {
"5": { "id": 5, "title": "…", "category": { "id": { "id": 3 } } },
"6": { }
},
"App\\UI\\Api\\Blog\\Models\\Entities\\Category": {
"3": { }
}
}
}
items holds references, not data
The actual values are in _references, keyed by the full class name and the
identifier. A client must dereference the references; otherwise, it gets only numbers.
References inside _references are references again — dereferencing is recursive.
A composite identifier key is joined with a hyphen
For example "3-7".
totalCount is zero until you ask for it
Send computeTotalCount=1. So zero does not mean "nothing found".
Reading one record#
Not found returns an empty array, not an error
With HTTP 200. Not HTTP 404 and notsuccess: false.
Writing#
The key order is fixed. code is a numeric result code; zero means
success.
The write response is incomplete
It returns only flat values of the saved entity — no nested collections and
no identifiers of newly created children. After writing with relations, read the
data back with includes.
An error envelope may not carry all four keys
Some error paths return only three. Do not rely on data being present.
A technical failure carries only a code
When the database or an internal call fails (the technical error codes, e.g. a database
error, an unknown error, a file write, an internal API error or timeout), message is
an empty string and the code decides. The details of the cause stay in the server
log. Validation and business-rule failures (a wrong value, a disallowed state, not
found, permission) carry their readable message as before. On an empty message the
client should therefore show its own generic text.
Pagination#
No links and no cursors. Just offset and limit in the query and totalCount in
the response.
Content type#
404 and 500 return HTML, not JSON
A non-existent resource or an unhandled exception returns an error page. Your
parser must check Content-Type or it will choke on invalid JSON.
Recommended processing#
- Check
Content-Type— if it is not JSON, it is a server error. - Check the status code: handle 400, 401, 403 and 429 separately. For 401 tell code
501(application key) from103(user token); for 429 waitRetry-After. 400 is an error in how the request is built (a wrong parameter shape, a forbidden field in a filter) and carries JSON, see Error codes. - If the response has
success, it is a write — decide by it and bycode. - If it does not, it is a read — dereference
_references.