Draw a sequence diagram
A type: sequence document draws the classic interaction diagram — participants across the top,
lifelines down, messages in call order — and then does what Mermaid can't: it plays the
conversation. Without a flow: block, the message order is the animation; a packet rides each
arrow, in order, on loop.
Participants and messages
Declare participants (columns, in order) and messages (rows, in order). Participants take the
same fields as architecture nodes — title, kind, icon, accent, subtitle — so a database
column can look like a database:
type: sequence
participants:
- { id: web, title: Web App, kind: user }
- { id: api, title: Orders API }
- { id: db, title: Postgres, kind: db }
messages:
- { from: web, to: api, label: POST /orders }
- { from: api, to: db, label: INSERT }
- { from: db, to: api, label: ok, reply: true }
- { from: api, to: web, label: 201 Created, reply: true }
A few things happened automatically there:
- Message colors came from the participants: each message tints itself with the accent of the
participant doing the work — the receiver of a call, the sender of a reply — so every
request/response pair shares one hue. An explicit
color:on a message wins. - Replies (
reply: true) render dashed with an open arrowhead and a quieter label, so request/response pairs read at a glance. - Activation bars grew on the receivers: a message starts a bar when a later reply from that
receiver back to the sender closes it. Nested request/reply pairs nest their bars. Set
activate: falseon a message to suppress its bar, oractivate: trueto force one without a matching reply. - The story dims and reveals. With the derived animation, everything starts faded; each message
row lights up as its packet fires, activation bars brighten while their participant works, and
the whole conversation fades back down before the loop restarts. A hand-written
flow:(oranimate: false) renders everything at full strength instead.
Self-messages and sections
A message from a participant to itself draws a small loop. A list entry of - section: <label>
opens a tinted, dashed band around every message until the next section (or the end) — use it to
chapter a long interaction. Give it an accent to color the band and its floating label
(- { section: Payment, accent: info }); each section also becomes a phase the animation can
seek to and lights up as its chapter begins:
type: sequence
participants:
- { id: web, title: Web App, kind: user }
- { id: api, title: Orders API }
- { id: pay, title: Payments, icon: lock, accent: info }
messages:
- { from: web, to: api, label: POST /orders }
- { from: api, to: api, label: validate cart }
- { section: Payment, accent: info }
- { from: api, to: pay, label: capture }
- { from: pay, to: api, label: captured, reply: true }
- { from: api, to: web, label: 201 Created, reply: true }
Async messages
kind: async renders dashed with an open arrowhead and gives the packet the slow, eased async
motion — right for fire-and-forget events and queue deliveries:
type: sequence
participants:
- { id: api, title: Orders API }
- { id: bus, title: Events, kind: queue }
- { id: mail, title: Mailer, icon: mail }
messages:
- { from: api, to: bus, label: OrderPlaced, kind: async }
- { from: bus, to: mail, label: deliver, kind: async }
- { from: mail, to: mail, label: render template }
Narrate the exchange
Because the derived animation plays the messages in order, a sequence narrates itself with almost no
effort: add a note: to any message and Beck shows it as a caption under the diagram just before
that message fires. Caption a few key steps to walk a reader through the conversation:
type: sequence
participants:
- { id: shopper, title: Shopper, kind: user }
- { id: api, title: Orders API }
- { id: pay, title: Payments, kind: external }
- { id: db, title: Postgres, kind: db }
messages:
- { from: shopper, to: api, label: POST /checkout, note: The shopper submits their cart to the Orders API. }
- { from: api, to: pay, label: capture, note: The API asks the payment service to capture the total. }
- { from: pay, to: api, label: captured, reply: true }
- { from: api, to: db, label: INSERT order, note: "With funds secured, the order is written to Postgres." }
- { from: db, to: api, label: ok, reply: true }
- { from: api, to: shopper, label: 201 Created, reply: true }
Notes only drive the derived flow — if you script a flow: yourself, narrate it with narrate
steps instead. Pace or disable the captions with meta.narrate. See Narrate the
story for the full picture.
Scripting the animation
The derived flow (one packet per message, in order) is usually what you want. To take over, add a
flow: block exactly as in any other Beck diagram — status, working, fail, and friends all
work on participants. See Animate the flow.
Full field tables: participants and messages in the YAML
schema. Generating one from C#:
SequenceDiagramBuilder.