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, Analyze with AI runs and consumes credits, and Call webhook makes the request for real. 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; Command | 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; Send campaign | records simulated subject and destination; creates no dispatch |
| Add private note | shows the text that would be written; does not write the note |
| Call webhook | makes the real request to the configured destination; the dialog warns before starting |
| 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, and each attempt becomes a billed step |
| 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. 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.
The webhook, by contrast, goes through the same destination guard and network as a real run; to test only that step, without running the flow, use Test call in its panel. See Actions.
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 or encountered End |
| Failed | a step/requirement failed; inspect error and output |
| Canceled | a Wait exit condition was recognized, No reply on conversation stopped qualifying before the first step, or a schedule/campaign parent run was replaced or deactivated |
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;
- in No reply on conversation, the check before the first step records the trigger as a step: Skipped when the conversation stopped qualifying.
Entered through shows the trigger type and the node identifier, such as n1, which distinguishes two triggers of the same type. Schedule and Command runs still appear in Activity as No trigger, even though the automations list shows those triggers by name; use the node identifier to confirm the entry point.
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. Today the Skipped badge appears only on the revalidated No reply on conversation trigger described above.
If the contact record cannot be read before a send, the step fails instead of skipping: without confirming the opt-out status, nothing is sent.
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. When the model returns invalid JSON, each new attempt appears as another step of the same node — the failed attempt shows as Failed, with node_attempt in Output — and each one is billed; Cost adds them all up. The attempt N label is still the run attempt, not the node attempt.
- 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.