Connect Two Numbers (Click-to-Call)
Click-to-Call lets you programmatically connect two phone numbers — for example, linking a sales agent with a customer — by initiating Outbound Calls from your application.
This is a powerful tool for CRMs, lead forms, support desks, or any system that needs to trigger calls automatically.
⚙️ How It Works
This Click-to-Call scenario creates two outbound calls and bridges them together:
- Leg A: The scenario first dials the first target (
$targetA
) usingdial@v1
. This could be an internal user, agent, or operator. - If leg A answers, the call enters the
answered
branch. - Leg B: In that branch, it then dials the second target (
$targetB
) using a seconddial@v1
call. - If both calls are successful, the scenario uses
bridge@v1
to connect the two legs together in real time. - Throughout the process, call statuses are tracked with custom variables (
$statusA
,$statusB
), and a full status object is sent to your server usingfetch@v2
.
You can configure different Caller IDs for each leg using $cliA
and $cliB
, which must either be numbers assigned to your account or pre-approved as Caller IDs.
description: Two outbound calls
compat:
version: 2025-09-01
defaults:
language: en-US
variables:
# Targets A and B
$targetA: "+33639980041"
$targetB: "+33639980042"
# CallerIDs
# these numbers must be either:
# - assigned numbers on your account
# - callerids approved on your account
$cliA: "+33199001234"
$cliB: "+33199006789"
# Dial statuses
$dialA: null
$dialB: null
# We will store the status of each leg
$statusA: "nodial"
$statusB: "nodial"
branches:
api-initiated:
actions:
# Dial A
- action: javascript@v1
params:
code: |
$statusA = 'dialing'
# The dial action is blocking until the call is hung up
- action: dial@v1
params:
cli: ${{ $cliA }}
targets:
- number: ${{ $targetA }}
timeout: 30
answerOnBranch: answered
result: $dialA
- if: $statusA === 'dialing'
action: javascript@v1
params:
code: $statusA = $dialA.status
- action: javascript@v1
params:
code: |
return {
run: run,
dial: {
A: $dialA,
B: $dialB,
},
status: {
A: $statusA,
B: $statusB
}
}
result: $body
# Push the call statuses to your server
- action: fetch@v2
params:
url: https://api.example.com/call-logs
method: POST
body: ${{ JSON.stringify($body) }}
headers:
Content-Type: application/json
# The answered branch defines the action for the first leg of the call (A)
answered:
actions:
# Update variables
- action: javascript@v1
params:
code: |
$statusA = 'answered'
$statusB = 'dialing'
# Call leg B now
- action: dial@v1
params:
cli: ${{ $cliB }}
answerOnBranch: legB
targets:
- number: ${{ $targetB }}
timeout: 30
result: $dialB
- if: "!$dialB.ok"
then:
- action: javascript@v1
params:
code: $statusB = $dialB.status
- action: say@v2
params:
what: Sorry, we could not reach an agent. Please try again later.
- action: hangup@v1
legB:
actions:
- action: javascript@v1
params:
code: |
$statusA = 'bridged'
$statusB = 'bridged'
- action: bridge@v1
- action: hangup@v1
🚀 Trigger via API
Here's how to trigger this flow using curl
and your API key:
curl --request POST \
--url https://api.callr.com/v2.0/actions/<your-scenario-sid>/runs \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-api-key: <your-callr-api-key>' \
--data '
{
"variables": {
"$targetA": "<target-a>",
"$targetB": "<target-b>"
}
}
'
Replace:
<your-scenario-sid>
with the SID of the Callr Actions scenario<your-callr-api-key>
with your actual API key<target-a>
with the first number to call<target-b>
with the second number to call
More examples
You can view the full documentation of this method here.
📝 Notes
- You can use this approach for call tracking, lead follow-up, or agent-customer handoffs.
- Both legs of the call are visible in your call logs, and full CDR data is available.
- You can enhance the flow with
say@v2
, orfetch@v2
to collect and store context.
Reminder
If you're in Build Mode, you can only call Testing Numbers — phone numbers you own and have verified.
Make sure to add your personal number as a Testing Number in the Callr Portal.
✅ Use Cases
- 💼 Sales: Connect reps with leads as soon as they fill out a form
- 🛠️ Support: Let agents instantly follow up on ticket updates
- 📊 Tracking: Log call metadata for analytics and reporting
Updated 13 days ago