Skip to content
Crystal Desk

Workflows / Branching & Approvals

Branching & Approvals

Every connection between stages in a workflow template is actually one of three routing rules, evaluated when a stage instance completes.

The three routing events

  • on_submit — fires when a Task stage's assignee submits their completion form. Routing is unconditional: the ticket simply advances to whatever stage is connected next.
  • on_approve — fires when an Approval stage's assignee approves the work under review. Routes the ticket forward to the next stage in the approved path.
  • on_reject — fires when an Approval stage's assignee rejects the work, with a required rejection reason. Routes the ticket backward to the stage that produced the rejected work, rather than forward.

This is what makes branching possible: a single Approval stage can have two outgoing connections — one for on_approve, one for on_reject — sending the ticket down entirely different paths depending on the outcome.

Rework loops and iteration count

When on_reject sends a ticket back to an earlier stage, that stage doesn't start fresh — it starts a new iteration. Every field marked "revision enabled" (see Revisions & History) keeps its previous value stored, and the iteration count increments so everyone downstream can see this is v2, v3, and so on, not the original submission.

Worked example

Consider a Script stage feeding into a Review (Approval) stage:

  1. The writer submits a first draft — on_submit moves the ticket to Review, iteration 1.
  2. The reviewer rejects it with the reason "tone too formal for the brief" — on_reject routes the ticket back to Script.
  3. The writer sees the rejection reason and their original v1 draft side by side, submits a revised version — this becomes iteration 2 (v2), and on_submit routes back to Review.
  4. The reviewer approves v2 — on_approve moves the ticket forward to the next stage (Voice Over, in a typical radio ad template).

The writer, and anyone reviewing the ticket's history later, can see both v1 and v2, the rejection reason that connected them, and exactly when each happened — nothing about the rework is implicit or undocumented.

For how the completion form fields themselves are defined per stage, see Custom Fields.