BPMN 2.0 Elements
Priostack supports the BPMN 2.0 specification. This page is the complete reference for all supported elements, including their XML representation and usage notes.
Start Events
| Element | Symbol | Description |
| None Start Event | ○ | Process begins immediately when started via API. No trigger required. |
| Message Start Event | ✉○ | Process is triggered when a named message is received. Used for event-driven process starts. |
| Timer Start Event | ⏱○ | Process is triggered on a schedule (ISO 8601 duration, date, or cycle). Example: R/PT1H = every hour. |
| Signal Start Event | △○ | Process is triggered when a named signal is broadcast. Multiple processes can listen for the same signal. |
<!-- None Start Event -->
<startEvent id="start" name="Order Received" />
<!-- Timer Start Event (every day at midnight) -->
<startEvent id="dailyStart">
<timerEventDefinition>
<timeCycle xsi:type="tFormalExpression">R/P1D</timeCycle>
</timerEventDefinition>
</startEvent>
<!-- Message Start Event -->
<startEvent id="msgStart">
<messageEventDefinition messageRef="orderMessage" />
</startEvent>
End Events
| Element | Symbol | Description |
| None End Event | ● | Process path terminates normally. If all tokens reach end events, the instance completes. |
| Message End Event | ✉● | Sends a message to an external participant when the process path ends. |
| Error End Event | ✖● | Throws a named error that can be caught by a boundary error event on a calling process. |
| Terminate End Event | ⬛● | Immediately terminates all running paths in the current scope, not just the current token. |
<!-- Error End Event -->
<endEvent id="errorEnd">
<errorEventDefinition errorRef="paymentError" />
</endEvent>
<error id="paymentError" name="Payment Failed" errorCode="PAYMENT_FAILED" />
Tasks
| Element | Description |
| Service Task | Executed by an external worker. The engine creates a job; the worker activates and completes it. Required extension: zeebe:taskDefinition type="..." |
| User Task | Requires a human to complete via the Tasklist. Optional assignee, candidate groups, and due date via zeebe:userTask extension. |
| Script Task | Evaluates a FEEL expression inline without an external worker. Useful for simple data transformations. |
| Send Task | Sends a message to an external system or to a Message Catch Event in another process. |
| Receive Task | Waits for a message correlated by a message name and correlation key. |
| Call Activity | Invokes another process definition as a sub-process. Variables can be mapped in/out. |
<!-- Service Task -->
<serviceTask id="validateOrder" name="Validate Order">
<extensionElements>
<zeebe:taskDefinition type="validate-order" retries="3" />
<zeebe:ioMapping>
<zeebe:input source="=orderId" target="orderId" />
<zeebe:output source="=valid" target="orderValid" />
</zeebe:ioMapping>
</extensionElements>
</serviceTask>
<!-- User Task -->
<userTask id="reviewTask" name="Review Order">
<extensionElements>
<zeebe:userTask>
<zeebe:assignee>=reviewer</zeebe:assignee>
<zeebe:candidateGroups>managers</zeebe:candidateGroups>
</zeebe:userTask>
</extensionElements>
</userTask>
<!-- Call Activity -->
<callActivity id="callPayment" name="Process Payment">
<extensionElements>
<zeebe:calledElement processId="payment-process" />
<zeebe:ioMapping>
<zeebe:input source="=amount" target="amount" />
<zeebe:input source="=currency" target="currency" />
<zeebe:output source="=transactionId" target="paymentTransactionId" />
</zeebe:ioMapping>
</extensionElements>
</callActivity>
Gateways
| Element | Symbol | Description |
| Exclusive Gateway (XOR) | ✕ | Exactly one outgoing path is taken. Each sequence flow has a FEEL condition; the first true condition wins. A default flow handles the fallback case. |
| Parallel Gateway (AND) | + | All outgoing paths are activated simultaneously (split). When used as a join, waits for all incoming tokens before continuing. |
| Inclusive Gateway (OR) | ○ | One or more outgoing paths are taken based on FEEL conditions. The join waits for all activated paths. |
| Event-Based Gateway | ◇ | Waits for the first of several events (messages, timers, signals) to occur, then follows that path. |
<!-- Exclusive Gateway -->
<exclusiveGateway id="checkAmount" name="Amount OK?" />
<sequenceFlow sourceRef="checkAmount" targetRef="approve">
<conditionExpression>=amount <= 1000</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="checkAmount" targetRef="managerApproval">
<conditionExpression>=amount > 1000</conditionExpression>
</sequenceFlow>
<!-- Parallel Gateway (split) -->
<parallelGateway id="splitTasks" name="Run in Parallel" />
<!-- Event-Based Gateway -->
<eventBasedGateway id="waitForEvent" />
Intermediate Events
| Element | Description |
| Intermediate Timer Catch | Pauses execution for a duration or until a specific date/time. |
| Intermediate Message Catch | Waits for a correlated message before continuing. Requires a correlation key. |
| Intermediate Signal Catch | Waits for a named signal to be broadcast. |
| Intermediate Message Throw | Sends a message to another process or external system mid-flow. |
Boundary Events
Boundary events attach to tasks and trigger alternative paths when the attached event fires. They can be interrupting (cancel the task) or non-interrupting (run in parallel).
| Type | Description |
| Timer Boundary | Escalates if the task takes longer than the defined duration. |
| Error Boundary | Catches errors thrown by the task or its sub-process. Always interrupting. |
| Message Boundary | Catches a correlated message while the task is active. |
| Signal Boundary | Catches a broadcast signal while the task is active. |
<!-- Timer Boundary Event (escalate after 1 hour) -->
<boundaryEvent id="timeout" attachedToRef="reviewTask" cancelActivity="true">
<timerEventDefinition>
<timeDuration xsi:type="tFormalExpression">PT1H</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<sequenceFlow sourceRef="timeout" targetRef="escalate" />
<!-- Error Boundary Event -->
<boundaryEvent id="paymentFailed" attachedToRef="processPayment">
<errorEventDefinition errorRef="paymentError" />
</boundaryEvent>
Subprocess
A subprocess is an embedded process within the parent process. It groups tasks and has its own scope for variables and boundary events.
<subProcess id="fulfillmentSubProcess" name="Fulfillment">
<startEvent id="subStart" />
<serviceTask id="pickItems" name="Pick Items">
<extensionElements>
<zeebe:taskDefinition type="pick-items" />
</extensionElements>
</serviceTask>
<serviceTask id="packItems" name="Pack Items">
<extensionElements>
<zeebe:taskDefinition type="pack-items" />
</extensionElements>
</serviceTask>
<endEvent id="subEnd" />
<sequenceFlow sourceRef="subStart" targetRef="pickItems" />
<sequenceFlow sourceRef="pickItems" targetRef="packItems" />
<sequenceFlow sourceRef="packItems" targetRef="subEnd" />
</subProcess>
Lanes
Lanes visually partition a pool to represent different participants, roles, or systems. They have no execution semantics — they are for modeling clarity only.
<laneSet id="laneSet1">
<lane id="customerLane" name="Customer">
<flowNodeRef>start</flowNodeRef>
<flowNodeRef>submitOrder</flowNodeRef>
</lane>
<lane id="systemLane" name="System">
<flowNodeRef>validateOrder</flowNodeRef>
<flowNodeRef>processPayment</flowNodeRef>
<flowNodeRef>end</flowNodeRef>
</lane>
</laneSet>
Tip: Use the
Priostack Designer to visually build BPMN diagrams. The designer uses bpmn-js and generates valid BPMN 2.0 XML that can be deployed directly via the API.