2 min read
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.