curl --request POST \
--url http://localhost:8080/phone/outbound-call \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"phoneAgentId": "<string>",
"contact": {
"id": "<string>"
},
"sessionCustomData": {},
"extraInstructions": "<string>"
}
'import requests
url = "http://localhost:8080/phone/outbound-call"
payload = {
"phoneAgentId": "<string>",
"contact": { "id": "<string>" },
"sessionCustomData": {},
"extraInstructions": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phoneAgentId: '<string>',
contact: {id: '<string>'},
sessionCustomData: {},
extraInstructions: '<string>'
})
};
fetch('http://localhost:8080/phone/outbound-call', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://localhost:8080/phone/outbound-call",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phoneAgentId' => '<string>',
'contact' => [
'id' => '<string>'
],
'sessionCustomData' => [
],
'extraInstructions' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://localhost:8080/phone/outbound-call"
payload := strings.NewReader("{\n \"phoneAgentId\": \"<string>\",\n \"contact\": {\n \"id\": \"<string>\"\n },\n \"sessionCustomData\": {},\n \"extraInstructions\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost:8080/phone/outbound-call")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"phoneAgentId\": \"<string>\",\n \"contact\": {\n \"id\": \"<string>\"\n },\n \"sessionCustomData\": {},\n \"extraInstructions\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/phone/outbound-call")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phoneAgentId\": \"<string>\",\n \"contact\": {\n \"id\": \"<string>\"\n },\n \"sessionCustomData\": {},\n \"extraInstructions\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"error": {
"code": "<string>",
"status": 123
},
"result": "<unknown>",
"sessionId": "<string>",
"callId": "<string>"
}{
"statusCode": 429,
"message": "<string>",
"error": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"error": "<string>"
}{
"statusCode": 429,
"message": "<string>",
"error": "<string>"
}Make an AI phone call
Request a one-time outbound call using an AI phone agent. Use Sequences for scheduled or bulk calling.
curl --request POST \
--url http://localhost:8080/phone/outbound-call \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"phoneAgentId": "<string>",
"contact": {
"id": "<string>"
},
"sessionCustomData": {},
"extraInstructions": "<string>"
}
'import requests
url = "http://localhost:8080/phone/outbound-call"
payload = {
"phoneAgentId": "<string>",
"contact": { "id": "<string>" },
"sessionCustomData": {},
"extraInstructions": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phoneAgentId: '<string>',
contact: {id: '<string>'},
sessionCustomData: {},
extraInstructions: '<string>'
})
};
fetch('http://localhost:8080/phone/outbound-call', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://localhost:8080/phone/outbound-call",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phoneAgentId' => '<string>',
'contact' => [
'id' => '<string>'
],
'sessionCustomData' => [
],
'extraInstructions' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://localhost:8080/phone/outbound-call"
payload := strings.NewReader("{\n \"phoneAgentId\": \"<string>\",\n \"contact\": {\n \"id\": \"<string>\"\n },\n \"sessionCustomData\": {},\n \"extraInstructions\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost:8080/phone/outbound-call")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"phoneAgentId\": \"<string>\",\n \"contact\": {\n \"id\": \"<string>\"\n },\n \"sessionCustomData\": {},\n \"extraInstructions\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/phone/outbound-call")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phoneAgentId\": \"<string>\",\n \"contact\": {\n \"id\": \"<string>\"\n },\n \"sessionCustomData\": {},\n \"extraInstructions\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"error": {
"code": "<string>",
"status": 123
},
"result": "<unknown>",
"sessionId": "<string>",
"callId": "<string>"
}{
"statusCode": 429,
"message": "<string>",
"error": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"error": "<string>"
}{
"statusCode": 429,
"message": "<string>",
"error": "<string>"
}429 or 503 with an outbound_call_* error, no call was started for that request. The endpoint does not retry it automatically or provide a Retry-After header. Your application decides whether to try again later.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
- Option 1
- Option 2
Show child attributes
Show child attributes
Custom attributes saved on the call session before the call starts, so workflows and webhooks that fire at call start already see them. Also surfaced to the AI agent as session context. Equivalent to the X-OPENCX-SESSION-CUSTOM-DATA header on inbound calls.
Show child attributes
Show child attributes
Extra instructions for the AI agent, scoped to this call only. Appended to the agent instructions in a clearly-scoped block — they complement, never replace, the agent prompt.
10000Response
Default Response
Error details if the call failed
Show child attributes
Show child attributes
Raw call result from the provider
ID of the session created for this call, available at dial time. Use it to correlate call webhooks (phone_call.started / phone_call.ended carry the same session_id) and to fetch the session — including its custom data — after the call.
Provider call ID
Was this page helpful?