← Blog
API Documentation

API Reference Documentation: A Complete Writing Guide

API Reference Documentation: A Complete Writing Guide

API reference documentation is the structured, endpoint-by-endpoint record of every resource, method, parameter, request body, and response your API can produce. It is the single source of truth developers consult when integrating your API, and Apidoke lets you author it in API Blueprint format and publish a live, interactive three-column reference with a built-in try-it console, all without a custom toolchain.

  • Good API reference documentation covers six things per endpoint: the HTTP method and path, a plain-language description, all parameters, an example request body, every possible response with its status code, and at least one response body example.
  • Consistent structure matters more than prose quality; a predictable layout lets developers scan rather than read.
  • Real, copy-paste-ready examples (not pseudocode) are the single biggest factor in developer satisfaction with reference docs.
  • Apidoke renders API Blueprint source into a live three-column reference where readers can fire real HTTP requests without leaving the page, which means your examples are always testable, not just readable.

What does API reference documentation actually include?

The term "API reference" is sometimes used loosely to mean any developer documentation. For the purposes of this guide, it means the machine-accurate, endpoint-level specification: every URL, every field, every status code. Tutorial and conceptual docs are separate concerns (the distinction is explained well in our guide on reference docs vs tutorial docs).

For a REST API, each endpoint entry in your reference documentation should contain seven components. Here is why each one exists:

  1. HTTP method and full path. The method (GET, POST, PUT, PATCH, DELETE) and path together define the action. Write them exactly as the server expects: POST /v1/orders, not "create an order endpoint".
  2. Short description. One to two sentences saying what the endpoint does and any critical constraint (idempotent, rate-limited, requires admin scope). Skip marketing language.
  3. Authentication requirement. State what credential type is required (Bearer token, API key header, OAuth 2.0 scope). If the endpoint is public, say so explicitly.
  4. Parameters. Path parameters, query parameters, and header parameters, each in a dedicated table (see below).
  5. Request body. The schema and a realistic example payload for POST, PUT, and PATCH endpoints.
  6. Responses. Every status code the endpoint can return, with a description and a response body example for each.
  7. Error codes. The specific error objects your API returns for 4xx and 5xx conditions, not just the HTTP status.

How to structure parameter tables

Parameters are where most reference docs fall apart. A parameter listed as "the ID" with no type, no format, and no indication of whether it is required is useless under pressure. Use an HTML table (or, in API Blueprint, the MSON syntax that renders as one) with at minimum these five columns:

ColumnWhat to writeExample
NameExact parameter name, case-sensitiveorder_id
LocationPath, Query, Header, or CookiePath
Typestring, integer, boolean, array, objectstring
RequiredYes or No (never leave blank)Yes
DescriptionPlain-language meaning plus any format note (UUID v4, ISO 8601, max 255 chars)The unique order identifier (UUID v4)

Add a sixth column for "Default" whenever a query parameter has one. Omitting defaults forces developers to run trial-and-error requests to discover behavior that you already know.

Path parameters vs query parameters: keep them in separate tables

Path parameters (the {order_id} segment in /v1/orders/{order_id}) are always required; they define the resource identity. Query parameters (?status=pending&limit=20) are usually optional filters or pagination controls. Mixing them in one table creates ambiguity. Use a heading like "Path parameters" and a second heading "Query parameters" to keep them visually separated in the rendered doc.

Writing request body documentation

For any POST, PUT, or PATCH endpoint, the request body is the most-consulted section. Developers copy it, modify it, and send it. Treat it with the same rigor as code.

Show the Content-Type header (Content-Type: application/json), then provide two things: a schema describing each field, and a complete, valid example. Do not show a schema without an example, and do not show an example without field-level descriptions. Developers under deadline pressure will use whichever one answers their question fastest; give them both.

Here is what that looks like in API Blueprint syntax, which Apidoke renders directly:

## Create Order [POST /v1/orders]

Create a new order for the authenticated account.

+ Request (application/json)
    + Attributes
        + customer_id: `cust_9f3a2b` (string, required) - The unique customer identifier.
        + items (array[object], required) - Line items for the order.
            + (object)
                + sku: `SKU-001` (string, required) - Product SKU.
                + quantity: 2 (number, required) - Units ordered. Minimum 1.
        + currency: `USD` (string, optional) - ISO 4217 currency code. Defaults to account currency.
    + Body

            {
              "customer_id": "cust_9f3a2b",
              "items": [
                { "sku": "SKU-001", "quantity": 2 }
              ],
              "currency": "USD"
            }

The + Attributes block in API Blueprint uses MSON (Markdown Structured Object Notation) to define the schema inline. The + Body block supplies the runnable example. Both appear side by side in Apidoke's three-column viewer, so a developer reading the description on the left can copy the JSON on the right without switching context.

Documenting responses: status codes and response bodies

This section is where many teams write the least and where developers need the most. A response entry that says only "200 OK: Success" is no more useful than no documentation at all.

Which HTTP status codes should you document?

Document every status code your API actually returns. As a starting point, most REST endpoints return some combination of the following (all defined in RFC 9110, the HTTP semantics standard):

Status codeMeaningWhen to document it
200 OKRequest succeeded, body contains resultGET, PUT, PATCH on success
201 CreatedResource was created; Location header presentPOST on success
204 No ContentSucceeded, no body returnedDELETE on success
400 Bad RequestClient sent malformed or invalid inputAny endpoint accepting input
401 UnauthorizedMissing or invalid credentialsAny authenticated endpoint
403 ForbiddenCredentials valid but permission deniedEndpoints with scope or role restrictions
404 Not FoundResource does not existAny endpoint with a path parameter
422 Unprocessable EntitySyntactically valid but semantically wrongBusiness rule violations
429 Too Many RequestsRate limit exceededAny rate-limited endpoint
500 Internal Server ErrorServer-side faultAlways; tells developers when to open a bug

What to include in each response entry

For a successful 200 response, show the full response body schema (field names, types, nullable or not) plus a realistic example. For error responses, show the exact error object your API returns. If your API returns structured errors like this:

{
  "error": {
    "code": "INVALID_SKU",
    "message": "SKU 'SKU-999' does not exist in the product catalog.",
    "field": "items[0].sku"
  }
}

Document that shape. A developer seeing a 422 at midnight needs to know the error object structure without reading your source code. In API Blueprint, each response gets its own block:

+ Response 201 (application/json)
    + Body

            {
              "order_id": "ord_8c2e1a",
              "status": "pending",
              "created_at": "2026-04-12T14:33:00Z"
            }

+ Response 400 (application/json)
    + Body

            {
              "error": {
                "code": "MISSING_REQUIRED_FIELD",
                "message": "'customer_id' is required.",
                "field": "customer_id"
              }
            }

+ Response 401 (application/json)
    + Body

            {
              "error": {
                "code": "UNAUTHORIZED",
                "message": "Bearer token is missing or expired."
              }
            }

Apidoke renders each + Response block as a selectable tab in the right column, so developers can switch between the 201 and the 400 without scrolling.

Three-column API reference documentation layout showing navigation on left, endpoint description in center, and request/response examples on right

How to organize endpoints into groups and resources

API reference documentation that is just a flat list of 80 endpoints is unusable. Group endpoints by the resource they operate on, then let navigation reflect that hierarchy. In API Blueprint, this maps directly to the # Group keyword:

# Group Orders

Endpoints for creating, retrieving, updating, and cancelling orders.

## Orders Collection [/v1/orders]

### List Orders [GET]
### Create Order [POST]

## Order [/v1/orders/{order_id}]

+ Parameters
    + order_id: `ord_8c2e1a` (string, required) - UUID of the order.

### Get Order [GET]
### Update Order [PATCH]
### Cancel Order [DELETE]

In Apidoke's published output, each # Group becomes a collapsible section in the left navigation column. Developers looking for order-related endpoints find them immediately without reading unrelated content. This structure also makes the reference scannable by the search engines and AI answer engines that parse your published docs page.

Documenting authentication per endpoint

Authentication documentation belongs at two levels: a top-level section explaining the mechanism (Bearer token, API key in the X-API-Key header, OAuth 2.0) and a per-endpoint note confirming what that specific endpoint requires. Never assume developers read the top-level section before looking at an individual endpoint.

A minimal per-endpoint note looks like this in plain prose:

Requires a valid Bearer token in the Authorization header. The token must carry the orders:write scope. A missing or expired token returns 401; an insufficient scope returns 403.

That one sentence tells a developer exactly what credential to send and what they will see if they get it wrong, covering both the happy path and the two most common failure modes. Our full guide on API documentation tools and practices covers authentication documentation in broader context.

Writing example values that actually work

Use real-looking but safe placeholder values, not generic strings like "string" or 12345. A UUID that looks like a real UUID (cust_9f3a2b) and a timestamp that looks like a real ISO 8601 timestamp (2026-04-12T14:33:00Z) teach the format implicitly. Developers copy examples first and read descriptions second.

Avoid these common mistakes:

  • Using "foo" or "bar" as string examples (they teach nothing about format).
  • Using 1 or 2 as ID examples (they look like sequential integers when your IDs are UUIDs).
  • Truncating arrays to ["..."] (show at least two elements so the structure is obvious).
  • Omitting optional fields from examples (include them with a comment noting they are optional, so developers know the field exists).

Keeping your reference documentation accurate over time

Stale API reference documentation erodes developer trust faster than any other documentation failure. A parameter table that still lists a field your API removed three months ago causes production bugs, not just confusion.

Two practices prevent drift. First, treat the API Blueprint source file as a first-class artifact in your source control alongside the API code itself. When an endpoint changes, the doc change ships in the same pull request. Second, use version history to preserve old endpoint documentation rather than deleting it. Developers on older API versions need the reference for that version, not just the latest.

Apidoke stores per-project version history, so you can maintain a v1 snapshot alongside a v2 reference without duplicating effort in a separate hosting environment. The built-in CodeMirror editor with live preview also means you can see exactly how a change will render before you publish it, reducing the chance of a formatting error reaching a public URL.

Split-pane editor showing API Blueprint source on the left and rendered three-column reference preview on the right

A complete endpoint entry: putting it all together

Here is a full API Blueprint endpoint entry that applies every principle from this guide:

# Group Orders

## Order [/v1/orders/{order_id}]

+ Parameters
    + order_id: `ord_8c2e1a` (string, required) - UUID v4 identifier for the order.

### Get Order [GET]

Returns a single order by ID. Requires the `orders:read` scope.

**Authentication:** Bearer token in `Authorization` header.

+ Request
    + Headers

            Authorization: Bearer eyJhbGci...

+ Response 200 (application/json)
    + Attributes
        + order_id: `ord_8c2e1a` (string) - Unique order identifier.
        + status: `pending` (enum[string]) - Current order status.
            + Members
                + `pending`
                + `confirmed`
                + `shipped`
                + `cancelled`
        + customer_id: `cust_9f3a2b` (string) - Customer who placed the order.
        + created_at: `2026-04-12T14:33:00Z` (string) - ISO 8601 creation timestamp.
        + total_amount: 49.98 (number) - Order total in the account currency.
    + Body

            {
              "order_id": "ord_8c2e1a",
              "status": "pending",
              "customer_id": "cust_9f3a2b",
              "created_at": "2026-04-12T14:33:00Z",
              "total_amount": 49.98
            }

+ Response 401 (application/json)
    + Body

            {
              "error": {
                "code": "UNAUTHORIZED",
                "message": "Bearer token is missing or expired."
              }
            }

+ Response 403 (application/json)
    + Body

            {
              "error": {
                "code": "FORBIDDEN",
                "message": "Token lacks the 'orders:read' scope."
              }
            }

+ Response 404 (application/json)
    + Body

            {
              "error": {
                "code": "ORDER_NOT_FOUND",
                "message": "No order found with ID 'ord_8c2e1a'."
              }
            }

This single entry answers every question a developer has before writing a line of integration code: the URL, the credential, the response shape, and what goes wrong. That is the bar every entry in your reference documentation should clear.

For the step-by-step process of turning entries like this into a published interactive reference, see our tutorial on how to document a REST API step by step. For syntax details on every API Blueprint construct, the official API Blueprint specification is the definitive reference.

Frequently asked questions

What is the difference between API reference documentation and API documentation generally?

API documentation is the umbrella term covering all written material about an API: getting started guides, authentication tutorials, conceptual overviews, changelogs, and reference material. API reference documentation specifically means the endpoint-by-endpoint specification: methods, paths, parameters, request bodies, and response codes. It is the most precise, least narrative section of the broader documentation set.

How many response codes should I document per endpoint?

Document every status code your API actually returns for that endpoint, including all 4xx error codes and 500. At a minimum, this is the success code (200 or 201), 400 or 422 for bad input, 401 for missing credentials, and 404 for unknown resources. Omitting error codes forces developers to discover them in production.

Do I need to document optional parameters?

Yes. Mark them clearly as optional and include their default value. Optional parameters that are undocumented are effectively hidden features; developers cannot use them, and when behavior changes the absence of documentation makes the change invisible.

How do I keep API reference documentation in sync with the actual API?

The most reliable method is storing your API Blueprint source file in the same repository as your API code, so documentation changes are part of the same pull-request review as code changes. Apidoke's per-project version history means you can publish a new version of the docs alongside a new API version without overwriting historical references.

Can I write API reference documentation without knowing OpenAPI or Swagger?

Yes. API Blueprint is a Markdown-based format designed to be readable and writable without toolchain knowledge. You write plain Markdown with structured conventions for endpoints, parameters, and response bodies. Apidoke compiles and publishes it into an interactive three-column reference with no build step required.

Ready to write and publish your API reference documentation? Create a free Apidoke account and have your first interactive reference live in under an hour, no credit card required.

Related reading: How to Document GraphQL APIs (And Why It Differs from REST)