6. Response Shape
6. Response Shape
Wrapping every response in a consistent envelope gives you a stable contract with your clients. It also buys you room to add metadata — pagination links, request IDs, warnings — without changing the shape of the actual data.
Success Envelope
Wrap collection and single-resource responses in a data key. Attach pagination metadata and navigation links at the top level:
{
"data": [
{ "id": 1, "name": "Widget A" },
{ "id": 2, "name": "Widget B" }
],
"meta": {
"total": 120,
"per_page": 20,
"current_page": 2,
"last_page": 6
},
"links": {
"self": "/products?page=2",
"next": "/products?page=3",
"prev": "/products?page=1"
}
}
For a single resource, data contains the object directly rather than an array:
{
"data": {
"id": 42,
"name": "Widget A",
"price": 19.99
}
}
Error Envelope
Errors follow the same top-level structure so that clients can handle them uniformly regardless of the error type:
{
"error": {
"code": 404,
"message": "The requested product was not found."
}
}
For validation errors, include a details object that maps each invalid field to an array of error messages (see topic 13 for the full convention).
Why an Envelope?
Without an envelope, a collection endpoint returns a bare JSON array. This creates two problems:
- You cannot add metadata later without breaking the response contract (an array cannot suddenly become an object).
- Top-level JSON arrays are a minor security concern in older browsers due to historical JSON hijacking vulnerabilities.
An envelope solves both problems from day one and makes your API far easier to extend over time.