How to Use JSON in REST APIs

JSON has become the de facto standard format for REST APIs, but using JSON correctly in an API involves more than just returning data in that format. This post covers the most common practices: how to structure requests and responses, the right header, and error handling patterns.

The Content-Type header

Every request and response carrying a JSON body should explicitly indicate that through the Content-Type header.

Content-Type: application/json

This tells the other side (client or server) that the message body should be interpreted as JSON, instead of trying to guess from the content. Without this header, some clients or servers might simply fail to parse the body correctly.

Structuring a success response

There’s no mandatory universal standard, but a common convention is to wrap the data in a predictable key.

// json
{
  "data": {
    "id": 123,
    "name": "Ana"
  }
}

This leaves room to add metadata later (pagination, for example) without breaking the existing structure.

// json
{
  "data": [
    { "id": 1, "name": "Ana" },
    { "id": 2, "name": "John" }
  ],
  "meta": {
    "page": 1,
    "totalPages": 5,
    "totalItems": 47
  }
}

Structuring an error response

Just like success responses, errors also benefit from a consistent structure.

// json
{
  "error": {
    "code": "REQUIRED_FIELD",
    "message": "The 'email' field is required",
    "field": "email"
  }
}

Having an error code (in addition to the readable message) lets the API’s client handle specific errors programmatically, without needing to parse free-text messages.

Using HTTP status codes correctly

The JSON in the response body doesn’t replace correct use of HTTP status codes, the two work together.

200 OK                      - success, data returned
201 Created                 - resource created successfully
400 Bad Request             - malformed request or invalid data
401 Unauthorized            - authentication required or invalid
404 Not Found               - resource doesn't exist
422 Unprocessable Entity    - valid JSON, but fails business rules
500 Internal Server Error   - server-side error

A common mistake is returning status 200 even when the operation failed, putting just a "success": false field in the JSON body. This breaks HTTP semantics and forces the client to always check the response body before knowing whether the request succeeded, instead of being able to trust the status code.

Pagination

For endpoints returning large lists, including pagination information in the JSON prevents the client from having to guess how many items exist.

// json
{
  "data": [ /* current page items */ ],
  "meta": {
    "currentPage": 2,
    "perPage": 20,
    "totalItems": 143,
    "totalPages": 8
  },
  "links": {
    "next": "/api/products?page=3",
    "previous": "/api/products?page=1"
  }
}

Naming keys consistently

Pick a convention (usually camelCase or snake_case) and keep it consistent across the whole API. Mixing both conventions in the same response is a common source of confusion for whoever consumes the API.

// json
// Inconsistent, avoid this
{
  "userName": "Ana",
  "user_email": "[email protected]"
}

// Consistent
{
  "userName": "Ana",
  "userEmail": "[email protected]"
}

Versioning and structural changes

If the response JSON’s structure needs to change in an incompatible way down the line, that’s usually a sign the API needs versioning (via URL, like /v2/products, or via header), instead of simply changing the structure for every client at once, which would break existing integrations.

Quick checklist

  • Are you sending and checking the Content-Type: application/json header?
  • Using correct HTTP status codes, not just a success/error field inside the JSON?
  • Consistent error structure, with an error code in addition to the readable message?
  • Consistent key naming convention across the whole API?
  • Pagination info included in endpoints that return large lists?

To quickly validate whether the JSON your API is returning (or receiving) is correct, paste it into JSON Validator.