Skip to main content
POST
/
call
cURL
curl --request POST \
  --url https://api.bolna.ai/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "agent_id": "123e4567-e89b-12d3-a456-426655440000",
  "recipient_phone_number": "+10123456789",
  "from_phone_number": "+19876543007",
  "scheduled_at": "2025-08-21T10:35:00+00:00",
  "user_data": {
    "variable1": "value1",
    "variable2": "value2",
    "variable3": "some phrase as value"
  },
  "agent_data": {
    "voice_id": "Sam"
  }
}
'
import requests

url = "https://api.bolna.ai/call"

payload = {
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789",
"from_phone_number": "+19876543007",
"scheduled_at": "2025-08-21T10:35:00+00:00",
"user_data": {
"variable1": "value1",
"variable2": "value2",
"variable3": "some phrase as value"
},
"agent_data": { "voice_id": "Sam" }
}
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({
agent_id: '123e4567-e89b-12d3-a456-426655440000',
recipient_phone_number: '+10123456789',
from_phone_number: '+19876543007',
scheduled_at: '2025-08-21T10:35:00+00:00',
user_data: {variable1: 'value1', variable2: 'value2', variable3: 'some phrase as value'},
agent_data: {voice_id: 'Sam'}
})
};

fetch('https://api.bolna.ai/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_URL => "https://api.bolna.ai/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([
'agent_id' => '123e4567-e89b-12d3-a456-426655440000',
'recipient_phone_number' => '+10123456789',
'from_phone_number' => '+19876543007',
'scheduled_at' => '2025-08-21T10:35:00+00:00',
'user_data' => [
'variable1' => 'value1',
'variable2' => 'value2',
'variable3' => 'some phrase as value'
],
'agent_data' => [
'voice_id' => 'Sam'
]
]),
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 := "https://api.bolna.ai/call"

payload := strings.NewReader("{\n \"agent_id\": \"123e4567-e89b-12d3-a456-426655440000\",\n \"recipient_phone_number\": \"+10123456789\",\n \"from_phone_number\": \"+19876543007\",\n \"scheduled_at\": \"2025-08-21T10:35:00+00:00\",\n \"user_data\": {\n \"variable1\": \"value1\",\n \"variable2\": \"value2\",\n \"variable3\": \"some phrase as value\"\n },\n \"agent_data\": {\n \"voice_id\": \"Sam\"\n }\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("https://api.bolna.ai/call")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"agent_id\": \"123e4567-e89b-12d3-a456-426655440000\",\n \"recipient_phone_number\": \"+10123456789\",\n \"from_phone_number\": \"+19876543007\",\n \"scheduled_at\": \"2025-08-21T10:35:00+00:00\",\n \"user_data\": {\n \"variable1\": \"value1\",\n \"variable2\": \"value2\",\n \"variable3\": \"some phrase as value\"\n },\n \"agent_data\": {\n \"voice_id\": \"Sam\"\n }\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.bolna.ai/call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"agent_id\": \"123e4567-e89b-12d3-a456-426655440000\",\n \"recipient_phone_number\": \"+10123456789\",\n \"from_phone_number\": \"+19876543007\",\n \"scheduled_at\": \"2025-08-21T10:35:00+00:00\",\n \"user_data\": {\n \"variable1\": \"value1\",\n \"variable2\": \"value2\",\n \"variable3\": \"some phrase as value\"\n },\n \"agent_data\": {\n \"voice_id\": \"Sam\"\n }\n}"

response = http.request(request)
puts response.read_body
{
  "message": "done",
  "status": "queued",
  "execution_id": "123e4567-e89b-12d3-a456-426614174000"
}
{
"error": 123,
"message": "<string>"
}
Places an outbound call from a Bolna agent to a phone number. Returns an execution_id you use to track and retrieve the call result.

Minimal example

Only two fields are required — agent_id and recipient_phone_number. Omit from_phone_number to use your account’s default number.
Minimal request
{
  "agent_id": "123e4567-e89b-12d3-a456-426655440000",
  "recipient_phone_number": "+919876543210"
}
Response
{
  "message": "done",
  "status": "queued",
  "execution_id": "b7140255-af33-4608-8e97-04dd944b8e48"
}

Realistic example with personalization

Pass user_data to inject variables into your agent’s prompt and welcome message (e.g. {customer_name} in the prompt becomes “Asha”):
Request with personalization
{
  "agent_id": "123e4567-e89b-12d3-a456-426655440000",
  "recipient_phone_number": "+919876543210",
  "from_phone_number": "+918035739222",
  "user_data": {
    "customer_name": "Asha",
    "appointment_day": "Friday"
  }
}

Tracking the call

Use the returned execution_id to poll GET /executions/{execution_id} for status. The call goes through these stages:
queued → initiated → ringing → in-progress → call-disconnected → completed
Wait for completed, not call-disconnected. The call-disconnected event fires the instant the line drops, but conversation_duration, total_cost, recording_url, and extracted_data are not yet populated. The completed event (a few seconds later) has all finalized fields. See Get Execution.

Common 400 errors

MessageFix
agent_id is requiredInclude a valid UUID agent_id
recipient_phone_number is requiredPhone number must be E.164 format, e.g. +919876543210
Invalid from_phone_numberMust be a number purchased in your Bolna account

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json

Make a phone call from agent

agent_id
string<uuid>
required

Agent id which will initiate the outbound call

recipient_phone_number
string
required

Phone number of the recipient along with country code (in E.164 format)

from_phone_number
string

Phone number of the sender along with country code (in E.164 format). Optional — if omitted, Bolna uses the account's default number.

scheduled_at
string

The scheduled date and time in ISO 8601 format with time zone

Example:

"2024-06-05T16:35:00.000+05:30"

user_data
object

Additional user dynamic variables as defined in the agent prompt

agent_data
object

Agent configuration to override the default configuration. Currently, only voice_id for the same provider is supported.

retry_config
object

Configuration for auto-retry of failed calls. See auto-retry documentation for details.

bypass_call_guardrails
boolean
default:false

Skip time validation checks and make call immediately regardless of agent's calling_guardrails configuration

Response

agent status response

message
string

Response message for the call initiated

Example:

"done"

status
enum<string>

Status of the call.

Available options:
queued
Example:

"queued"

execution_id
string

Unique execution_id or call_id identifier of the call.

Pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}
Example:

"123e4567-e89b-12d3-a456-426614174000"