Sequence diagrams

A sequence_diagram draws a runtime interaction coordinate-free: participants rank left-to-right and messages top-to-bottom in declaration order, lifelines extend past the last message, and the height follows the content (only width is declared). It is a page-level block — not a diagram shape.

customer checkout sequenceCustomerWeb AppAPI ApplicationStripeSubmit payment formPOST /ordersCapture chargecharge idpersist order201 CreatedRetries reuse the idempotency key.
sequence_diagram {
  width = 720

  participant "customer" { name = "Customer"        kind = :actor }
  participant "web"      { name = "Web App" }
  participant "api"      { name = "API Application" }
  participant "stripe"   { name = "Stripe"          kind = :external }

  message "m1" { from = "customer" to = "web"    text = "Submit payment form" }
  message "m2" { from = "web"      to = "api"    text = "POST /orders" }
  message "m3" { from = "api"      to = "stripe" text = "Capture charge" }
  message "m4" { from = "stripe"   to = "api"    text = "charge id"  kind = :reply }
  message "m5" { from = "api"      to = "api"    text = "persist order" }
  message "m6" { from = "api"      to = "web"    text = "201 Created" kind = :reply }
  note    "n1" { at = "m3"  text = "Retries reuse the idempotency key." }
}

Blocks

sequence_diagram

PropertyTypeRequiredDescription
widthf64noRendered width in pixels; the height follows the content.
col_widthf64noHorizontal distance between participant lifelines.
row_heightf64noVertical distance between message rows.
header_heightf64noY of the first message row (below the participant heads).
ididentifiernoOptional explicit HTML id.
classlist<utf8>noOptional style classes on the <svg>.
descutf8noAccessible description (aria-label + <title>).

Child blocks

SlotAcceptsMultipleDescription
participantsparticipantyesParticipants, left-to-right in declaration order.
messagesmessageyesMessages, top-to-bottom in declaration order.
notesnoteyesMargin notes anchored to messages.

participant

Column order is declaration order. kind picks the head: :box (default), :actor (stick figure), :external (dashed box). link makes the head a clickable in-site link, resolved like a prose link.

PropertyTypeRequiredDescription
idutf8yesStable id messages reference via from / to. Column order is declaration order.
nameutf8noDisplay name shown in the head (defaults to the id).
kindParticipantKindnoHead style: :box (default) / :actor / :external.
linkutf8noLink the head to an in-site page (bare page name, or site:page).
classlist<utf8>noStyle classes for the head shapes (replaces the theme defaults).

message

Row order is declaration order. kind picks the arrow: :sync (solid line, filled head — the default), :async (solid, open head), :reply (dashed, open head). The same from and to renders the standard self-message loop.

PropertyTypeRequiredDescription
idutf8yesStable id (notes reference it via at). Row order is declaration order.
fromutf8yesSending participant id.
toutf8yesReceiving participant id (same as from for a self-message loop).
textutf8noArrow label.
kindMessageKindnoArrow style: :sync (default) / :async / :reply.

note

A margin annotation, drawn right of the last lifeline at the row of the message named by at.

PropertyTypeRequiredDescription
idutf8yesStable id.
atutf8yesId of the message this note is anchored beside.
textutf8yesThe note text.

Data-driven sequences

Like every @children slot, the child lists accept computed splices — so a repeated scenario model can generate its figure:

sequence_diagram {
  participants = map(actors, fn(a: Actor) -> Participant { { id: a.key, name: a.label } })
  messages = map(steps, fn(s: FlowStep) -> Message {
    { id: s.key, from: s.from, to: s.to, text: s.action }
  })
}