jsontoschema
All posts
apidocumentationschema

Documenting API Responses with Generated Schemas

API documentation rots. The endpoint returns new fields, someone adds a nullable property, and the docs still show the response from six months ago. The problem is not laziness. Writing accurate response documentation takes real effort, and that effort compounds across dozens of endpoints.

A faster approach: hit the endpoint, paste the response into a schema generator, and use the output as your documentation. The schema captures every field, its type, and whether it is optional. It updates in seconds instead of hours.

What a generated schema looks like

Suppose your /users/:id endpoint returns this:

{
  "id": 4012,
  "email": "dev@example.com",
  "name": "Alex Chen",
  "role": "editor",
  "team": null,
  "created_at": "2026-01-15T09:30:00Z",
  "preferences": {
    "theme": "dark",
    "notifications": true
  }
}

A generated schema reduces this to its structure:

{
  id: number,
  email: string,
  name: string,
  role: string,
  team: string | null,
  created_at: string,
  preferences: {
    theme: string,
    notifications: boolean
  }
}

No sample values to go stale. No ambiguity about types. The string | null on team tells consumers exactly what to expect. This format is compact enough to drop into a README, a Notion doc, or a code comment above the fetch call.

Handling multiple response shapes

Real APIs return different shapes depending on context. A list endpoint includes pagination. An error response has a different structure entirely. The trick is to generate a schema for each variant and label them.

For a paginated list:

{
  data: [{
    id: number,
    email: string,
    name: string,
    role: string,
    team?: string | null,
    created_at: string
  }],
  meta: {
    page: number,
    per_page: number,
    total: number
  }
}

The ? suffix on team appears when you feed multiple sample items where some lack the field. Array merging handles this automatically: pass in a response with three users, and the schema reflects which fields are consistent and which vary.

Fitting this into your workflow

The lowest-friction version of this process:

  1. Run your API tests or hit the endpoint with curl.
  2. Paste the response into the converter.
  3. Copy the schema into your docs.

For teams that want automation, the @maisondigital/jsontoschema npm package accepts JSON on stdin and outputs a schema. Pipe curl output through it in a CI step to regenerate docs on every release.

curl -s https://api.example.com/users/1 | npx @maisondigital/jsontoschema

This gives you documentation that is always accurate because it comes from real responses, not from someone's memory of what the response looked like.

When this beats OpenAPI

OpenAPI specs are thorough but expensive to maintain. For internal APIs, prototypes, or early-stage projects, a generated schema in a markdown file is often enough. It answers the question every consumer actually has: "what fields does this return, and what are their types?"

If you later need a full OpenAPI spec, the schema still saves time. It gives you an accurate snapshot to translate rather than starting from scratch.

The next time your API docs fall behind, skip the manual update. Paste a real response into the converter and let the schema do the documenting.