Skip to main content
POST
/
v2
/
agent
cURL
curl --request POST \
  --url https://api.bolna.ai/v2/agent \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "agent_config": {
    "agent_name": "Alfred",
    "tasks": [
      {
        "task_config": {
          "hangup_after_silence": 10,
          "incremental_delay": 400,
          "number_of_words_for_interruption": 2,
          "hangup_after_LLMCall": false,
          "call_cancellation_prompt": null,
          "backchanneling": false,
          "backchanneling_message_gap": 5,
          "backchanneling_start_delay": 5,
          "ambient_noise_track": "coffee-shop",
          "call_terminate": 90,
          "voicemail": false,
          "inbound_limit": -1,
          "whitelist_phone_numbers": null,
          "disallow_unknown_numbers": false
        }
      }
    ],
    "agent_welcome_message": "How are you doing Bruce?",
    "webhook_url": "https://your-server.com/webhook",
    "agent_type": "other",
    "ingest_source_config": {
      "source_type": "api",
      "source_url": "https://example.com/api/data",
      "source_auth_token": "abc123",
      "source_name": "leads_sheet_june.csv"
    },
    "calling_guardrails": {
      "call_start_hour": 9,
      "call_end_hour": 17
    }
  },
  "agent_prompts": {}
}
'
import requests

url = "https://api.bolna.ai/v2/agent"

payload = {
"agent_config": {
"agent_name": "Alfred",
"tasks": [{ "task_config": {
"hangup_after_silence": 10,
"incremental_delay": 400,
"number_of_words_for_interruption": 2,
"hangup_after_LLMCall": False,
"call_cancellation_prompt": None,
"backchanneling": False,
"backchanneling_message_gap": 5,
"backchanneling_start_delay": 5,
"ambient_noise_track": "coffee-shop",
"call_terminate": 90,
"voicemail": False,
"inbound_limit": -1,
"whitelist_phone_numbers": None,
"disallow_unknown_numbers": False
} }],
"agent_welcome_message": "How are you doing Bruce?",
"webhook_url": "https://your-server.com/webhook",
"agent_type": "other",
"ingest_source_config": {
"source_type": "api",
"source_url": "https://example.com/api/data",
"source_auth_token": "abc123",
"source_name": "leads_sheet_june.csv"
},
"calling_guardrails": {
"call_start_hour": 9,
"call_end_hour": 17
}
},
"agent_prompts": {}
}
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_config: {
agent_name: 'Alfred',
tasks: [
{
task_config: {
hangup_after_silence: 10,
incremental_delay: 400,
number_of_words_for_interruption: 2,
hangup_after_LLMCall: false,
call_cancellation_prompt: null,
backchanneling: false,
backchanneling_message_gap: 5,
backchanneling_start_delay: 5,
ambient_noise_track: 'coffee-shop',
call_terminate: 90,
voicemail: false,
inbound_limit: -1,
whitelist_phone_numbers: null,
disallow_unknown_numbers: false
}
}
],
agent_welcome_message: 'How are you doing Bruce?',
webhook_url: 'https://your-server.com/webhook',
agent_type: 'other',
ingest_source_config: {
source_type: 'api',
source_url: 'https://example.com/api/data',
source_auth_token: 'abc123',
source_name: 'leads_sheet_june.csv'
},
calling_guardrails: {call_start_hour: 9, call_end_hour: 17}
},
agent_prompts: {}
})
};

fetch('https://api.bolna.ai/v2/agent', 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/v2/agent",
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_config' => [
'agent_name' => 'Alfred',
'tasks' => [
[
'task_config' => [
'hangup_after_silence' => 10,
'incremental_delay' => 400,
'number_of_words_for_interruption' => 2,
'hangup_after_LLMCall' => false,
'call_cancellation_prompt' => null,
'backchanneling' => false,
'backchanneling_message_gap' => 5,
'backchanneling_start_delay' => 5,
'ambient_noise_track' => 'coffee-shop',
'call_terminate' => 90,
'voicemail' => false,
'inbound_limit' => -1,
'whitelist_phone_numbers' => null,
'disallow_unknown_numbers' => false
]
]
],
'agent_welcome_message' => 'How are you doing Bruce?',
'webhook_url' => 'https://your-server.com/webhook',
'agent_type' => 'other',
'ingest_source_config' => [
'source_type' => 'api',
'source_url' => 'https://example.com/api/data',
'source_auth_token' => 'abc123',
'source_name' => 'leads_sheet_june.csv'
],
'calling_guardrails' => [
'call_start_hour' => 9,
'call_end_hour' => 17
]
],
'agent_prompts' => [

]
]),
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/v2/agent"

payload := strings.NewReader("{\n \"agent_config\": {\n \"agent_name\": \"Alfred\",\n \"tasks\": [\n {\n \"task_config\": {\n \"hangup_after_silence\": 10,\n \"incremental_delay\": 400,\n \"number_of_words_for_interruption\": 2,\n \"hangup_after_LLMCall\": false,\n \"call_cancellation_prompt\": null,\n \"backchanneling\": false,\n \"backchanneling_message_gap\": 5,\n \"backchanneling_start_delay\": 5,\n \"ambient_noise_track\": \"coffee-shop\",\n \"call_terminate\": 90,\n \"voicemail\": false,\n \"inbound_limit\": -1,\n \"whitelist_phone_numbers\": null,\n \"disallow_unknown_numbers\": false\n }\n }\n ],\n \"agent_welcome_message\": \"How are you doing Bruce?\",\n \"webhook_url\": \"https://your-server.com/webhook\",\n \"agent_type\": \"other\",\n \"ingest_source_config\": {\n \"source_type\": \"api\",\n \"source_url\": \"https://example.com/api/data\",\n \"source_auth_token\": \"abc123\",\n \"source_name\": \"leads_sheet_june.csv\"\n },\n \"calling_guardrails\": {\n \"call_start_hour\": 9,\n \"call_end_hour\": 17\n }\n },\n \"agent_prompts\": {}\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/v2/agent")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"agent_config\": {\n \"agent_name\": \"Alfred\",\n \"tasks\": [\n {\n \"task_config\": {\n \"hangup_after_silence\": 10,\n \"incremental_delay\": 400,\n \"number_of_words_for_interruption\": 2,\n \"hangup_after_LLMCall\": false,\n \"call_cancellation_prompt\": null,\n \"backchanneling\": false,\n \"backchanneling_message_gap\": 5,\n \"backchanneling_start_delay\": 5,\n \"ambient_noise_track\": \"coffee-shop\",\n \"call_terminate\": 90,\n \"voicemail\": false,\n \"inbound_limit\": -1,\n \"whitelist_phone_numbers\": null,\n \"disallow_unknown_numbers\": false\n }\n }\n ],\n \"agent_welcome_message\": \"How are you doing Bruce?\",\n \"webhook_url\": \"https://your-server.com/webhook\",\n \"agent_type\": \"other\",\n \"ingest_source_config\": {\n \"source_type\": \"api\",\n \"source_url\": \"https://example.com/api/data\",\n \"source_auth_token\": \"abc123\",\n \"source_name\": \"leads_sheet_june.csv\"\n },\n \"calling_guardrails\": {\n \"call_start_hour\": 9,\n \"call_end_hour\": 17\n }\n },\n \"agent_prompts\": {}\n}")
.asString();
require 'uri'
require 'net/http'

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

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_config\": {\n \"agent_name\": \"Alfred\",\n \"tasks\": [\n {\n \"task_config\": {\n \"hangup_after_silence\": 10,\n \"incremental_delay\": 400,\n \"number_of_words_for_interruption\": 2,\n \"hangup_after_LLMCall\": false,\n \"call_cancellation_prompt\": null,\n \"backchanneling\": false,\n \"backchanneling_message_gap\": 5,\n \"backchanneling_start_delay\": 5,\n \"ambient_noise_track\": \"coffee-shop\",\n \"call_terminate\": 90,\n \"voicemail\": false,\n \"inbound_limit\": -1,\n \"whitelist_phone_numbers\": null,\n \"disallow_unknown_numbers\": false\n }\n }\n ],\n \"agent_welcome_message\": \"How are you doing Bruce?\",\n \"webhook_url\": \"https://your-server.com/webhook\",\n \"agent_type\": \"other\",\n \"ingest_source_config\": {\n \"source_type\": \"api\",\n \"source_url\": \"https://example.com/api/data\",\n \"source_auth_token\": \"abc123\",\n \"source_name\": \"leads_sheet_june.csv\"\n },\n \"calling_guardrails\": {\n \"call_start_hour\": 9,\n \"call_end_hour\": 17\n }\n },\n \"agent_prompts\": {}\n}"

response = http.request(request)
puts response.read_body
{
  "agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "state": "created"
}
{
"error": 123,
"message": "<string>"
}
Creates a new voice AI agent. Returns HTTP 201 with { "agent_id": "...", "state": "created" }.
The quickest path is creating an agent in the dashboard (Auto Build) and copying its ID. Use the API when you need to programmatically provision agents at scale or integrate agent creation into your deployment pipeline.

Minimal example

The smallest body that produces a working English conversation agent:
Minimal request body
{
  "agent_config": {
    "agent_name": "My First Agent",
    "agent_welcome_message": "Hi! How can I help you today?",
    "tasks": [{
      "task_type": "conversation",
      "toolchain": {
        "execution": "sequential",
        "pipelines": [["transcriber", "llm", "synthesizer"]]
      },
      "tools_config": {
        "llm_agent": {
          "agent_type": "simple_llm_agent",
          "agent_flow_type": "streaming",
          "llm_config": {
            "provider": "openai",
            "model": "gpt-4.1-mini",
            "max_tokens": 150,
            "temperature": 0.2
          }
        },
        "synthesizer": {
          "provider": "elevenlabs",
          "provider_config": {
            "voice": "Nila",
            "voice_id": "V9LCAAi4tTlqe9JadbCo",
            "model": "eleven_turbo_v2_5"
          },
          "stream": true,
          "buffer_size": 250,
          "audio_format": "wav"
        },
        "transcriber": {
          "provider": "deepgram",
          "model": "nova-3",
          "language": "en",
          "stream": true,
          "encoding": "linear16",
          "sampling_rate": 16000,
          "endpointing": 250
        },
        "input": { "provider": "plivo", "format": "wav" },
        "output": { "provider": "plivo", "format": "wav" }
      },
      "task_config": {
        "call_terminate": 90,
        "hangup_after_silence": 10
      }
    }]
  },
  "agent_prompts": {
    "task_1": {
      "system_prompt": "You are a helpful assistant. Keep replies short and friendly."
    }
  }
}
201 Response
{
  "agent_id": "123e4567-e89b-12d3-a456-426655440000",
  "state": "created"
}

Common 400 errors

MessageFix
agent_config is requiredWrap your config in { "agent_config": { ... } }
tasks is requiredThe tasks array must have at least one entry
toolchain.pipelines must be array of arraysUse [["transcriber","llm","synthesizer"]], not ["transcriber","llm","synthesizer"]

Next steps

After creating an agent, place a call with POST /call using the returned agent_id. See the API Quickstart for a complete end-to-end example.

Authorizations

Authorization
string
header
required

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

Body

application/json

Creates a new agent

agent_config
object
required

Configuration of the agent

agent_prompts
object
required

Prompts to be provided to the agent. It can have multiple tasks of the form task_<task_id>

Response

agent created response

agent_id
string<uuid>
state
enum<string>
Available options:
created
Example:

"created"