A timeout tells the caller that it did not receive a response in time. It does not tell the caller whether the server completed the operation. That distinction matters when an API creates a resource: drawing “timeout → create again” can hide the risk of duplicate work.

This tutorial models an illustrative report-generation API. It is a documentation exercise, not a production implementation or evidence of how a particular service behaves. The goal is to make the retry policy and its assumptions visible to a reviewer.

Write the contract before drawing the arrows

Assume the client sends a request key with a report creation request. The API stores a result associated with that key. A retry with the same key and payload returns the stored result instead of creating another report. This example shows one retry after a lost response, followed by a separate lookup if the client still cannot confirm the result.

That contract is a design assumption. A real service must define key scope, retention, concurrent requests, and what happens when the same key arrives with a different payload. The diagram cannot supply those guarantees on its own.

Show the ambiguous result explicitly

Reusable example
Download .mmd

Rendering diagram…

View Mermaid source
sequenceDiagram
    autonumber
    participant C as Client
    participant A as Reports API
    participant R as Result store
    C->>A: Create report, key K
    A->>R: Save report result under K
    R-->>A: Result recorded
    Note over C,A: Response is lost, client reaches its timeout
    C->>A: Retry same request with key K
    A->>R: Look up result for K
    R-->>A: Existing report result
    alt Retry response arrives
        A-->>C: Return existing report ID
    else Retry also times out
        Note over C: Stop automatic retries, outcome is unknown
        C->>A: Query status for key K
        A-->>C: Report ID or pending status
    end
Copy the source, then paste, edit and export in the workspace.Open editor →

The first note matters more than another arrow labeled “error.” It says that the result was recorded but the client did not see the response. The second request therefore asks the API to resolve the same logical operation, using the same key.

The diagram uses alt for alternative outcomes and a note for the missing response. See the Mermaid sequence reference for these constructs. Arrow appearance is a drawing convention; the labels carry the protocol meaning.

Review what the diagram leaves out

This is a deliberately simplified successful lookup path. The lookup can also fail, the key can expire, and a server can crash between creating a report and storing the result. Add those cases if they are part of the decision under review. In particular, an implementation that stores the key only after performing the side effect may still duplicate work during a race or crash.

Review questionWhy it changes the picture
Is the request safe to repeat?Some operations need deduplication or another recovery method
Who chooses the key?A new key on every retry can represent a new operation
When is the result recorded?A gap between the side effect and the record can permit duplicates
How many retries are allowed?An unbounded loop conceals the stopping condition
How does the user see an unknown outcome?“Failed” can be misleading when work may have completed

Avoid putting a precise timeout or backoff duration into the example unless it comes from the service contract. A guessed number looks like an agreed operational requirement once it enters a design document.

Adapt the example without losing its meaning

Rename the participants first. Then replace “Create report” with the operation you are documenting, and decide whether the assumed key-based behavior actually exists. If it does not, remove the stored-result guarantee and show the recovery action the service really supports.

Keep the normal response and the unknown outcome distinct. If your application shows “Check status” after a timeout, include that state in the accompanying UI description. Do not promise that the diagram's status query will always succeed; the example assumes it succeeds so that the main ambiguity remains easy to follow.

Copy the example into the workspace, change one part of the contract, and ask a reviewer to trace the lost-response branch. If they can say whether another resource is created and what the client does next, the diagram answers its central question. For more syntax, see the sequence diagram guide.