Outbound AI agent campaigns: the AI dialer and cold calling
How to launch robot-driven outbound calling: pipeline statuses, the agent card, a campaign in the AI dialer, the call result in the lead, the post-call webhook and analytics. Plus the case where calls are placed straight from the ElevenLabs dashboard.
The voice agent does not only answer calls — it places them too. This page covers the outbound side: how to build a campaign, where each call's result lands, and what breaks most often. Base agent setup is covered separately in AI voice agent.
#Two routes, and they are not equivalent
| CRM AI dialer | ElevenLabs batch calling | |
|---|---|---|
| Queue, retries, calling hours | in the CRM | in the ElevenLabs dashboard |
| Concurrent call limit | set per campaign | your plan's limit only |
| Lead locked during the call | yes | no |
| How the lead is found | from the call context | by the last 9 digits of the number |
| Reporting | in the CRM pipeline with every other lead | a separate campaign report |
Default to the AI dialer: one system instead of two, and the result is in the pipeline straight away. Batch calling makes sense when the campaign already lives on the ElevenLabs side — that case is covered at the end of this page.
#Step 1. Call-outcome statuses
The agent needs somewhere to put the result. For cold calling, a dedicated set of statuses is created in the CRM — exactly the ones the call result distinguishes between:
| Code | Status | Group |
|---|---|---|
meeting_booked | Meeting booked | Accepted |
interested | Interested | In progress |
send_info | Send materials | In progress |
wrong_person | Wrong person | In progress |
recall | Call back | In progress |
not_interested | Not interested | Cancelled |
no_need | No need | Cancelled |
competitor | Uses a competitor | Cancelled |
do_not_call | Do not call | Cancelled |
invalid_contact | Invalid contact | Error |
List only the codes the agent is allowed to set in its prompt: the model will use exactly what you permitted and nothing else. How groups and transitions work is covered in the statuses article.
#Step 2. The project and the list
- 01
Create a separate project for the campaign
The queue is drawn from it and the reports are filtered by it — a cold list never mixes with working leads.
- 02
Import the list
Leads → Import from file, mapping the columns onto CRM fields: importing from Excel and CSV. - 03
Map the comment column — always
It holds the company card: line of business, region, segment. That is what reaches the agent before the first word; without it the agent opens the conversation blind.
- 04
Strip the obvious junk
Rows flagged as having a broken number in the source register are better excluded by hand: those are not phone numbers, they are source errors.
#Step 3. The agent card for outbound
Integrations → AI agent
Agent IDfrom ElevenLabsrequiredthe agent's identifier in the dashboard
Outbound numberfrom ElevenLabsrequiredthe phone number the agent calls from
Gatewayemptyfor outbound campaigns ElevenLabs dials by itself; your telephony takes no part in the call
Projectchoicerequiredthe same one the queue is drawn from
Manager for meetingsuserrequiredwithout it
schedule_meetingrefuses — so the campaign's only goal fails exactly when the client has already agreedAllow cart changesflagturn it off for cold calling: nothing is sold during the call
Call length limitsecondsrequiredwith headroom above the target length: a timeout cut-off kills the
set_call_outcomecall
#Step 4. Tools for an outbound conversation
Every tool is a POST with the X-Asterisk-Secret header; ready-made addresses are listed in the CRM on the AI agent page. On an outbound call the client's number comes from the call context.
| Tool | What it does |
|---|---|
set_call_outcome | the important one: a status code plus a note for the manager. Called exactly once, before the goodbye |
schedule_meeting | meeting time, channel (Meet/Zoom), messenger for the link, email, topic. Sets the status, assigns the manager, creates the reminder |
update_customer | name, messenger, alternative number, email — called the moment it is heard, not at the end |
schedule_callback | an agreed call-back time; paired with the recall status |
end_call | the built-in ElevenLabs tool — only after set_call_outcome |
The note in set_call_outcome is not a secondary field. It, rather than the status, is what makes cold calling worth anything: “not interested, they already run another system” and “not interested, they have no sales team” are two different lists for the next wave. That is why an unknown status code never discards the note: a status can be set by hand, while a reason the agent relayed cannot be recovered from anywhere.
#Step 5. The post-call webhook
Settings → Webhooks → Post-call webhook in the ElevenLabs dashboard, HMAC auth, the secret being the same string as in the “Webhook signing key” field under Integrations → ElevenLabs.
Turn on “Pull call history automatically” next to it: every half hour the CRM fetches conversations it does not have yet. That covers three cases — the webhook was never configured, it was switched on after the first calls, or a delivery was lost. No duplicates: the conversation id is the key.
#Step 6. The campaign
AI dialer → New campaign
Projectchoicerequiredwhere the queue is drawn from
AI agentchoicerequiredthe agent card from step 3
Concurrent callsnumberrequiredbounded by your ElevenLabs plan: set too high it just burns attempts — a refused call counts as a failed one
Attempts per leadnumbertypically 2–3
Retry intervalsminutesfor example 60 and 240
Days and hoursschedulerequireda call at nine in the morning or seven in the evening ruins more than one conversation — it ruins the number's reputation
Then *Fill the queue*: project plus status. The queue is filled by selection, so a lead that has already been called and changed status will not be pulled into a new wave. The campaign monitor refreshes every few seconds and shows who is on a call right now.
#Step 7. Conversation analytics
Two different things are configured in the agent dashboard. Evaluation criteria answer “did this conversation work”: was a specific date and time agreed, was the decision maker on the line, did the agent answer “are you a robot?” honestly, did it stop after a clear refusal.
Data collection extracts structured fields from the conversation — which system they use today, how many people work with clients, what hurts, which objection came up. This does not duplicate set_call_outcome: the tool writes into the lead during the call, while analytics gives you the cross-section of the whole campaign and answers “who should the next wave call”.
#Step 8. Checks before the first call
lookup_customerresponds and finds the lead by number — the response should contain the comment with the company card.set_call_outcomewith a test status code changes the lead: check its history.- One live call to your own number, using “Call with the AI agent” from a lead card.
- Afterwards the card holds all three: the call with its transcript, the summary as a note, the new status in the history.
| Tool response | Cause |
|---|---|
403 forbidden | wrong Asterisk Secret, or the header never arrived |
not_found | no lead matches the last nine digits of the number |
unknown_status or status_applied: false | this CRM has no such status code — go back to step 1 |
If the call is there but the status is not, the model never called set_call_outcome. That is fixed in the tool description and the order inside the prompt, not by restarting the campaign.
#If calls are placed straight from ElevenLabs
When the campaign is built in the ElevenLabs dashboard (batch calling), the CRM takes no part in dialling — but the result can still land in the lead. The tools are the same; one thing changes: the lead is found by phone number, by its last nine digits, and the most recent lead for that number is taken. The way the number is written does not matter.
Access to the tools is granted by the Asterisk Secret from the telephony settings. A webmaster token will not do: it can do exactly one thing — create a lead — and never changes the status of an existing one. The secret lives only in the tool settings on the ElevenLabs side (server to server); it must never go into a browser, a landing page or a CSV, and changing it instantly breaks every tool that uses it.
Calls placed this way are invisible to your own server, so the webhook and the automatic history pull from step 5 are the only source of recordings and transcripts. Conversations that happened before the setup are backfilled with a separate command on the CRM server; running it again is safe.
#Boundaries worth knowing in advance
- The agent never marks “no answer”. An unanswered call is a conversation that never happened, so no tool was called in it. Those numbers show up in the campaign queue as failed attempts.
- Voicemail is its own case. Turn detection on, or the answering machine will sit through the whole script and count as a conversation.
- It is better not to let the agent quote prices. The cost depends on the number of users and the set of modules, and a cold call has no time to establish either: a figure named blind either scares the prospect off or contradicts the real quote later.
- A robot call is personal data. The recording is stored, so the prompt needs an honest answer to “where did you get my number” and a
do_not_callstatus for “stop calling me” — one that is excluded from later waves. - The agent never denies being a robot. Asked directly, it says so and offers to hand over to a human — which is not only ethics but also one of the things the evaluation criteria check.