You've just edited a Flow. Before it touches real users you want to know it does what you intended. This page walks every step from "I just made a change" to "the live tenant is running the new definition."
- You have saved at least one change to a Flow in the Flows editor.
- You have access to a scratch user or a non-production tenant you can sign in as.
Three ways to test a Flow
Section titled “Three ways to test a Flow”The three options trade convenience for fidelity. Start with the Test pane to spot block-level mistakes quickly, then graduate to a full end-to-end sign-in when you're ready to confirm real-world behaviour.
1. The in-editor Test pane
Section titled “1. The in-editor Test pane”Every block in the Flows editor has a Test tab in its configuration panel. Open the panel, switch to the Test tab, fill in the inputs the block expects, and hit Run. The pane shows you what that block would output — the state keys it would write, the branch it would take, any error it would surface.
The Test pane is the fastest feedback loop. It's ideal for checking whether a webhook block reaches your endpoint, whether a Decision block evaluates your condition correctly, and whether an Action writes the keys you expect. For a deeper walkthrough of testing individual Actions, see Testing custom actions.
The engine does not have a dry-run flag. If your Flow contains a terminal block — such as Issue Session or Create User — and it is reached during a Test pane run or a :simulate call, that block executes for real. A test sign-in creates a real session; a test registration creates a real user. Always test against a scratch account on a non-production tenant, not against a real user on your live tenant.
2. The :simulate endpoint
Section titled “2. The :simulate endpoint”For scripted or CI-driven testing, send a request directly to the simulate endpoint:
curl -s -X POST \ https://<tenant>-<org>.intelliauth.local/api/v1/pipelines/by-flow-type/login:simulate \ -H "Authorization: Bearer <admin-token>" \ -H "Content-Type: application/json" \ -d '{ "event": { "identifier": "alice@cymmetri.io" }, "step": "post_auth" }'{ "terminal_block_id": "issue-session", "state": { "event.user.id": "usr_01ABCDE...", "step.risk-evaluate.score": 12, "step.decision.branch": "allow" }, "duration_ms": 47, "error": null}The response tells you which terminal block was reached, the full state map at the end of the run, how long execution took, and any error the engine surfaced. You can snapshot this output in a CI job and diff it against a known-good baseline whenever the Flow definition changes.
The same persistence caveat applies here: terminal blocks run for real. Keep your test identifier pointed at a scratch user.
3. End-to-end on the live tenant
Section titled “3. End-to-end on the live tenant”The highest-fidelity test is simply signing in as a real (or scratch) user through the tenant's login page. You'll see exactly what the Flow does — the MFA prompt, the redirect, the token claims — because it is the real path. Use a non-production tenant or a dedicated test account so that any side effects (sessions created, webhooks fired, accounts tagged) don't affect real users.
After the sign-in completes, check the Recent runs panel on the Flow detail page. It shows a per-block trace of the run you just triggered: each block's inputs, outputs, branch taken, and duration. Any block that errored shows the error message inline.
Publishing — what "save" means
Section titled “Publishing — what "save" means”The platform has no separate publish button for Flows. When you hit Save in the editor, the new Flow definition is live. New authentication attempts pick it up immediately.
This is intentional: most Flow changes are safety improvements or policy corrections, and the sooner they take effect the better. It does mean you should test before saving, not after.
System Flows (Login, Registration, Password Reset, and the rest) publish immediately on save. If you are building a custom Flow — one you'll attach to a specific application or trigger — you can save it and test it in isolation before attaching it. The attachment is the publish action for custom Flows.
What rolls live and what doesn't
Section titled “What rolls live and what doesn't”When you save a Flow, three things happen in order:
- The new Flow definition is stored and becomes the active version.
- Any sign-in that starts from this point picks up the new definition.
- Sign-ins that are already in progress — users who are mid-flow with a stage token in their browser — continue on the definition they started with.
The platform pins the Flow version into the stage token at the start of each run. An in-flight session won't be interrupted by your change. Practically, this means you may see a brief overlap: a few users finishing on the old definition while new users start on the new one. That window closes within a few minutes as in-flight sessions complete.
Verifying it worked
Section titled “Verifying it worked”Three signals tell you the new Flow is doing what you intended:
- Recent runs panel — on the Flow detail page (Flows -> pick a flow), the panel updates in near-real-time as runs complete. Each entry shows the blocks that fired, their outputs, and any errors.
- Audit log — every completed Flow run writes a
flow.run_completedevent to the audit log. Open Settings -> Audit log, filter byflow.run_completed, and confirm the right Flow ID and outcome appear. See Audit log overview for filter and export options. - Your own application — sign in through the actual login page, decode the access token, and verify the claims, scopes, or redirect behaviour look right. This is the ground truth.
Rolling back
Section titled “Rolling back”There is no built-in version history for Flows in this release. If you need to revert a change, re-open the editor, restore the prior definition by hand, and save. The new save becomes live immediately, and you're back to the previous behaviour.
Because there's no automatic rollback, keep your Flow definitions in a version-control repository of your own — paste the JSON export into a Git repo, commit before each edit, and you'll have a clean diff and a safe restore point at all times. A built-in version history is on the roadmap.