All posts
MermaidSequence DiagramsAPI Documentation

How to document REST APIs with Mermaid sequence diagrams

5 min readThe MermaidCreator team

API documentation usually comes in two flavors: a wall of prose that nobody reads, or an OpenAPI spec that's thorough but hard to scan. Mermaid sequence diagrams fill the gap — they show what happens across multiple services in the time it takes to read a single request/response table.

Why sequence diagrams for APIs?

A sequence diagram shows messages flowing between participants over time. For APIs, each participant maps naturally to a system boundary: client, API gateway, service, database, third-party. The vertical axis is implicit time, so readers immediately see what calls what, in what order, and what comes back.

Compare reading "the client sends a JWT in the Authorization header, the gateway verifies it, then forwards the request to the user service which queries the database" to this:

sequenceDiagram
    participant C as Client
    participant G as API Gateway
    participant S as User Service
    participant D as Database

    C->>G: GET /users/42 (JWT)
    G->>G: Verify token
    G->>S: GET /users/42
    S->>D: SELECT * FROM users WHERE id=42
    D-->>S: User row
    S-->>G: 200 OK { user }
    G-->>C: 200 OK { user }

The diagram says the same thing in less space and makes the system boundaries impossible to miss.

Sequence diagram syntax basics

Every sequence diagram starts with sequenceDiagram. Participants can be declared explicitly or inferred automatically from the first message that references them:

sequenceDiagram
    participant Frontend
    participant API
    participant Cache

Messages use arrows to show direction and type:

ArrowMeaning
->>Solid arrow (synchronous call)
-->>Dashed arrow (response / async)
-xSolid arrow with X (fire-and-forget)
-)Open arrow (async, non-blocking)

Give participants short aliases with participant DB as Database to keep the message body readable without sacrificing clear labels.

A practical example: JWT authentication

Here's a typical JWT login flow that most APIs share. The alt / else block handles branching without needing a separate diagram:

sequenceDiagram
    participant C as Client
    participant A as Auth Service
    participant R as Resource API
    participant DB as User DB

    C->>A: POST /auth/login { email, password }
    A->>DB: SELECT user WHERE email=?
    DB-->>A: User record + hashed password
    A->>A: bcrypt.compare(password, hash)
    alt Valid credentials
        A-->>C: 200 { access_token, refresh_token }
        C->>R: GET /profile (Bearer token)
        R->>A: Verify token
        A-->>R: { userId, roles }
        R-->>C: 200 { profile }
    else Invalid credentials
        A-->>C: 401 Unauthorized
    end

Useful annotations

Notes add context that doesn't belong on an arrow:

sequenceDiagram
    participant C as Client
    participant A as API

    Note over C,A: HTTPS required
    C->>A: POST /data { payload }
    Note right of A: Validate schema
    A-->>C: 201 Created

Activation bars show how long a participant is busy — useful for spotting where latency accumulates:

sequenceDiagram
    Client->>+Server: Request
    Server->>+DB: Query
    DB-->>-Server: Results
    Server-->>-Client: Response

The + and - suffix opens and closes the activation box on each participant.

loop blocks document polling or retry logic without repeating arrows:

sequenceDiagram
    Client->>Server: POST /export (start job)
    Server-->>Client: 202 Accepted { jobId }
    loop Every 2s until done
        Client->>Server: GET /export/status/{ jobId }
        Server-->>Client: { status: "processing" }
    end
    Client->>Server: GET /export/status/{ jobId }
    Server-->>Client: { status: "done", url: "..." }

Where to put your diagrams

Sequence diagrams earn their keep when they live close to the code:

  • In README files — a single auth flow diagram onboards new contributors faster than three paragraphs.
  • In API docs — alongside or in place of the Flows section in an OpenAPI document.
  • In ADRs — when a decision changed the call graph, show before and after side by side.
  • In PR descriptions — a short sequence diagram prevents "what does this actually do?" comments.

Because Mermaid is plain text, all of these work without exporting an image. GitHub renders fenced ```mermaid ``` blocks natively, and Notion, GitLab, and most modern wikis do too.

Tips for keeping diagrams useful

One flow per diagram. Use alt / else for the single most important branch; link to a second diagram for everything else. A diagram that shows every edge case teaches nothing.

Name participants by role, not by hostname. API Gateway ages better than kong-prod-01.

Show only the messages that matter. Health-check calls, logging, and internal retries are noise unless the diagram is specifically about those.

Update the diagram in the same PR as the code change. Nothing goes stale faster than documentation that lives two folders away from the thing it describes.

Sequence diagrams vs. OpenAPI specs

These tools are complementary, not competing. An OpenAPI spec is the authoritative contract for every request and response field. A sequence diagram is the map you read before you study the spec — the thing that makes the spec make sense. Teams that maintain both get oriented engineers faster and catch integration bugs earlier.

Draft a flow in the visual editor, copy the Mermaid source into your repository, and it travels with the code from there.

Sequence diagrams don't replace OpenAPI specs. They're the map you read before you study the spec — the thing that makes the spec make sense.

Related posts