JSON API Tutorial: Designing Clean Request and Response Bodies
Practical patterns for JSON APIs including envelopes, errors, pagination, versioning, and examples you can adapt.
What “JSON API” means here
This tutorial focuses on HTTP APIs that exchange JSON—not exclusively the formal JSON:API specification (though some ideas overlap). You will design predictable request bodies, response shapes, and error objects that clients can rely on.
Start with resources, not RPC soup
Model nouns your product already uses: users, projects, invoices. Prefer:
GET /projects/42
over overloaded endpoints that hide meaning in the body alone. Use JSON bodies for create/update payloads:
{
"name": "Northwind Launch",
"status": "planned"
}
Keep verbs in HTTP methods: POST to create, PATCH for partial updates, PUT when replacing a resource makes sense for your domain.
Response consistency
Pick a convention and apply it everywhere. Two common styles:
Direct resource
{
"id": 42,
"name": "Northwind Launch",
"status": "planned"
}
Envelope
{
"data": {
"id": 42,
"name": "Northwind Launch",
"status": "planned"
},
"meta": { "requestId": "req_9f3" }
}
Envelopes help when you always need meta or pagination fields. Direct resources feel lighter. Either works—mixing them freely does not.
Errors clients can parse
Avoid returning HTML error pages to API clients. Prefer structured JSON:
{
"error": {
"code": "validation_failed",
"message": "name is required",
"details": [
{ "field": "name", "issue": "required" }
]
}
}
Use appropriate status codes (400, 401, 404, 409, 422, 500) and keep code stable for programmatic handling.
Pagination pattern
{
"data": [ ... ],
"pagination": {
"nextCursor": "eyJpZCI6MTAwfQ",
"limit": 25
}
}
Cursor pagination scales better than naive offset for large datasets. Include links if your clients prefer HATEOAS-style navigation.
Versioning without chaos
Options include URL prefixes (/v1/), headers, or media types. URL versioning is the most obvious for public APIs. Do not silently break JSON field meanings inside an existing version—add fields, deprecate carefully, remove only in a new version.
Content negotiation basics
Send Content-Type: application/json on bodies. Ask clients to send Accept: application/json. Reject ambiguous payloads early rather than guessing.
While integrating, keep a formatter/validator nearby. JSON Editor is handy for shaping example requests and verifying fixtures before you wire them into Postman or automated tests.
Testing checklist
- Happy-path create/read/update/delete
- Validation errors return stable JSON
- Auth failures do not leak internal traces
- Pagination empty states return arrays, not
null - Unknown fields policy is documented (
ignorevsreject)
Ship a small vertical slice
Implement one resource end-to-end with docs and examples. Expand patterns only after the first slice feels boringly consistent. Clean JSON APIs are less about clever tricks and more about repeating simple shapes until clients trust you.
Related articles
APIs · 3 min read
REST API JSON Basics: Methods, Status Codes, and Payloads
Learn how REST-style HTTP APIs use JSON for bodies, which status codes pair with which outcomes, and how to avoid common pitfalls.
Basics · 3 min read
JSON for Beginners: Syntax, Examples, and First Steps
A practical beginner guide to JSON syntax, nesting, arrays, and safe habits for reading and writing valid documents.
Best Practices · 3 min read
JSON Best Practices for Maintainable APIs and Configs
Field-tested JSON best practices covering naming, nulls, versioning, size, security, and documentation habits.