Markdown for API Documentation: Structure, Examples, and Best Practices
Markdown for API Documentation: Structure, Examples, and Best Practices
Markdown for API documentation has become the de facto standard across the software industry. GitHub READMEs, OpenAPI description fields, npm package pages, and developer portals all render markdown. When you write your API docs in markdown, you write once and publish everywhere. This guide covers the structure of well-written API docs, how to use code blocks effectively, and the patterns that make documentation actually useful to developers.
Quick Answer: Markdown API documentation uses fenced code blocks, parameter tables, and H2/H3 headings to organize endpoints, authentication, and error codes in a single readable file. Teams that write API docs in markdown alongside their code see 3x fewer doc-to-code drift issues because developers update documentation in the same pull request as the code change.
Why Did the Industry Choose Markdown for API Docs?
Before markdown became standard, API documentation lived in wikis, Word documents, or custom HTML pages. These formats had real problems.
HTML documentation required either a technical writer who knew HTML or a CMS that added complexity. Word documents could not be version-controlled alongside code. Wikis drifted out of sync with the actual API because updates required a separate workflow from code changes.
Markdown solved all three problems:
- Lives in the repository. A
README.mdor adocs/folder lives next to the code. When an endpoint changes, the developer can update the docs in the same pull request. - Renders everywhere. GitHub, GitLab, Bitbucket, npm, PyPI, and most developer portals render markdown automatically. No build step required for basic documentation.
- Readable as plain text. Even without rendering, a markdown API doc is scannable and readable in a terminal or a code editor.
For a broader look at how markdown fits into technical writing workflows, see the guide on technical documentation with markdown.
What Is the Right Structure for Good API Documentation?
Well-structured API docs follow a consistent pattern. Here is a complete structure for a REST API:
# My API
## Overview
Brief description of what the API does, who it is for, and
what problems it solves.
## Base URL
`https://api.myservice.com/v1`
## Authentication
## Endpoints
### GET /users
### POST /users
### GET /users/{id}
### PATCH /users/{id}
### DELETE /users/{id}
## Error Codes
## Rate Limiting
## Changelog
Each section serves a specific purpose. Developers scan to find what they need, so clear H2 and H3 headings are critical.
How Do You Write a Clear Overview Section?
The overview should answer three questions in plain language: what does this API do, who should use it, and what can be built with it. Keep it short. Most developers will skip this section entirely if they already know the product. Write it for the first-timer.
## Overview
The Payments API lets you charge customers, issue refunds, and retrieve
transaction history. It is designed for server-side use and supports
one-time charges and recurring subscriptions.
All requests are made over HTTPS. The API returns JSON responses for
all endpoints including errors.
How Do You Document Authentication?
Authentication is the first thing every developer tries to figure out. Put it early and make it concrete:
## Authentication
All requests require an `Authorization` header with a Bearer token.
```http
Authorization: Bearer your_api_key_here
API keys are generated in the developer dashboard.
Keys have three permission levels: read, write, and admin.
Never expose your API key in client-side code or public repositories.
## How Do You Document Individual Endpoints?
Each endpoint deserves its own H3 section. A good endpoint doc includes: the HTTP method and path, a short description, the request parameters or body, the response shape, and at least one code example.
```markdown
### POST /users
Create a new user account.
**Request Body**
| Parameter | Type | Required | Description |
|---|---|---|---|
| email | string | Yes | User's email address (must be unique) |
| name | string | Yes | Full display name |
| role | string | No | `user` or `admin`. Defaults to `user` |
| metadata | object | No | Arbitrary key-value pairs (max 10 keys) |
**Example Request**
```bash
curl -X POST https://api.myservice.com/v1/users \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"name": "Alice Johnson",
"role": "user"
}'
Example Response
{
"id": "usr_01HXYZ123",
"email": "alice@example.com",
"name": "Alice Johnson",
"role": "user",
"created_at": "2026-01-15T10:30:00Z"
}
Status Codes
| Status | Meaning |
|---|---|
| 201 | User created successfully |
| 400 | Invalid request body |
| 409 | Email address already in use |
| 422 | Validation error (see errors array in response) |
## How Do You Use Code Blocks Effectively in API Docs?
Code blocks are the most important element in API documentation. Every curl example, JSON payload, and code snippet should be in a fenced code block with a language specifier.
**Language specifiers** trigger syntax highlighting in most renderers:
- ` ```bash ` for curl commands and shell scripts
- ` ```json ` for request and response bodies
- ` ```http ` for raw HTTP request headers
- ` ```javascript ` for SDK examples in JS/Node.js
- ` ```python ` for Python SDK examples
- ` ```typescript ` for TypeScript SDK examples
Using the correct language identifier makes your examples dramatically easier to read. Compare:
Without language specifier (no highlighting):
curl -X GET https://api.myservice.com/v1/users
-H “Authorization: Bearer abc123”
With `bash` specifier (highlighted):
```bash
curl -X GET https://api.myservice.com/v1/users \
-H "Authorization: Bearer abc123"
The rendering difference matters especially for complex JSON payloads where developers need to scan for specific keys. According to developer experience research, API docs with syntax-highlighted code examples reduce integration time by an average of 2 hours compared to docs with plain, unhighlighted code blocks.
Parameters Tables
Markdown tables are ideal for documenting request parameters. A consistent column structure reduces cognitive load across every endpoint:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | No | 20 | Number of results per page (max 100) |
| offset | integer | No | 0 | Number of results to skip |
| sort | string | No | `created_at` | Field to sort by |
| order | string | No | `desc` | Sort direction: `asc` or `desc` |
| status | string | No | all | Filter by status: `active`, `inactive` |
For a deeper reference on markdown table syntax, including alignment options, see the markdown tables guide.
Linking Between Sections
Long API docs need internal navigation. Markdown heading IDs are generated automatically by most renderers, which means you can link to any section:
See the [Authentication section](#authentication) for details on
generating API keys.
Error handling is covered in the [Error Codes](#error-codes) section.
This is especially valuable in long single-page API references where developers need to jump between the endpoint definition and shared concepts like authentication or pagination.
Error Documentation
Every error your API can return should be documented. A table works well here:
## Error Codes
All errors follow a consistent JSON structure:
```json
{
"error": {
"code": "invalid_email",
"message": "The provided email address is not valid.",
"param": "email"
}
}
| Code | HTTP Status | Description |
|---|---|---|
unauthorized |
401 | Missing or invalid API key |
forbidden |
403 | API key does not have required permissions |
not_found |
404 | Resource does not exist |
invalid_email |
422 | Email format validation failed |
duplicate_email |
409 | Email already registered |
rate_limit_exceeded |
429 | Too many requests, see rate limiting |
server_error |
500 | Internal server error, retry after 30s |
## Versioning and Changelog
Document your API version at the top and maintain a changelog at the bottom. This lets developers understand what has changed when they upgrade SDK versions:
```markdown
## Changelog
### v2.3.0 (2026-01-15)
- Added `metadata` field to POST /users
- `GET /users` now supports filtering by `role` parameter
### v2.2.0 (2025-12-01)
- Rate limits increased to 1,000 requests per minute
- Deprecated `GET /users/search` (use `GET /users?q=` instead)
### v2.1.0 (2025-10-15)
- Added `PATCH /users/{id}` for partial updates
- Fixed: `DELETE /users/{id}` now returns 204 instead of 200
How Does OpenAPI Use Markdown?
OpenAPI (formerly Swagger) is the standard for machine-readable API specifications, but its YAML description fields render as markdown. Every description field in an OpenAPI spec is markdown text. This means the skills you use to write README docs apply directly inside your API spec:
paths:
/users:
post:
summary: Create a user
description: |
Creates a new user account. The email must be unique across all users.
**Permissions required:** `write` or `admin`
See [Authentication](#authentication) for details on API keys.
Good markdown in your OpenAPI descriptions improves the quality of the Swagger UI, Redoc, and any other tool that renders your spec.
Well-documented APIs are used more, integrated faster, and generate fewer support requests. Markdown gives you a lightweight, portable, and version-friendly format to write those docs without friction. edtr.md is a free browser-based markdown editor where you can draft, preview, and export your API documentation with no setup required.
Try it yourself
Open edtr.md and start writing Markdown with live preview, diagrams, math, and PDF export. Free, no sign-up.
Open editor