Workflow Builder
The Workflow Builder turns a business rule into automation. A workflow watches one entity type (invoices, purchase orders, leave requests, deals, and so on), waits for a trigger event, checks a set of conditions, and then runs actions — which can include routing the record through an approval chain.

Before you begin
- Confirm the relevant feature toggles are enabled in Workflow → Settings (e.g.
require_po_approval,multi_level_approval,parallel_approval). - Decide whether the “does this need approval” decision belongs in a Policy (a numeric threshold) rather than in the workflow itself. Keep workflows focused on who and what.
Create a workflow
Step 1 — Choose the entity
Go to Workflow → Workflows and click New Workflow. Pick the entity type the workflow applies to (for example Purchase Order, Invoice, Leave Request, Deal). Every workflow is scoped to exactly one entity — its conditions and fields come from that entity.
Step 2 — Pick the trigger
Select the event that starts the workflow:
| Trigger | Fires when… | Typical use |
|---|---|---|
| On create | A new record is saved | Route every new PO for approval |
| On update | Any field on the record changes | Re-check when an invoice amount is edited |
| On status change | The record’s status/state moves (e.g. draft → submitted) | Start approval only after the user submits |
Prefer On status change for approval flows — it avoids firing while the user is still drafting the record.
Step 3 — Add conditions (JSONLogic)
Add one or more conditions that must all be true for the workflow to act. Conditions are evaluated with JSONLogic against the record’s fields. Use the visual condition builder, or edit the JSONLogic directly.
Example — only for large, non-VN purchase orders:
{ "and": [
{ ">": [ { "var": "totalAmount" }, 50000000 ] },
{ "!=": [ { "var": "supplierCountry" }, "VN" ] }
] }See the operators reference below.
Step 4 — Define actions
Choose what happens when the trigger fires and the conditions pass:
| Action | What it does |
|---|---|
| Create approval | Starts an approval chain (see Step 5) |
| Auto-submit | Moves the record into the submitted/pending state automatically |
| Auto-execute | Runs the record’s next lifecycle step automatically (e.g. post, confirm) |
| Assign | Assigns the record to a user or role |
| Notify | Sends an in-app / email notification to users or roles |
| Set field | Writes a value to a field on the record |
A workflow can run several actions in one pass — e.g. set a field, notify the requester, and create an approval.
Step 5 — Build the approval chain
If you added Create approval, define its levels. Each level can be serial or parallel:
- Serial (A → B → C): level 2 only starts after level 1 approves. Use for escalation ladders (Manager → Finance → CFO).
- Parallel (A AND B): all approvers at the level must approve before the chain advances. Use for dual control or cross-department sign-off.
You can mix them: run levels 1 and 2 in parallel, then require a final serial level 3.
Multi-level chains require the multi_level_approval toggle; parallel levels require parallel_approval. Without them, only a single-approver step is honoured.

Step 6 — Test
Use Test (or run a sample record from the source module) to confirm the workflow triggers, its conditions match, and the chain routes to the intended approvers — without affecting production records.
Step 7 — Activate
Toggle the workflow Active. It now runs on every matching event. Inactive workflows are saved but never fire.
Conditions operators reference
JSONLogic operators available in the condition builder:
| Operator | Meaning | Example |
|---|---|---|
== / === | Equals | status equals submitted |
!= / !== | Not equals | department not IT |
> >= < <= | Numeric comparison | amount > 50,000,000 |
in | Value is in a list | category in ["capex","opex"] |
and | All sub-conditions true | amount high AND new supplier |
or | Any sub-condition true | overdue OR flagged |
! | Negation | NOT approved |
var | Reference a record field | { "var": "totalAmount" } |
Field names in var are the entity’s stored field keys (usually camelCase, e.g. totalAmount, discountPercent, supplierId). The visual builder lists valid fields for the chosen entity so you don’t have to guess.
Trigger types reference
| Trigger | Scope | Notes |
|---|---|---|
| On create | New records only | Fires once, at insert |
| On update | Field changes | Can fire repeatedly; scope with conditions to avoid loops |
| On status change | State transitions | Best for approval kick-off; pairs with an entity’s lifecycle |
Actions reference
| Action | Blocking? | Common pairing |
|---|---|---|
| Create approval | Yes — holds the record until decided | Notify approvers |
| Auto-submit | No | On create trigger |
| Auto-execute | No | After final approval |
| Assign | No | Notify assignee |
| Notify | No | Any step |
| Set field | No | Stamp risk level / route code |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Workflow never fires | Wrong trigger, or workflow inactive | Confirm trigger matches the real event; set Active |
| Fires but doesn’t route to approver | Conditions never match | Test conditions against a real record’s field values |
| Only one approver acts despite multi-level | multi_level_approval off | Enable in Workflow → Settings |
| Parallel level acts serially | parallel_approval off | Enable the toggle |
| Loops on every save | Broad On update trigger | Add a condition that stops re-firing (e.g. status guard) |
| Approver on leave, chain stalls | No delegation | Create a Delegation rule |
FAQ
Q: Can one workflow cover several entities? A: No. Each workflow is scoped to one entity. Create separate workflows (or start from a template) per entity.
Q: Where do the field names in conditions come from? A: They are the entity’s stored fields. The visual builder lists them for the entity you chose in Step 1.
Q: How do I stop an approval flow I no longer want? A: Toggle the workflow Inactive. In-flight approvals continue; no new ones start.