Runs and tests
The Test button at the top of the editor creates a run with a Test badge. The Activity section in the left rail contains that run and runs created by real triggers.
Test does not mean a disposable environment: the run and its steps remain in history, some lookups use real records, and Analyze with AI runs and consumes credits. Use an appropriate target and read the limitations below before interpreting the result.
Access and version
Section titled “Access and version”Test requires automations.write (edit Automations), but the automation may be off. Repeated tests are allowed and each one creates another run in history. Activity follows read access to the organization’s automations.
When you open Test automation:
- Current canvas is the default and runs the open graph, including unsaved changes;
- Live version appears after publication and runs that immutable version.
The backend validates the graph before creating the run. Covered errors close the dialog and highlight nodes on the canvas. Not every required action setting is validated; a test can still begin and fail on an empty or incomplete step.
Trigger and target
Section titled “Trigger and target”With more than one trigger, select Which trigger to simulate. The test starts on the branch leaving that node.
| Trigger | Requested target |
|---|---|
| Conversation event; No reply on conversation | conversation |
| Contact tag; Contact added to list; Audience | contact |
| Schedule | JSON object with simulated payload |
For Schedule, the example contains ISO scheduled_for and fired_at. Help still calls it a Webhook payload, although Webhook is not a current trigger. For Contact added to list, choosing a contact does not populate list_id, list_name or consent_source; test expressions that depend on those fields separately.
You may continue without a conversation or contact; steps requiring that context can fail. Search reads real organization records, not an isolated copy.
What the test does
Section titled “What the test does”Testing uses the same chaining engine. It executes immediately for up to about 20 seconds, or stops earlier on Wait, completion or failure. If it must continue later, the regular engine resumes the run from the queue.
| Step or effect | In a test |
|---|---|
| Send message | interpolates and records simulated: true and would_send; sends nothing |
| Send email | records simulated subject/list; creates no dispatch |
| Call webhook | records the simulated call; makes no request |
| Assign, tags, save to contact, hand off to agent and resolve conversation | computes output without changing the business record |
| Pick contact | looks up a real contact but does not correctly propagate it to later steps |
| Get the contact’s conversation | reuses an existing conversation; if none exists, only says it would create one |
| Condition | evaluates available context and chooses a branch |
| Wait | honors real duration and window; a long wait also delays the test |
| Analyze with AI | calls the model and consumes credits; may try up to three times |
| End automation | completes the run at that point |
The dialog says Get the contact’s conversation may open a real conversation. The current test runtime does not create one: it reuses an existing conversation or simulates creation without propagating it.
What simulation does not prove
Section titled “What simulation does not prove”Message and email return before outbound safeguards; email also returns before validating the module and sender. Webhook returns before final destination and network checks. A simulated test does not prove:
- opt-out, snooze, whose turn it is, or frequency cap;
- Meta window, approved template, and compatible inbox;
- email module, sender, or dispatch creation;
- webhook reachability, authentication, response, or SSRF blocking.
Validate these contracts in configuration and monitor a controlled real run.
Activity
Section titled “Activity”The list shows 25 runs per page, newest first, with When, Trigger, Status and Cost. There are no filters. While a row on the page is queued or running, the list checks for updates every five seconds.
Audience, No reply on conversation and Schedule use a parent run to discover occurrences and children to walk the graph. History can contain a parent row with no steps and rows for each contact, conversation or time.
Deleting an automation cascades to versions, runs and steps; turning it off preserves history.
Effective statuses
Section titled “Effective statuses”| Status | Current interpretation |
|---|---|
| Queued | next tick, continuation after the budget, or a Wait wake-up time |
| Running | claimed and processing a step |
| Waiting | exists in the UI, but the engine does not write it; waits appear as Queued |
| Completed | reached the end, encountered End, or met a Wait exit condition |
| Failed | a step/requirement failed; inspect error and output |
| Canceled | used for replaced/deactivated schedule or campaign parent runs, not Wait exits |
Cron runs once per minute and claims up to 50 eligible runs. A normal trigger can wait almost a minute; Test starts within its own request.
Path taken
Section titled “Path taken”Selecting a row opens the graph from the version used by the run, not today’s draft. Executed nodes receive state and the rest are dimmed; a Condition indicates the chosen branch.
Current limitations:
- a trigger creates no step, so its card and first edge remain dim even on the used branch;
- the list does not query
trigger_node_id; Entered through cannot distinguish two triggers of the same type; - Schedule and its children appear as No trigger.
Use graph and step sequence together; the first highlighted segment and trigger label are not complete evidence.
Timeline
Section titled “Timeline”Each item shows node, time, run attempt, status, Input, Output and error. Output is the best available record: AI JSON, branch, would_send, skipped or canceled_by.
Input is not the resolved value received by the step. The engine stores only { "config": ... }, the raw configuration. Final text/prompt, variables, headers and resolved body may not be recorded.
When a safeguard blocks a real send, the reason enters output.skipped, but the step remains Completed. The Skipped badge exists, but the current runner does not write that status.
skipped code | Meaning |
|---|---|
contact_opted_out | contact opted out of automated communication |
conversation_snoozed | conversation is snoozed |
customer_awaiting_reply | customer spoke last |
frequency_cap | aggregate 24-hour limit reached |
meta_window_closed | free text blocked with no usable fallback |
template_not_found | template not found |
template_no_inbox | compatible inbox not resolved |
template_wrong_inbox | template belongs to another WABA/inbox |
template_not_approved | template is not approved |
template_invalid | components or variables are invalid |
Once all visible steps close, the timeline stops updating. This happens on Wait and when the budget ends between steps. If the list moves from Queued to Completed but details stay stale, reload or select the run again.
A failure can show the explanation from the automation’s first open configuration alert below the technical error. It is not correlated with that run or node; verify code and step before acting.
Cost and diagnosis
Section titled “Cost and diagnosis”Cost sums credit_usage debits linked to steps. Today direct consumption comes from Analyze with AI. attempt N is the run attempt, not every internal model call. On invalid-JSON retry, the provider may charge up to three calls while the ledger may record only the first; with BYOK, compare against the provider.
- Distinguish a Test, parent run and real contact/conversation run.
- Read status and error; do not mistake a Queued wait for a stuck run.
- Open the historical version and locate the last step.
- Read Output first and treat Input as raw configuration.
- Look for
skipped,canceled_by,simulated,would_sendandbranch. - After a wait/continuation, reload to retrieve later steps.
- Verify safeguards, channel, Meta template, email and webhook outside simulation.
- Only then change the canvas and run another test; the old run stays tied to its version.