Request and response shape

Topics in this section
2 cards

Consistent JSON

Clients write code against your field names, so pick conventions once and apply them everywhere. Use one naming style (snake_case or camelCase, not both). Send times as ISO 8601 strings in UTC: "2026-10-23T14:05:00Z". Send money as an integer in minor units plus a currency: {"amount": 1999, "currency": "EUR"} for €19.99; floating-point numbers can't represent most decimal amounts exactly.

Return ids as strings, even if they're numbers today: JavaScript loses precision on integers above 2⁵³, and you may switch to UUIDs later. And wrap lists in an object, {"data": […], "next_cursor": …}, so you can add paging fields later without breaking clients.

In real life

Stripe returns amounts in the smallest currency unit (cents) and ids like "ch_3Nx…" as strings. Twitter's API added an id_str field because its numeric ids lost precision in JavaScript.

In code: HTTP
GET /orders/42
→ 200 OK
{
  "id": "42",
  "status": "paid",
  "total": {"amount": 1999, "currency": "EUR"},
  "created_at": "2026-10-23T14:05:00Z",
  "customer_id": "7"
}

GET /orders
→ 200 OK
{"data": [ … ], "next_cursor": "eyJpZCI6NDJ9"}
  • 0.1 + 0.2 is 0.30000000000000004 in floating point; integer cents avoid that class of bug.
  • A bare top-level array can't gain new fields later; an object can.
Check yourself

Which choices make a payments API's JSON safer for clients? (Choose three.)

Select 3, then check.

One error format

Every error from your API should have the same shape, so a client writes one error handler. The IETF standard for this is Problem Details (RFC 9457), sent as Content-Type application/problem+json. Its fields, all optional: type (a URI identifying the kind of error), title (short, human-readable), status (the HTTP code), detail (this occurrence), instance (which request). You may add your own fields, such as a list of invalid fields.

Two rules make errors useful. Give a stable machine-readable code (the type), so clients branch on it instead of parsing English. And never put stack traces, SQL or internal hostnames in the body: they help attackers, not users.

In real life

A validation error for a booking: status 422, type …/errors/invalid-dates, detail 'check_out must be after check_in', plus errors: [{"field": "check_out", …}] so the form can highlight the field.

In code: HTTP
POST /bookings
{"check_in": "2026-11-05", "check_out": "2026-11-03"}

→ 422 Unprocessable Content
Content-Type: application/problem+json
{
  "type": "https://api.example.com/errors/invalid-dates",
  "title": "Invalid dates",
  "status": 422,
  "detail": "check_out must be after check_in",
  "errors": [{"field": "check_out", "message": "must be after check_in"}]
}
  • RFC 9457 replaced RFC 7807 in 2023; the format is the same.
  • The extra 'errors' array is an extension, which the RFC allows.
Check yourself

What belongs in an API error response? (Choose two.)

Select 2, then check.