Document an API with Mermaid: Sequence Diagrams, Failure Paths and Real HTTP Tests
An API diagram often looks complete until something fails. It shows a browser calling an endpoint and a database returning data, but leaves out the expired session, invalid request, rate limit or timeout. Those missing paths are often exactly what the next developer needs to understand.
A Mermaid sequence diagram gives each participant a column and each message a place in time. The source is plain text, which means you can review it beside code and update it without dragging boxes around. The free Web2Generators Mermaid live editor lets you paste the examples below, inspect a live preview and download the source or a PNG. Its introduction to the Mermaid editor explains the available diagram families and the importance of saving your source before leaving.
This tutorial builds a useful diagram for a protected API endpoint, then turns it into a small, repeatable testing plan. The example URLs and credentials are fictional. Test only systems you own or are authorized to examine.
First, define the question the diagram must answer
Suppose a browser fetches the current user’s saved projects from GET /api/projects. The API checks the session, fetches records, and returns JSON. In a technical review, you probably want answers to five questions:
- Which component receives the request first?
- Where does authentication happen?
- Which conditions return an error instead of project data?
- Does the browser ever retry the operation?
- Which observations would prove that the implementation matches the drawing?
You do not need to show every framework middleware or database query. A diagram of user-visible outcomes can stay short, even when the implementation is complex. Start with the browser, API and database, and add a proxy or cache only when its behavior matters to the particular question.
Step 1: Create the successful request flow
Paste this into the Mermaid editor, without the surrounding Markdown code fences:
sequenceDiagram
autonumber
participant Browser
participant API
participant DB as Database
Browser->>API: GET /api/projects
API->>API: Validate session
API->>DB: Query projects for user
DB-->>API: Project rows
API-->>Browser: 200 OK, JSON array
participant creates the vertical lanes. A solid arrow represents a message sent to another component; a dashed arrow is commonly used for a reply. autonumber adds steps that are handy when referring to a particular exchange during code review.
The database query should be scoped to the authenticated user on the server. Merely placing “Validate session” in a diagram does not make that check exist in the application. A diagram describes intended behavior; it is not a security test.
This first version is useful, but it makes one silent promise: every request has a valid session and every database operation succeeds. Real users do not live inside that promise.
Step 2: Add alternative outcomes with alt and else
Mermaid’s alt block is designed for conditional branches. Expand the diagram to show an unauthorized response, a database failure and the normal result:
sequenceDiagram
autonumber
participant Browser
participant API
participant DB as Database
Browser->>API: GET /api/projects
API->>API: Validate session
alt Session missing or expired
API-->>Browser: 401 Unauthorized
else Valid session
API->>DB: Query projects for user
alt Database unavailable
DB-->>API: Connection error
API-->>Browser: 503 Service Unavailable
else Query succeeds
DB-->>API: Project rows
API-->>Browser: 200 OK, JSON array
end
end
The nested branch makes the failure location explicit. A 401 means the client has not supplied valid authentication credentials for this resource. A 503 indicates that the service is temporarily unable to handle the request; whether it also supplies a Retry-After header is a separate API design decision. Do not label a database error 401 simply because the application cannot complete the operation.
Notice what the drawing deliberately omits. It does not show a password or session cookie value, and it does not assume a retry always happens. Document the protocol behavior your application actually implements, not the behavior you hope it implements later.
Step 3: Diagram CORS separately when it affects the request
If your frontend and API use different origins, the browser may send an OPTIONS preflight before a cross-origin request. A simple authenticated GET using cookies does not automatically require a preflight, whereas a request with a non-safelisted Authorization header often does.
A focused preflight diagram might be:
sequenceDiagram
participant Browser
participant Gateway
participant API
Browser->>Gateway: OPTIONS /api/projects
Note over Browser,Gateway: Origin and requested method/headers
alt Preflight denied
Gateway-->>Browser: Response without required CORS permission
Note over Browser: Browser stops before the actual request
else Preflight approved
Gateway-->>Browser: 204 with required CORS headers
Browser->>Gateway: GET /api/projects with Authorization
Gateway->>API: Forward GET
API-->>Gateway: Application response
Gateway-->>Browser: Response with appropriate CORS headers
end
This is a conceptual example, not a guarantee of a particular browser’s caching or gateway behavior. The actual response also needs correct CORS headers if JavaScript is to read it. See CORS Preflight Failures Explained for the browser permission rules, why OPTIONS is different from an API login check, and how to troubleshoot a failing exchange.
A useful documentation pattern is to keep authentication and CORS on separate diagrams unless you are explaining a bug involving both. One picture with every possible browser and server branch quickly becomes unreadable.
Step 4: Use a state diagram when transitions matter more than messages
Sequence diagrams show who speaks to whom. State diagrams answer a different question: what state can an operation occupy, and which event moves it forward?
For an asynchronous report export, for example:
stateDiagram-v2
[*] --> Queued: Submit job
Queued --> Running: Worker starts
Running --> Ready: Export succeeds
Running --> Failed: Export fails
Queued --> Cancelled: Cancel accepted
Ready --> [*]
Failed --> [*]
Cancelled --> [*]
This drawing is much more useful for deciding whether a Cancel button should still appear after a job starts. It also makes unanswered design questions visible: can a failed export be retried, and does the retry create a new job? If the answer is yes, add an explicit transition instead of relying on a note outside the model.
The Mermaid editor’s guide includes flowcharts, state diagrams, entity relationships and Gantt examples when a sequence diagram is not the best fit.
Step 5: Turn arrows into test cases
A well-maintained diagram should lead to tests, not substitute for them. For the protected projects endpoint, create a small outcome matrix:
| Path in the diagram | Test condition | Expected observation |
|---|---|---|
| Valid session | Use an authorized staging test account | 200 and the documented JSON shape |
| Missing session | Omit the test credential | 401, without private data |
| Invalid method | Send an unsupported method | The documented method error, often 405 |
| Database unavailable | Use a controlled staging fault injection | The specified error response, without stack traces |
| Temporary service error | Trigger a sanctioned staging scenario | Predictable client error handling |
You can prepare harmless requests with the Web2Generators cURL command line builder. It builds the command locally; it does not send the request. Run the command in your terminal and compare the response with the drawing.
For example, a request without credentials might be:
curl --include --request GET \
--url 'https://staging.example.com/api/projects' \
--header 'Accept: application/json'
For a staging-only bearer token, use an environment variable rather than writing a real token into your documentation:
curl --include --request GET \
--url 'https://staging.example.com/api/projects' \
--header 'Accept: application/json' \
--header "Authorization: Bearer $TEST_API_TOKEN"
Shell environments vary; the second example assumes a POSIX-style shell and a correctly defined environment variable. If an API expects a JSON request body, the guide JSON vs Form Data vs Multipart explains why request format and headers matter. If the URL contains repeated or encoded query parameters, use the URL encoder and query editor to inspect them before creating a test.
What cURL proves, and what it does not
A cURL response proves what that request received at that moment. It does not prove that browser CORS rules permit JavaScript to read the response, that every authenticated role is handled correctly, or that the server has no other vulnerabilities. For browser-specific behavior, compare the real flow in DevTools. The Web2Generators browser Network inspection guide explains how to capture the relevant requests.
Step 6: Keep diagrams safe and accessible
Mermaid source is readable text. That is convenient for reviews, but it also means anything pasted into the diagram can end up in a repository, PNG or shared document. Use placeholder domains, generic user names and descriptive labels rather than real credentials, access tokens, customer records or internal hostnames.
When sharing diagrams, add a brief written summary of the important branches. Do not depend on red and green colors alone to communicate success and failure. Prefer a narrow diagram with readable labels over a wide screenshot whose text becomes tiny on mobile. The Mermaid editor can download PNG and source files; retain the source alongside your documentation so the next change remains editable.
A helpful review checklist is short:
- Does each message point to the component that actually owns it?
- Are unauthorized, invalid and temporarily unavailable outcomes distinguishable?
- Are retry and cancellation rules explicit rather than implied?
- Do the HTTP methods, URLs and status codes match tests and API documentation?
- Can someone understand the most important outcome without relying on color?
- Does the diagram omit secrets and private infrastructure details?
Make the diagram part of the change
Store the Mermaid source beside the endpoint’s specification or README. When a developer changes an authentication rule or response code, update the diagram in the same review. For complex systems, split a high-level architecture view from focused diagrams for login, data retrieval and recovery paths.
The goal is not to draw a perfect system. It is to make the next debugging session less dependent on assumptions. Try mapping one real endpoint in the Web2Generators Mermaid live editor, then use the cURL builder to verify one success case and one failure case before sharing it with your team.