Sequence & interaction
UML sequence diagrams CHECKED against the call stack they describe, not merely drawn. Every arrow is drawn where it was typed, so what makes an interaction wrong leaves almost nothing behind in the picture: a reply returned to the wrong participant moves one arrowhead one column and changes three of the figure's ninety-five elements, and a reader who sees a reply come back reads it as a reply coming back. A message to a destroyed lifeline and a deadlock leave nothing at all. This engine decides seventeen questions the drawing cannot show: a reply returned to a participant that never made the call, a message to a lifeline after its destruction cross, a call answered on only one branch of an `alt`, a cycle of calls none of which can be answered, two concurrent branches racing to address one service, two `alt` guards that both accept the same input, and a band of inputs no branch handles. Messages state whether they are a call, a reply or a fire-and-forget, because an arrowhead does not — and a document imported from a notation that leaves that unstated is reported as unchecked rather than analysed on a guess.

In the same space
Most users come to Sequence & interaction from PlantUML sequence, Mermaid sequenceDiagram, websequencediagrams.com, sequencediagram.org, Lucidchart (UML sequence), Visio (UML sequence) or Enterprise Architect (sequence). flowss runs this engine in the browser — no install, shareable via URL, exportable to PNG / SVG / PDF / source.
Syntax at a glance
sequence "Checkout"
actor Shopper
participant Web "Storefront"
participant Orders "Order service"
Shopper -> Web : place order
Web -> Orders : POST /orders
Orders reply Web : created
Web reply Shopper: confirmationPaste this in the Studio code pane to see Sequence & interaction render live. The full grammar is at the upstream-docs link above.
Sample templates
All 9 →The one to copy. A checkout that calls out to a card vault, posts to a ledger and notifies the storefront, with a payment saga created for the transaction and destroyed when it ends. Every call is answered by the participant that made it, on every branch; the `alt` covers its declared domain exactly with no overlap; the two `par` branches address different lifelines; the saga is used only between its create and its destroy. Reports clean, and every one of the seventeen checks says what it covered.
The same interaction with one word changed: the card vault answers the order service instead of the saga that called it. Fourteen arrows, fourteen rows, the same labels — one arrowhead lands one column further along. The saga is left blocked forever on an answer that went elsewhere, and the order service receives an answer to a call it never made. No runtime could produce this interaction, and no tool that draws what it is handed can tell you so.
A session is closed and then used. In every tool that draws lifelines the full height of the figure, the arrow lands on an ordinary dashed line and looks exactly like a message to a live object — which is why the defect survives review. Here the lifeline stops at the destruction cross, so the message visibly lands on nothing AND the panel says which line destroyed it. The second finding is its consequence: the call that message opened can never be answered.
Four ordinary arrows and two ordinary activation bars. Inventory calls pricing while pricing is mid-call to inventory, and neither call is ever answered — so each is waiting for a reply that cannot arrive until it replies first. The picture is a deadlock and it is indistinguishable from a working handshake. The engine also refuses the false positive next door: a callback that IS answered — one service calling back into another mid-call and getting a reply — is ordinary and this check says nothing about it.
Every branch of the `alt` has arrows in it, so every branch looks answered. One of them is not: on the retry path the service never replies to the client that called it, and the client waits forever. This is the check that most needs narrowing to be worth having — written as "the call was made outside the fragment and answered inside it" it fires on the commonest correct pattern in the notation, so it fires only when at least one branch fails to answer a call the fragment inherited.
The one check here that would cry wolf constantly if it were not gated, and the gate is the point. Free-text guards parse as ordinary values, so two prose branches look disjoint and exhaustive of nothing — which is why this check runs only on a fragment that declares what it is testing and over what domain. Given that declaration it becomes exact: two branches that both accept the same scores, and a band of scores no branch accepts at all. Both draw as a fragment with arrows in every branch.
sequence · ← Browse all engines · Quick-start guide