Workflows are steps that run outside the conversation:
- A Pre-call workflow runs before the agent is dispatched. Its outputs become dynamic variables the prompt can use, for example a CRM lookup that fills
{{customer_name}}and{{tier}}. - A Post-call workflow runs after post-call analysis. It can push results to other systems or text the caller a follow-up.
Find them under Workflows in the agent's settings panel. Each agent has one of each.
Step types#
| Type | Label | What it does |
|---|---|---|
http |
HTTP request | Sends GET, POST, PUT or PATCH to a URL. The body is a template; when empty, all variables are sent as JSON. |
set_variables |
Set variables | Sets variables from templates, for example greeting = Hi {{first_name}}. |
code |
Run code | Runs JavaScript in a sandbox. args holds the step's Arguments and dv the variables so far. Return an object. |
integration_app |
Integration app | Runs an action of a connected integration app. See Integrations. |
send_sms |
Send SMS | Post-call only. Texts Message to the caller, or to the number in the recipient field. |
A workflow holds up to 20 steps.
Step settings#
| Setting | Field | Notes |
|---|---|---|
| Step id | id |
Letters, numbers, - and _, up to 40 characters. Unique in the workflow. |
| Step name | name |
Up to 80 characters. |
| Depends on | depends_on |
Step ids that must finish first. Cycles are rejected when you save. |
| Run only if | condition |
A condition on variables. The step is skipped when it is false. |
| Outputs to dynamic variables | outputs |
Variable name mapped to a dotted path in the JSON response or result, for example tier = data.customer.tier. |
| Variables to set | values |
For Set variables, and on HTTP request to set extra variables after the response. |
| Step timeout | timeout_ms |
100 to 300,000 ms. Default 2,000. |
For Run code and Integration app without mapped outputs, every key of the returned object becomes a variable.
Templates in workflows#
URLs, headers, bodies, messages and arguments accept {{variable}}. In workflows, a variable that has no value renders as empty text, and object values render as JSON.
Conditions#
Run only if supports:
| Form | Example |
|---|---|
==, != |
{{tier}} == gold |
>, <, >=, <= (numbers) |
{{balance}} > 0 |
contains (case-insensitive) |
{{call_summary}} contains refund |
exists |
{{customer_id}} exists |
| A single value | {{is_vip}} is true unless empty, false or 0 |
How a run works#
- Steps whose dependencies are done run in parallel, level by level.
- A step whose dependency failed or timed out is skipped. A step after a skipped dependency still runs.
- Every output is added to the variables, so later steps can use earlier results.
- The whole stage shares one time budget. Steps still waiting when it runs out end as
timeout. - The run status is
success(no errors),partial,timeoutorfailed(every step failed).
Time budget#
Time budget for the whole stage (budget_ms) is 200 ms to 300,000 ms, default 3,000 ms. At run time it is capped at:
| Stage | Cap |
|---|---|
| Pre-call, inbound and web calls | 60 seconds |
| Pre-call, outbound calls | 5 minutes |
| Post-call | 5 minutes |
Pre-call steps delay the start of the call, so keep them fast.
Pre-call workflows#
Pre-call workflows run for:
- Inbound phone calls, after the number's inbound webhook.
- Create phone call, Create web call and Register phone call requests.
Available variables: the call's dynamic variables (including environment tag values), from_number, to_number and agent_id. Inbound runs also have direction.
The outputs are merged into the call's retell_llm_dynamic_variables, overriding values with the same name.
The editor still shows "Inbound calls are not covered yet", but inbound phone calls do run the pre-call workflow. Calls started by a batch call do not run it.
Post-call workflows#
Post-call workflows run after post-call analysis. Available variables:
- The call's dynamic and collected variables.
call_id,agent_id,from_number,to_number,direction,duration_ms,disconnection_reason.call_summary,user_sentiment,call_successful, and each custom analysis field by name.transcript: the whole transcript asrole: textlines.
Outputs are saved to the call's collected_dynamic_variables.
Send SMS uses the call's agent number as the sender. Leave the recipient empty to text the caller.
Needs keys Send SMS needs Telnyx messaging configured.
Test and monitor#
Test run runs the saved workflow with the variables you give it, without a call, and shows each step's status, time and outputs. Recent runs lists the last runs of each stage with their call ID and duration.
Example#
A pre-call lookup followed by a variable built from its result:
{
"enabled": true,
"budget_ms": 2500,
"steps": [
{
"id": "lookup",
"name": "CRM lookup",
"type": "http",
"method": "GET",
"url": "https://crm.example.com/lookup?phone={{from_number}}",
"headers": { "Authorization": "Bearer {{crm_token}}" },
"outputs": { "customer_name": "data.name", "tier": "data.tier" },
"timeout_ms": 1500
},
{
"id": "greeting",
"name": "VIP greeting",
"type": "set_variables",
"depends_on": ["lookup"],
"condition": "{{tier}} == gold",
"values": { "vip_note": "This is a gold customer. Offer priority booking." }
}
]
}| Action | Endpoint |
|---|---|
| Get both workflows | GET /agents/{agent_id}/workflows |
| Save one | PUT /agents/{agent_id}/workflows/{stage} (pre_call or post_call) |
| Test | POST /agents/{agent_id}/workflows/{stage}/test with { "variables": { ... } } |
| List runs | GET /agents/{agent_id}/workflow-runs (filter with ?call_id=) |
HTTP requests to your URLs go through Tried's outbound protection, so private and internal addresses are refused.