Skip to content
Expedify
6 min

Voice Outbound Action

Ringing someone is the one action in this course that can get an organisation in trouble. The node knows that — its compliance checks are on by default, and most of its settings exist to stop you.

Every other node in this module answers. This one starts the conversation: the workflow decides somebody should be called, and their phone rings. A lead filled in a form, a payment failed, a delivery is late — all good reasons, and all of them reach a person who did not choose that moment.

Which is why this node is the most heavily guarded in the product. It can dial one number or a thousand, with an AI agent or a member of your team on the line. Nearly everything in its configuration exists to bound that: who may be called, when, how often, and how quickly.

No workflow on this page, and no written source for this lesson. Outbound calling needs a telephony provider the tutorial organisation does not have. Written from the node itself.

Who gets called

Six of nineteen. The rest are the guard rails, below.

call_type

What it holds
Human: Connect two humans | AI: AI agent handles call One of: human · ai Defaults to ai.

call_input

What it holds
Unified call input - single object or array of objects with phone and variables

call_input_mode

What it holds
Single call or batch calls mode One of: single · batch Defaults to single.

integration_id

What it holds
Voice provider integration ID (Exotel, Twilio, etc.)

caller_id

What it holds
Phone number to display to customer

caller_id_mode

What it holds
Caller ID mode: fixed (dropdown selection) or dynamic (variable input) One of: fixed · dynamic Defaults to fixed.

call_input is the field that matters and it takes three shapes: one object with a phone number and the variables the agent should know, an array of them, or a reference to an array an upstream node produced. The last is how a campaign is built — a search returns contacts, and this node calls them.

Nothing binds the call to a contact for you. This is the node's own warning and it catches everyone. Passing a phone number does not tell the Voice Agent who it is speaking to — the name, the account, the reason for the call all have to be listed in variables explicitly. An agent that says “hello, who am I speaking to” on an outbound call is a variables problem, not an agent problem.

You will also see a phone_input field in older workflows. It is deprecated and call_input replaces it. Do not start anything new on it.

The guard rails

Three of these are on before you touch anything, and knowing which is the difference between a compliant campaign and an expensive one.

compliance.check_dnc

Default
On
What it does
Filters the list against Do Not Call before dialling. Numbers on it are dropped, not skipped-with-an-error.

recording_options.record_call

Default
On
What it does
Records the call. Fine in some jurisdictions, an offence in others without an announcement — check before you rely on the default.

compliance.enable_amd

Default
Off
What it does
Answering-machine detection. Off means an AI agent will happily hold a conversation with a voicemail greeting.

business_hours_config.enabled

Default
Off
What it does
Off means a workflow triggered at 3am calls at 3am. Turn it on for anything customer-facing.

Turn answering-machine detection on for any AI campaign. With it off, voicemail is indistinguishable from a person to the agent — it talks, records a call that reached nobody, and bills for the minutes. With it on you also choose what to do: continue leaves a message, hangup does not. Either is a decision; the default is not.

Business hours are an enum, not free text. The timezone list is fixed — nine zones — so if the one you need is not there, that is the answer rather than a typo to fix. The windows are a list, so a lunch break is two windows rather than one with a hole in it.

Three different timeouts

This is where people lose an afternoon. The node has three time limits and they measure different things.

Two of the three are on this node and neither of them limits the call.

ring_timeout_seconds

Range and default
What it measures
How long their phone rings before you give up. The only one about the customer's experience.

call_timeout_minutes

Range and default
What it measures
How long the workflow waits for the call to finish. Left empty it is automatic — three minutes on Exotel, thirty elsewhere.

Range and default
What it measures
How long the call itself may last. This is the only one that ends a conversation.

The automatic default for the middle one is worth internalising, because three minutes is short. On Exotel, a workflow that waits for a call and does something with the transcript will stop waiting partway through an ordinary conversation unless you set the value yourself. For batch campaigns it is the setting to get right first.

Batches and retries

In batch mode the node paces itself: three simultaneous calls by default, five seconds between them, and a failure does not stop the run. Raise the concurrency and you raise the chance of your provider throttling you and of several people picking up to silence because the agent is busy. Three is a sensible number.

Retries are off by default and worth leaving off until you have thought about them. When enabled they back off exponentially, and the base delay cannot go below two minutes — a limit of the scheduler rather than a policy. Consider that a floor and set something much larger; retrying a missed call two minutes later reads as harassment, not diligence.

What breaks

Watch out: ai_call_config.voice_agent_node_id must equal the target voice_agent node — set it with `voice_agent:` and the compiler wires it.

call_input takes a phone + variables the agent needs (there's no auto-binding to the called contact).

A dropped number is not a failure. Numbers removed by the Do Not Call check simply do not appear in the call list. The run succeeds, the batch is smaller than your audience, and nothing says why. If a campaign reached fewer people than you expected, compare the count going in against the calls placed before you go looking for a bug.

The workflow pauses per call, and the pause is where batches get expensive. Like the inbound node, this one parks the run until the call completes. In a batch that is fine; in a loop calling one number at a time it means the workflow is held open for the sum of every conversation. Use batch mode rather than a Loop around a single call.

Caller ID is what the customer sees, and it decides whether they answer. Fixed mode picks one number; dynamic lets a variable choose per call, which is how a regional campaign shows a local number. Neither is the number the call comes from technically — it is the number displayed — so a caller ID nobody can ring back is worse than none.

Try it

  1. Call yourself first. One entry in call_input with your own number, call_type set to ai, pointed at a Voice Agent. Nothing else.
  2. Pass your own name through variables and have the agent greet you with it. That is the step that proves the binding is manual.
  3. Set ring_timeout_seconds to 10 and do not answer. Watch the workflow resume ten seconds later — then compare with what call_timeout_minutes would have done.
  4. Turn on answering-machine detection with amd_action set to hangup, and let it go to voicemail. Then turn it off and do the same. Listening to an AI agent talk to your voicemail greeting is the most persuasive argument for the setting.
  5. Only then point it at a real list, with business hours on and the batch concurrency left at three.

Next: Transfer Call — handing a live conversation to a person, which is what a good AI agent does the moment it is out of its depth.

Related lessons