Skip to main content
Convert2JSON

JSON API response examples

The response shapes you meet in practice, and what each convention costs the client that consumes it.

Last reviewed

A single resource

Two decisions worth copying. The id is a string, which removes the large-integer precision problem entirely. And `verifiedAt` is present as null rather than absent, so the client can tell "not verified" from "the server did not send this field".

{
  "id": "usr_8f2c41",
  "email": "[email protected]",
  "displayName": "Ada Lovelace",
  "createdAt": "2026-03-14T09:21:00Z",
  "plan": { "id": "pro", "seats": 5 },
  "verifiedAt": null
}

A collection with pagination

Cursor pagination is stable under inserts; offset pagination is not, and will silently skip or repeat rows on a busy table. Wrapping the list in `data` costs one level of nesting and buys somewhere to put pagination without changing the array’s shape.

{
  "data": [
    { "id": "ord_1001", "total": 24.99, "status": "paid" },
    { "id": "ord_1002", "total": 12.00, "status": "pending" }
  ],
  "page": { "size": 2, "cursor": "eyJvIjoxMDAyfQ", "hasMore": true },
  "total": 137
}

An error response

A machine-readable `type`, a human-readable `message`, a `requestId` that appears in the logs, and per-field detail. The one thing to avoid is putting the whole error in the message string: clients then parse prose, and the prose changes.

{
  "error": {
    "type": "validation_failed",
    "message": "The request body did not pass validation.",
    "requestId": "req_7d1e",
    "details": [
      { "field": "email", "code": "invalid_format" },
      { "field": "seats", "code": "out_of_range", "min": 1, "max": 50 }
    ]
  }
}

Nested versus referenced resources

// embedded — one round trip, larger payload, duplication across items
{ "id": "ord_1001", "customer": { "id": "usr_8f2c41", "email": "[email protected]" } }

// referenced — smaller, but the client needs a second request
{ "id": "ord_1001", "customerId": "usr_8f2c41" }

// sideloaded — one round trip, no duplication, more client work
{
  "data": [{ "id": "ord_1001", "customerId": "usr_8f2c41" }],
  "included": { "customers": [{ "id": "usr_8f2c41", "email": "[email protected]" }] }
}

A batch or partial-success response

Bulk endpoints need a shape that can say "three of these worked and one did not", which a single HTTP status cannot express. Returning 207-style per-item results, with the same error object used everywhere else, keeps clients from writing a second error parser.

{
  "results": [
    { "index": 0, "status": "created", "id": "ord_1003" },
    { "index": 1, "status": "created", "id": "ord_1004" },
    {
      "index": 2,
      "status": "failed",
      "error": { "type": "validation_failed", "details": [{ "field": "total", "code": "required" }] }
    }
  ],
  "summary": { "requested": 3, "succeeded": 2, "failed": 1 }
}

Conventions worth being deliberate about

  • Dates as ISO 8601 with an explicit offset. Unix timestamps are ambiguous about units and unreadable in logs.
  • Money as an integer number of minor units plus a currency code, never a float. 19.99 is not exactly representable.
  • Large ids as strings, for the reason above.
  • One casing convention for keys, applied everywhere. Mixed snake_case and camelCase in one payload is a reliable source of bugs.
  • Omit versus null, decided once and documented. Both are defensible; inconsistency is not.

Generate your client types from the real response

Documentation drifts from implementation. Capture an actual response, generate types from it, and you catch the field that was quietly renamed. Do it with a payload that exercises the optional fields — a generator can only describe what it is shown, so a sample where every optional field happens to be present produces types that claim everything is required.

Keep reading

  • JSON Schema examplesSchemas that do something, from a five-line object check up to conditionals and reusable definitions.
  • JSONPath examplesOne sample document, and the expressions people actually need against it, each with the result it produces.