# Agent Studio
Source: https://www.bolna.ai/docs/agent-setup/agent-builder
Go from a brief description to a production-grade, call-ready voice AI agent in 5 to 8 minutes — no prompt writing required.
## What is Agent Studio?
Agent Studio turns a short description of your use case into a production-grade, call-ready voice AI agent — in 5 to 8 minutes. No prompt engineering, no guesswork. Just fill in a form and get a fully structured agent prompt, auto-selected voice, and a published version ready to make calls.
***
## How to Use It
Click **+ New Agent** in the sidebar and choose **Auto Build Agent** to open Agent Studio.
The form has **3 steps**:
Tell the builder who the agent is and what the call is for.
Define the welcome message, guardrails, and conversation flow.
Set the final line the agent says before hanging up.
Once submitted, your agent is production-ready in **5 to 8 minutes**. You can navigate away — the agent will appear in your dashboard when ready.
***
## Step 1 — Identity & Goal
There are two ways to provide context — and the more context you give, the better your agent will be.
Upload a PDF, DOCX, TXT, or CSV — a call script, SOP, FAQ sheet, or any business document. The builder reads it and pre-fills the fields automatically.
Fill in the fields yourself. Be as detailed as possible — specific goals, flows, and guardrails produce a far better agent than vague inputs.
You can also do both — upload a document **and** add extra details in the fields. More context always means a better agent.
### Fields
| Field | Required | What to enter |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| **Agent Name** | ✅ | The name the agent introduces itself with. E.g. *Saanvi* |
| **Industry** | ✅ | Select from the list or choose "Other" to type your own |
| **Agent Designation** | ✅ | The agent's role. E.g. *Recruitment Specialist* |
| **Company Name** | ✅ | The organisation the agent represents |
| **Company Description** | Optional | A short description of the company |
| **Languages** | ✅ | One or more languages the agent should speak. Set one as Primary |
| **Gender** | ✅ | Male or Female — used to auto-select the best matching voice |
| **Tone** | ✅ | Pick one or more: *Warm & professional, Formal, Casual, Assertive, Empathetic* |
| **What Should This Call Achieve?** | ✅ | The call goal in 1–2 sentences. E.g. *Screen candidates and book a technical interview if they qualify* |
Blended tones work well — e.g. **Warm & professional + Empathetic** for support calls, **Warm + Assertive** for collections. Avoid picking all of them.
***
## Step 2 — Conversation
| Field | Required | What to enter |
| ------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Agent Welcome Message** | ✅ | The first thing the agent says when the call connects. Use `{variable_name}` for dynamic values |
| **Guardrails** | ✅ | Hard rules the agent must follow — topics to avoid, things it must never say, when to hand off to a human |
| **Conversation Flow** | ✅ | The steps the agent follows in order. Numbered steps work best. E.g. *1. Greet → 2. Ask about experience → 3. Qualify* |
Click **"See default guardrails"** on the Guardrails field for a pre-filled set of sensible defaults you can copy and customise.
***
## Step 3 — Closing
| Field | Required | What to enter |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| **Closing Line** | ✅ | The last message the agent says before disconnecting. E.g. *Thanks for your time. We'll follow up by email.* |
| **Hangup Prompt** | Optional | Toggle on to give the agent a custom instruction for when to end the call — useful for complex call flows |
***
## After Generation
Once the prompt is ready, it is automatically saved to your agent. You can:
* **Review and edit** the prompt in the [Agent Tab](/docs/agent-setup/agent-tab)
* **Adjust the voice** in the [Audio Tab](/docs/agent-setup/audio-tab) — a voice is auto-selected based on your language and gender settings
* **Test the agent** via browser or by receiving a test call
***
## Frequently Asked Questions
**5 to 8 minutes**. You can navigate away; the agent status updates automatically when it's done.
Yes. The generated prompt is fully editable in the Agent tab. Agent Studio gives you a strong starting point you can fine-tune from there.
PDF, DOCX, TXT, and CSV files are supported. Upload call scripts, SOPs, FAQ sheets, or any business document relevant to the agent's role.
***
## Next Steps
Review and edit the generated prompt
Adjust the auto-selected voice if needed
Start making calls with your new agent
Best practices for prompting voice agents
# Configure Multilingual Agent Prompts and Hangup Settings
Source: https://www.bolna.ai/docs/agent-setup/agent-tab
Set up your Bolna Voice AI agent's welcome message, write per-language prompts with dynamic variables, configure language switching, and define intelligent call hangup conditions.
The Agent Tab controls your agent's welcome message, prompts, and conversation behavior. Add multiple languages, set a primary, and write a dedicated prompt for each.
***
## Agent Welcome Message
The first thing callers hear when they connect.
Brief greetings work best. Long announcements feel robotic.
Personalize with `{variable_name}`, e.g. `{customer_name}`.
***
## Canvas
Each language gets its own prompt. Select a language tab and write the prompt for that language. The agent activates the matching prompt when speaking in that language during a call.
### Managing Languages
Languages are **synced** between the Agent Tab and [Audio Tab](/docs/agent-setup/audio-tab). Adding or removing a language in either tab updates both. Each language can also have its own [STT and TTS providers](/docs/agent-setup/audio-tab) configured in the Audio Tab.
Click **+ Add Language** to create a new language tab.
Click the **crown icon** next to any language to make it primary. The primary language is what the agent starts every conversation in, marked with **(Primary)** in the tab.
Select each language tab and write its prompt.
Click the **x** on a tab to remove it from both tabs.
### Prompt Structure
| Section | Purpose | Example |
| ---------------- | --------------- | ------------------------------------------- |
| **Personality** | Tone and feel | "warm, perceptive, and results-driven" |
| **Context** | Role background | "You are calling on behalf of Acme Corp..." |
| **Instructions** | Tasks and flow | "Ask for their order number first..." |
| **Guardrails** | Restrictions | "Never discuss competitor products..." |
The editor shows a **token count** in the bottom-right to help you stay within LLM limits.
### Variable Syntax
| Syntax | Purpose | How to use |
| ----------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `{variable_name}` | Insert or define variables | Type `{` to open the variable picker. Select an existing variable or type a new name to create one. |
| `@` | Insert prompt modules, custom functions, or variables | Type `@` to browse and select existing modules, functions, or variables. You cannot create new items with `@`. |
Select existing variables or **create new ones** by typing a name. Values are passed via API or CSV at call time.
Select existing [prompt modules](/docs/prompting-guide#prompt-modules), [custom functions](/docs/tool-calling/custom-function-calls), or variables. Cannot create new items.
### Browse Modules
Click the **Browse Modules** button in the top-right of the prompt section to open the full modules library. Browse by category (Collection, Optional, Flow, Sector, Universal), preview what each module does, and insert it directly into your prompt. See the [Prompting Guide](/docs/prompting-guide#prompt-modules) for the full list of available modules.
***
## Language Switching Instructions
A **single shared field** that applies to all languages. Describes when the agent should switch languages mid-call.
| What to include | Example |
| ---------------------- | ----------------------------------------------------- |
| **Trigger conditions** | "Switch to Hindi if the user speaks in Hindi" |
| **Fallback behavior** | "Fall back to English if the language is unsupported" |
| **Default rule** | "Respond in the language the user is currently using" |
Write these once. They apply across all languages automatically.
***
## Per-Language Advanced Settings
Each language tab has its own expandable **Advanced Settings** section.
| Field | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Agent Name** | Name the agent uses to identify itself in this language |
| **Handoff Message** | Message spoken when switching **away from** this language. Supports variables like `{agent_name}` and `{language}`. |
### Prompt Variables for Testing
When you use `{variable_name}` in your prompt, those variables **automatically appear** as input fields in the testing section. Fill in test values to preview how the prompt behaves before going live.
The **Timezone** selector (e.g., `Asia/Kolkata UTC+05:30`) is a separate field that sets the timezone context for test calls.
Settings are independent. Hindi's Agent Name and Handoff Message do not affect English.
Always set a Handoff Message per language. Without it, transitions feel abrupt.
***
## Hangup Using Prompt
Let your agent decide when to end calls based on conversation context instead of silence detection or timeouts.
Turn on **Hangup using a prompt**.
Write conditions for when a conversation is complete. For multilingual agents, include closing lines in each language.
```
A conversation is considered complete if any of the following conditions are met:
User is not interested:
The assistant has said the following closing line:
Conversation Closing (English): "That is sad to hear. But no worries if you would ever want to learn more give me a cool."
Conversation Closing (Hindi): "ये सुनकर अफ़सोस हुआ। लेकिन कोई बात नहीं, अगर आप कभी और जानना चाहें तो मुझे call कर लें।"
The user has responded after that with any of the following phrases: "goodbye", "bye", "thank you", "thanks", "ok", "okay", or similar.
The last message in the transcript must be from the user.
```
Without this, calls end only on silence detection or timeouts.
***
## Next Steps
Configure the language model and knowledge bases
Set up voice, transcription, and languages
Best practices for writing prompts
Dynamic personalization with context
# Set Up Webhooks and Post-Call Extractions
Source: https://www.bolna.ai/docs/agent-setup/analytics-tab
Configure webhooks, call summarization, and data extraction for Bolna Voice AI. Push data to your CRM from every call.
## What is the Extractions Tab?
The Extractions Tab is where you configure webhooks for real-time data and post-call processing tasks. Automatically summarize conversations, extract structured data, and push execution data to your systems.
***
## Configuration Options
### Push Execution Data to Webhook
**Don't miss real-time updates!** Configure a webhook to receive all execution data as calls happen — essential for CRM integrations and live dashboards.
Enter your webhook URL to automatically receive all execution data for this agent.
Click **[See all events](/docs/guides/post-call/polling-call-status-webhooks)** to view the complete list of webhook event types you can receive.
***
### Post Call Tasks
Choose tasks to execute after the agent conversation is complete.
Automatically generate a summary of every conversation. Great for quick review and logging.
Toggle on to enable automatic conversation summarization.
Create custom extraction templates organized by categories to automatically capture structured data from call transcripts.
**Extractions** allow you to automatically capture structured data from call transcripts. Organize extractions into categories and define custom questions to extract specific information like lead quality, appointment details, customer sentiment, and more.
### Key Features
**Categories** - Organize related extractions together (e.g., "Agent Handover", "Visit Details", "Lead Qualification")
**Extraction Templates** - Define what data to capture with:
* **Name** - Descriptive identifier (e.g., "Call Outcome", "Customer Sentiment")
* **Extraction Prompt** - Instructions guiding the LLM on what to extract
* **Answer Type** - Choose between Free Text (open-ended) or Pre-defined (categorical options)
* **Model** - Select LLM for extraction processing (default: gpt-4.1-mini)
**Testing** - Validate extractions against sample or real transcripts before production deployment
### Common Extraction Categories
Detect when calls need human intervention
Extract budget, timeline, decision-maker info
Capture appointment times, dates, confirmation status
Analyze satisfaction levels and feedback
Learn how to create and manage extraction templates, configure answer types, and test extractions in the [Using Extractions](/docs/guides/prompting/using-extractions) guide.
***
## Use Cases
Automatically update customer records after calls
Extract qualification data from sales calls
Capture required data points for regulations
Analyze conversation outcomes and metrics
***
## Next Steps
Configure inbound call settings
Add function tools and APIs
View call logs and transcripts
Learn about webhook events
# Configure Voice and Transcription Settings
Source: https://www.bolna.ai/docs/agent-setup/audio-tab
Set up languages, speech-to-text, and text-to-speech for your Bolna Voice AI agent. Pick providers, select voices, clone custom voices, and tune audio quality.
The Audio Tab controls how your agent listens and speaks. Configure languages, choose transcription and voice providers, and tune audio quality. For multilingual agents, you can select **different STT and TTS providers per language**.
***
## Languages
Set the languages your agent can understand and speak. Pick a primary language and add secondary languages for multilingual conversations.
* **Primary Language** is marked with `(Primary)` and is the language your agent uses at the start of every conversation. The main prompt and multilingual settings are tied to this language.
* **Secondary Languages** allow the agent to understand and respond when a caller switches languages mid-call.
* Click **+ Add Language** to add more languages.
* Remove any language by clicking the **x** next to it.
### Changing the Primary Language
Click the **crown icon** next to any secondary language to make it primary. A tooltip will confirm the action, for example "Make Hindi primary". This sets the selected language as the default for the main prompt and multilingual settings.
### Supported Languages
| Language | Code |
| ---------- | ---- |
| English | `en` |
| Hindi | `hi` |
| Bengali | `bn` |
| Assamese | `as` |
| French | `fr` |
| Gujarati | `gu` |
| Indonesian | `id` |
| Kannada | `kn` |
| Malay | `ms` |
| Malayalam | `ml` |
| Marathi | `mr` |
| Odia | `od` |
| Punjabi | `pa` |
| Spanish | `es` |
| Tamil | `ta` |
| Telugu | `te` |
| Urdu | `ur` |
| Dutch | `nl` |
For agents that handle multiple languages in a single call, see the [Multilingual Support](/docs/customizations/multilingual-languages-support) guide.
***
## Speech-to-Text
Controls how your agent converts the caller's spoken words into text before the LLM processes them. For multilingual agents, each language can have its own STT provider and model. Select a language tab to configure its transcription settings independently.
Different languages may perform better with different providers. For example, use **Sarvam** for Hindi and **Deepgram** for English.
### Provider and Model
Choose a transcription provider from the **Provider** dropdown, then pick the specific model from the **Model** dropdown.
| Provider | What it offers |
| -------------- | -------------------------------------------------------------- |
| **AssemblyAI** | Real-time transcription with strong punctuation and formatting |
| **Azure** | Microsoft Azure Speech Services |
| **Deepgram** | High-accuracy, low-latency transcription with keyword boosting |
| **ElevenLabs** | Transcription powered by ElevenLabs |
| **Gladia** | Multilingual transcription service |
| **Google** | Google Cloud Speech-to-Text |
| **OpenAI** | OpenAI Whisper-based transcription |
| **Sarvam** | Optimized for Indian languages like Hindi, Tamil, and Telugu |
| **Smallest** | Lightweight, fast transcription provider |
### Keywords
Boost recognition accuracy for specific words the transcriber might miss, such as brand names, product names, or technical terms. Enter keywords in the format `word:boost_value` (e.g., `Bruce:100`).
Keyword boosting is **only available with Deepgram**. The Keywords field has no effect when using other providers.
***
## Text-to-Speech
Controls how your agent sounds when speaking to the caller. For multilingual agents, each language can have its own TTS provider, model, and voice. Select a language tab to configure voice settings independently.
### Provider, Model, and Voice
Choose from **AzureTTS**, **Cartesia**, **ElevenLabs**, or **Sarvam**.
Select the model that fits your latency and quality needs (e.g., ElevenLabs `eleven_turbo_v2_5` for low latency).
Click the **Voice** dropdown to browse all voices for the selected provider and model.
### Browsing Voices
Click the Voice dropdown to see a searchable list of all available voices. Filter by gender using the **All**, **Male**, **Female**, and **Neutral** tabs. Each voice shows a **play button** so you can preview it before selecting.
### Preview Welcome Message
Click **Preview welcome message** to hear the selected voice speak your agent's welcome prompt (configured in the [Agent Tab](/docs/agent-setup/agent-tab)). This lets you test how the voice sounds before going live.
### Voice Tuning Parameters
Fine-tune your agent's voice using the sliders below the voice selector. Available parameters may vary by provider.
| Parameter | What it controls |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Buffer Size** | Audio buffered before playback begins. Higher values produce smoother audio but increase delay. Values between 150 and 250 work well for real-time conversations. |
| **Speed Rate** | Speaking speed. `1` is natural pace, above `1` is faster, below `1` is slower. |
| **Similarity Boost** | How closely the output matches the original voice sample. Higher values are more faithful but may reduce naturalness. |
| **Stability** | Voice consistency across sentences. Higher values keep tone steady, lower values add expressive variation. |
| **Style Exaggeration** | Emphasis on stylistic characteristics. `0` is neutral, higher values add more personality. |
High **Buffer Size** improves quality but adds latency. If callers notice a delay before the agent speaks, lower this value.
***
## Adding and Cloning Voices
Click the **Add Voice +** button in the Text-to-Speech section to add a custom voice by ID or clone one from an audio sample.
Custom voice uploads are **only available for ElevenLabs and Cartesia**.
### Add a Voice by ID
Use this when you already have a voice ID from your provider's voice library.
Make sure the **Add by ID** tab is selected in the dialog.
Select **ElevenLabs** or **Cartesia**.
Paste the voice ID from your provider. For ElevenLabs, find IDs in the [ElevenLabs voice library](https://elevenlabs.io/voice-library).
The voice will appear in the Voice dropdown for all your agents.
### Clone a Voice
Create a new voice by uploading an audio recording. Useful for maintaining a consistent brand voice or using a specific person's voice (with their permission).
Switch to the **Clone Voice** tab in the dialog.
Select **ElevenLabs** or **Cartesia**.
Add a **Voice name** (e.g., "Sales Assistant Voice") and **Description** (e.g., "Warm male Indian accent").
Choose the language of your audio sample.
Drag and drop your audio file or click **click to browse**. Audio files only, maximum 10 MB.
The platform processes your sample and adds the new voice to the Voice dropdown.
### Supported Languages for Voice Cloning
Both ElevenLabs and Cartesia support the same set of languages for cloning:
| Language | Code | Language | Code |
| ------------------- | ---- | ---------- | ---- |
| English | `en` | Hindi | `hi` |
| Bengali | `bn` | Assamese | `as` |
| Dutch | `nl` | French | `fr` |
| Gujarati | `gu` | Indonesian | `id` |
| Kannada | `kn` | Malay | `ms` |
| Malayalam | `ml` | Marathi | `mr` |
| Odia | `od` | Punjabi | `pa` |
| Spanish | `es` | Tamil | `ta` |
| Telugu | `te` | Urdu | `ur` |
| Indian Multilingual | - | | |
For best results, use a clean recording with no background noise, a single speaker, and at least 30 seconds of continuous speech.
***
## Next Steps
Configure interruption handling, endpointing, and latency
Set up agents that speak multiple languages in a single call
Create a custom voice from an audio sample
Explore Deepgram transcription models and keyword boosting
# Agent Conversations, Metrics & Logs
Source: https://www.bolna.ai/docs/agent-setup/call-history
Access Voice AI agent conversations, recordings, transcripts, and execution data. Monitor performance metrics, debug with logs, and export data for analysis.
## What is Call History?
Call History (Agent Conversations) displays all historical conversations with your agents. View performance metrics, listen to recordings, read transcripts, and access raw execution data for debugging and analysis.
***
## How to Access Call History
Click **Call History** in the left navigation menu.
Click **See all call logs** in the actions panel.
***
## Performance Metrics
The top section displays **real-time metrics** for your selected agent and date range. Use these to monitor campaign performance at a glance.
| Metric | Description |
| -------------------- | ---------------------------------------------- |
| **Total Executions** | Total number of call attempts |
| **Total Cost** | Total campaign spend |
| **Total Duration** | Total call time in seconds |
| **Status Breakdown** | Count of Error, Completed, and No-Answer calls |
| **Avg Cost** | Average cost per call |
| **Avg Duration** | Average call length |
***
## Filtering Calls
| Filter | Description |
| -------------- | ----------------------------------------- |
| **Agent** | Select a specific agent to view its calls |
| **Batch** | Filter by batch campaign |
| **Date Range** | Choose a date range for the calls |
| **Group By** | Group calls by different criteria |
| **Call Type** | Filter by inbound or outbound calls |
| **Status** | Filter by Completed, Error, or No-Answer |
| **Provider** | Filter by telephony provider |
Use the **search by execution ID** box to quickly find a specific call.
***
## Call Table
Each call is displayed with the following information:
| Column | Description |
| --------------------- | --------------------------------------------------- |
| **Execution ID** | Unique identifier for the call |
| **User Number** | Phone number of the caller/recipient |
| **Conversation Type** | Type of call (plivo outbound, twilio inbound, etc.) |
| **Duration (s)** | Call duration in seconds |
| **Hangup By** | Who ended the call (Callee, Carrier, Plivo, etc.) |
| **Batch** | Batch campaign if applicable |
| **Timestamp** | When the call occurred |
| **Cost** | Cost of the call |
| **Status** | Call status (Completed, No-answer, Error) |
***
## Call Details
Click **Recordings, transcripts, etc** to view the full conversation data.
| Section | Description |
| -------------- | ----------------------------------------------------- |
| **Recording** | Audio waveform with play, copy, and download options |
| **Transcript** | Full conversation showing Assistant and User messages |
Use the copy button to quickly copy the recording URL or transcript text.
Click the **Trace Data** icon to view detailed execution logs for debugging.
| Column | Description |
| ------------- | ---------------------------------------------------------- |
| **Timestamp** | Exact time of each log entry |
| **Log Data** | The actual request or response content |
| **Direction** | Whether it's a request or response |
| **Component** | Which component handled it (synthesizer, transcriber, llm) |
| **Provider** | Provider used (elevenlabs, deepgram, azure, etc.) |
When you fetch logs via the [Get execution raw logs API](/docs/api-reference/executions/get_execution_raw_logs), LLM assistant responses may also include **`reasoning_content`** (model thinking or reasoning summary) when the provider returns it.
**Trace data is essential for debugging!** Use it to identify latency issues, transcription errors, or unexpected LLM responses.
Click **Download logs** to export all trace data for detailed analysis.
Click the **Raw Data** icon to view the complete JSON execution data.
The raw data format matches the [Get Execution API](/docs/api-reference/executions/get_execution) response, making it easy to integrate with your systems programmatically.
***
## Quick Actions
| Action | Description |
| --------------------- | --------------------------------- |
| **Refresh** | Reload the call list |
| **Stop Queued Calls** | Cancel pending calls in the queue |
| **Download Records** | Export call data as CSV |
Export call data as CSV for analysis in spreadsheet tools or to share with your team.
***
## Next Steps
Configure webhooks and post-call tasks
Access call data programmatically
Configure your agent settings
Set up automated calling campaigns
# Configure Telephony, Noise, and Call Timing for Voice AI
Source: https://www.bolna.ai/docs/agent-setup/call-tab
Set up telephony providers like Plivo and Twilio, enable noise cancellation, voicemail detection, DTMF keypad input, ambient noise, and outbound call timing restrictions in the Bolna Call Tab.
## What is the Call Tab?
The Call Tab is where you configure how your agent handles phone calls. Set up your telephony provider, enable call features like noise cancellation and voicemail detection, and manage call timing and hangup behavior.
***
## Configuration Options
### Telephony Provider & Call Features
Configure your telephony provider and toggle powerful call capabilities.
Filter background noise for clearer calls (adjustable intensity)
Detect voicemail systems to avoid awkward messages
Accept touch-tone input for IVR-style menus
Automatically retry failed calls later
Connect your own telephony provider in [Providers](/docs/getting-started/providers) for more control and cost savings.
***
### Ambient Noise
Add background ambient noise to your calls for a more natural, human-like experience. Ambient noise is available for **Plivo** and **Vobiz** telephony providers.
Bolna supports both **preset** and **custom** ambient noise tracks. Select a preset or upload your own custom track to use as background noise during calls.
#### Preset Tracks
Three preset tracks are available to all users out of the box:
| Track | Description |
| ------------------- | ---------------------------------------------- |
| **Coffee Shop** | Background sounds of a coffee shop environment |
| **Office Ambience** | Subtle office background noise |
| **Call Center** | Call center ambient sounds |
Set ambient noise to **None** to disable it (default).
#### Custom Tracks
You can upload your own custom ambient noise tracks for a personalized experience:
* **Supported formats**: `wav`, `mp3`
* **Maximum file size**: 10 MB
* You can upload, list, and delete your custom tracks from the dashboard or via the API
* Custom tracks are private to your account, while presets are available to everyone
Ambient noise is only supported with **Plivo** and **Vobiz** telephony providers.
***
### Final Call Message
Configure the last message your agent says before disconnecting.
Choose the language for your final message (supports multi-language).
Enter a warm, professional closing (e.g., "Thank you for your time. Goodbye!")
Click **+ Add** to include final messages in other languages.
A warm, professional final message leaves a positive lasting impression on callers.
***
### Call Management
Configure how and when calls should end.
| Setting | Description | Recommended |
| -------------------------- | -------------------------------------- | ------------------------------------------ |
| **Hangup on User Silence** | Auto-hangup after X seconds of silence | 6-10 seconds |
| **Total Call Timeout** | Maximum call duration in seconds | 300s (5 min) for support, higher for sales |
**Set reasonable timeouts** to manage costs and prevent stuck calls. Very long calls can indicate issues or abandoned calls.
***
### Outbound Call Timing Restrictions
Restrict outbound calls to a specific time window. This is **off by default**. Toggle it on to set an allowed calling window.
| Field | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **Allowed Time Window** | Set a start and end time (e.g., 9:00 AM to 9:00 PM). Calls outside this window are automatically rescheduled to the next allowed time. |
The time window is validated against the **recipient's local timezone**, detected automatically from their phone number. For example, a 9 AM start means 9 AM in the recipient's timezone, not yours.
Many regions have laws restricting when you can make outbound calls. Enable timing restrictions to stay compliant with local regulations.
You can also configure call timing restrictions via the API and bypass them for urgent calls. See the full [Calling Guardrails](/docs/guides/outbound/calling-guardrails) guide for details.
***
## Next Steps
Set allowed hours, bypass rules, and compliance
Configure latency and interruptions
Add function tools and APIs
Connect Twilio, Plivo, or Exotel
# Import agents
Source: https://www.bolna.ai/docs/agent-setup/copy-import-agent
Import Bolna Voice AI agent templates for instant deployment. Clone & customize pre-built conversational workflows for support, lead gen, booking & more.
# Configure Voice AI Latency and Interruptions
Source: https://www.bolna.ai/docs/agent-setup/engine-tab
Fine-tune your Bolna Voice AI agent's performance. Configure transcription accuracy, interruption thresholds, response latency, and user detection.
## What is the Engine Tab?
The Engine Tab controls the core performance settings of your voice AI agent. Fine-tune transcription accuracy, interruption behavior, response timing, and user presence detection for optimal conversation quality.
***
## Configuration Options
### Transcription & Interruptions
Control how speech is captured and processed during conversations.
Enable for higher accuracy transcription. Essential for compliance and call analytics.
Number of words to wait before considering user input as an interruption.
**Stopwords like "Stop", "Wait", "Hold On"** will always pause the agent immediately, regardless of the interruption threshold.
***
### Response Latency
Configure how quickly your agent responds to user input.
| Setting | Description | Impact |
| --------------------- | ------------------------------------ | ----------------------------------- |
| **Response Rate** | Choose preset or Custom | Balanced, Fast, or Custom timing |
| **Endpointing (ms)** | Wait time before generating response | Lower = faster but may cut off user |
| **Linear Delay (ms)** | Accounts for mid-sentence pauses | Prevents premature responses |
**Lower latency isn't always better!** Setting values too low may cause the agent to interrupt users mid-sentence. Start with defaults and adjust based on testing.
For **natural conversations**, use Endpointing around 200-300ms and Linear Delay around 400-500ms.
***
### User Online Detection
Detect when users go silent and automatically re-engage them.
Toggle **User Online Detection** to check if the user is still on the call.
Customize the prompt (e.g., "Hey, are you still there?") with multi-language support.
Set **Invoke message after (seconds)** to control when the check triggers.
Set the timer between **8-15 seconds** to give users enough time to respond without seeming impatient.
***
## Best Practices
Use default settings initially and adjust based on real call feedback
Make test calls to experience the timing and interruption handling
Customer support may need longer pauses; sales may prefer faster responses
Review call recordings to identify timing issues
***
## Next Steps
Configure telephony and call features
Set up voice and transcription providers
Configure language model settings
Review call logs and recordings
# Set Up Inbound Calls & Caller Matching
Source: https://www.bolna.ai/docs/agent-setup/inbound-tab
Configure inbound call settings for Bolna Voice AI. Match callers using CSV, Google Sheets, or API. Set up spam prevention and preload customer data.
## What is the Inbound Tab?
The Inbound Tab is where you configure settings for receiving incoming calls. Match callers to your database, preload user data before the call starts, and set up spam prevention to protect your agents from abuse.
***
## Database for Inbound Phone Numbers
Match incoming calls to users and preload their data before the call starts. Choose from three data source options:
Connect your own API to fetch user data dynamically when a call comes in.
Choose **"Use your internal APIs"** from the dropdown.
Provide your API endpoint that will receive the caller data request.
Enter your Bearer token for secure authentication.
### Query Parameters
Bolna automatically passes these parameters to your API:
| Parameter | Description |
| ---------------- | ------------------------------- |
| `contact_number` | The caller's phone number |
| `agent_id` | Your agent's identifier |
| `execution_id` | Unique identifier for this call |
**Your API must return a JSON response** with user details. Bolna will inject this data directly into your agent's prompt for personalized conversations.
### Example API Request
```bash theme={"system"}
curl -X GET "https://your-api.com/user-data?contact_number=+919876543210&agent_id=abc123&execution_id=xyz789" \
-H "Authorization: Bearer YOUR_AUTH_TOKEN" \
-H "Content-Type: application/json"
```
### Example API Response
```json theme={"system"}
{
"user_name": "John Doe",
"account_status": "premium",
"last_purchase": "2026-01-15"
}
```
Authentication uses Bearer token and is stored securely by Bolna.
Upload a CSV file containing your user database.
Choose **"Use a CSV"** from the dropdown.
Click **Upload CSV File** and select your file.
The CSV file **must include a `contact_number` column** containing phone numbers. These numbers will be matched against the caller's phone number.
### CSV Format Example
```csv theme={"system"}
contact_number,user_name,account_type
+919876543210,John Doe,premium
+918765432109,Jane Smith,basic
```
Connect a public Google Sheet as your user database.
Choose **"Use a public Google Sheet"** from the dropdown.
Paste the URL of your public Google Sheet.
Specify the exact name of the sheet tab to use.
The sheet **must be public** and should include a `contact_number` column containing phone numbers.
***
## Call Restrictions
Toggle on **"Allow Calls Only from Database"** to restrict incoming calls to only phone numbers found in your chosen database. Unknown callers will be rejected.
***
## Spam Prevention Settings
Protect your agent from spam and abuse.
| Setting | Description |
| ---------------------------------- | ------------------------------------------------------------ |
| **Maximum Calls per Phone Number** | Limit calls from a single number. Set to `-1` for unlimited. |
| **Always-Allow List** | Phone numbers that bypass all call limits. |
Add your support team and VIP customers to the Always-Allow List to ensure they're never blocked.
***
## Use Cases
Only allow calls from registered customers
Preload customer data for personalized service
Limit repeated calls from the same number
Fetch real-time customer data via API
***
## Next Steps
Configure prompts and welcome message
Set up telephony and call management
Complete inbound setup guide
Purchase and manage phone numbers
# Choose and Configure LLM Models for Voice AI
Source: https://www.bolna.ai/docs/agent-setup/llm-tab
Select and configure the language model for your Bolna Voice AI agent. Choose from OpenAI, Azure, Anthropic, and connect knowledge bases.
## What is the LLM Tab?
The LLM Tab is where you select and configure the intelligence behind your voice AI agent. Choose your language model provider, adjust response parameters, and connect knowledge bases for enhanced conversations.
***
## Configuration Options
### Choose LLM Model
Select your AI provider and model for conversation intelligence.
Choose from Azure, OpenAI, Anthropic, Groq, and more
Pick the specific model (e.g., `gpt-4.1-mini cluster`)
Connect your own provider keys in [Providers](/docs/getting-started/providers) to reduce costs and access more models.
***
### Model Parameters
Fine-tune how your agent generates responses.
| Parameter | Description | Recommended |
| -------------------- | ----------------------------------------------------------------------------- | ---------------------------------- |
| **Tokens Generated** | Max tokens per LLM output | 300-500 for concise responses |
| **Temperature** | Controls creativity/randomness | 0.3-0.5 for balanced responses |
| **Reasoning effort** | How much the model reasons before answering. Shown for models that support it | Lowest available setting for voice |
**Keep temperature low** (0.3-0.5) if you want consistent, controlled responses. Higher temperature increases creativity but may cause deviation from your prompt instructions.
GPT-5 models are the exception: they accept only `1`, so the temperature control has no effect on them. Constrain those agents through the prompt instead.
On GPT-5 models, reasoning tokens are drawn from the same budget as **Tokens Generated**, so raise the cap whenever you raise reasoning effort. The effort control lists only the values the selected model accepts, and the options change when you switch models. See [OpenAI](/docs/providers/llm-model/openai#reasoning-effort) for the per-model values.
***
### Add Knowledge Base
Connect your knowledge bases to give your agent accurate, contextual information.
Open the **"Select knowledge bases"** multi-select dropdown.
Check one or more knowledge bases (PDFs, URLs) to connect.
Click **"Add new knowledgebase"** to create and upload new content.
Knowledge bases enable your agent to answer questions with accurate, up-to-date information from your documents and URLs. Connect multiple knowledge bases for comprehensive coverage.
Create knowledge bases in the [Knowledge Base](/docs/getting-started/knowledge-base) section by uploading PDFs or adding URLs.
***
## Next Steps
Create and manage knowledge bases
Configure prompts and welcome message
Set up voice, transcription, and languages
Connect your own LLM provider
# Configure Voice AI Agents in Bolna
Source: https://www.bolna.ai/docs/agent-setup/overview
Complete guide to configuring Bolna Voice AI agents. Customize prompts, test conversations, and deploy agents for inbound and outbound calls.
## What is Agent Setup?
Agent Setup is where you configure and fine-tune your Voice AI agents. Access it from the [Bolna Platform](https://platform.bolna.ai/) after creating or selecting an agent.
***
## Your Agents Sidebar
The left sidebar shows all your agents and provides quick access to create or import agents.
| Action | Description |
| --------------- | ------------------------------------------------------------------------------------------ |
| **+ New Agent** | Create a new agent using Auto Build, Pre-built templates, or from scratch |
| **Import** | Import an existing agent configuration using an [agent ID](/docs/agent-setup/copy-import-agent) |
| **Search** | Quickly find agents by name |
| **Agent List** | Click any agent to open its configuration |
New agents are created in **draft** status until you save them.
***
## Agent Header
The header bar displays key information and quick actions for your selected agent.
| Element | Description |
| ------------------- | -------------------------------------------------------- |
| **Agent Name** | Your agent's display name |
| **Agent ID** | Copy for API integrations |
| **Share** | Generate a shareable link for team collaboration |
| **Cost per min** | Estimated cost breakdown per minute |
| **Routing** | Active routing region (e.g., India routing) |
| **Provider Status** | Status indicators for Transcriber, LLM, Voice, Telephony |
Receive a test call on your phone number
Configure this agent for inbound calls
***
## Configuration Tabs
Configure every aspect of your agent using the **8 specialized tabs**.
Prompts & welcome message
Model & knowledge base
Voice & transcription
Latency & interruptions
Telephony & voicemail
Functions & APIs
Webhooks & extraction
Caller matching
***
## Testing & Saving
Test your agent before deploying and save your changes.
### Testing Options
| Method | Description | Best For |
| ----------------------- | ------------------------------------- | ------------------------------------ |
| **Chat with agent** | Text-based conversation testing | Quick prompt iteration and debugging |
| **Get call from agent** | Receive a test call on your phone | Real-world voice experience |
| **Test via browser** | Make calls directly from your browser | Testing without using phone minutes |
**Pro tip:** Use "Chat with agent" for quick iterations, then validate with a real phone call before deploying!
### Save & Manage
| Action | Description |
| --------------------- | --------------------------------------------------------------------------- |
| **Save agent** | Save your configuration — changes only take effect after saving! |
| **See all call logs** | View [call history](/docs/agent-setup/call-history), recordings, and transcripts |
| **Delete** | Remove the agent (use with caution) |
**Remember to save!** Your changes won't apply until you click **Save agent**.
***
## Quick Links
Step-by-step guide to creating your first agent
Import existing agent configurations
Purchase phone numbers for inbound calls
View call logs, recordings, and transcripts
***
## Next Steps
Configure prompts and welcome message
Choose your language model and knowledge base
Set up voice and transcription
Upload documents for context-aware responses
# Connect Function Tools and API Integrations
Source: https://www.bolna.ai/docs/agent-setup/tools-tab
Add built-in function tools and custom API integrations to your Bolna Voice AI agent. Enable calendar booking, call transfers, and connect any external API endpoint.
The Tools Tab is where you connect external tools and APIs that your agent's LLM can call during live conversations. This lets your agent take real-time actions like booking appointments, transferring calls, or fetching data from your own backend.
***
## Built-in Tools
Bolna provides ready-to-use tools for common voice agent workflows. Click **+ Add** next to any tool to enable it for your agent.
Check open meeting slots from Cal.com in real-time during a call
Create calendar bookings directly via Cal.com during the conversation
Route the call to a human agent or another phone number — with an optional [pre-call webhook](/docs/tool-calling/transfer-calls#pre-call-webhook)
Connect any external API endpoint with a custom function schema
***
## Custom Functions
For integrations beyond the built-in tools, use **Custom Functions** to connect any API endpoint. You can create a custom function in two ways:
### Write Manually
Click **Write manually** to open a JSON editor where you define the function schema from scratch. This gives you full control over the function name, description, parameters, and API configuration.
The fields `name`, `description`, `key`, and `method` are mandatory. The `key` must always be set to `"custom_task"`. Do not change this value.
### Generate from cURL
Click **Generate from cURL** to paste an existing cURL command. Bolna will parse the request and auto-generate a function schema that you can review and edit before adding it to your agent.
After clicking **Generate function**, Bolna parses the cURL and produces a ready-to-edit function configuration:
The cURL import is a starting point. Always review the generated function name, description, and parameters before submitting. See the [Custom Functions guide](/docs/tool-calling/custom-function-calls#generate-from-curl) for a detailed walkthrough.
### Pre-call Webhook (optional)
Each custom tool also has two optional inputs to fire a [pre-call webhook](/docs/tool-calling/custom-function-calls#pre-call-webhooks) *before* the tool's main API call runs:
* **Pre-call webhook URL** — the endpoint to notify. If left blank, the agent-level Webhook URL is used.
* **Pre-call webhook parameters** — the JSON body template, with `%(field)s` substitution for the tool's arguments. Leaving this empty disables the pre-call webhook.
Both save with the tool and round-trip on edit.
The built-in [Transfer Call](/docs/tool-calling/transfer-calls#pre-call-webhook) tool supports the same pre-call webhook fields via a **Send a pre-call webhook before transfer** toggle in its configuration modal.
***
## Managing Added Tools
Once you add a tool, it appears as a configurable card in the Tools Tab.
| Action | How to do it |
| ------------- | ------------------------------------------------------------- |
| **Configure** | Click the tool card to edit its parameters and API connection |
| **Delete** | Click the delete icon on the tool card to remove it |
***
## Next Steps
Full schema reference, examples, and best practices
Set up call routing to human agents
Configure webhooks and post-call extractions
Pass dynamic data into your function tools
# Agents Library
Source: https://www.bolna.ai/docs/agents-library
Browse and import pre-built Voice AI agent templates. Deploy production-ready agents for support, sales, scheduling, and more in minutes.
## What is the Agents Library?
The Bolna Agents Library provides **ready-to-use Voice AI agent templates** that you can import and customize for your specific use case. Each template comes pre-configured with optimized prompts, workflows, and settings, allowing you to deploy production-ready agents in minutes.
Browse agents by industry below and click **Import this agent** to add it to your account.
Adjust the prompts, [context variables](/docs/guides/prompting/using-context), and settings in the [Agent Setup](/docs/agent-setup/agent-tab) to match your needs.
Test using the Playground chat or by [making test calls](/docs/guides/outbound/making-outgoing-calls).
Go live for [inbound](/docs/guides/inbound/receiving-incoming-calls) or [outbound](/docs/guides/outbound/making-outgoing-calls) calling.
Every agent below works in **English + Hindi** and can be imported with one click.
***
## Pre-built Agent Templates
Provides 24/7 inbound call answering for FAQs, order tracking, and customer triage.
**Industry:** E-Commerce
**Languages:** English + Hindi
**Call to test:** [+918035317400](tel:+918035317400)
Import this agent →
Calls customers with abandoned carts to recover lost sales through personalized outreach.
**Industry:** E-Commerce
**Languages:** English + Hindi
**Call to test:** [+918035317449](tel:+918035317449)
Import this agent →
Handles last-mile logistics tasks like cash-on-delivery confirmation and delivery scheduling.
**Industry:** E-Commerce
**Languages:** English + Hindi
**Call to test:** [+918035317450](tel:+918035317450)
Import this agent →
Keeps users engaged with feature upgrades, product launches, and important updates.
**Industry:** BFSI\
**Languages:** English + Hindi
**Call to test:** [+918035317403](tel:+918035317403)
Import this agent →
Automates reminders for EMIs, collections, form-filling deadlines, and payment follow-ups.
**Industry:** BFSI\
**Languages:** English + Hindi
**Call to test:** [+918035317402](tel:+918035317402)
Import this agent →
Helps fintech companies sell credit cards through intelligent Hindi conversations.
**Industry:** BFSI\
**Languages:** English
Import this agent →
Helps fintech companies sell loans through intelligent Hindi conversations and financial expertise.
**Industry:** BFSI\
**Languages:** English
Import this agent →
Answers every call to handle clinic, hotel, and office scheduling automatically.
**Industry:** Hospitality
**Languages:** English + Hindi
**Call to test:** [+918035317405](tel:+918035317405)
Import this agent →
Conducts automated NPS, feedback, and product surveys with detailed personalized questioning.
**Industry:** Hospitality
**Languages:** English + Hindi
**Call to test:** [+918035317408](tel:+918035317408)
Import this agent →
Schedules salon appointments and collects client information for beauty businesses.
**Industry:** Hospitality
**Languages:** English
Import this agent →
Screens, interviews, and onboards candidates at scale with intelligent voice conversations.
**Industry:** Recruitment
**Languages:** English + Hindi
**Call to test:** [+918035317441](tel:+918035317441)
Import this agent →
Calls every lead to ask qualifying questions, answer FAQs, and warmly introduce the business.
**Industry:** Ed Tech
**Languages:** English + Hindi
**Call to test:** [+918035317443](tel:+918035317443)
Import this agent →
Conducts personalized guidance calls to warmly onboard users into health tech platforms.
**Industry:** Health Tech
**Languages:** English + Hindi
**Call to test:** [+918035317448](tel:+918035317448)
Import this agent →
Qualifies property leads (owner or broker) and collects detailed property information.
**Industry:** Real Estate
**Languages:** English
Import this agent →
Helps users plan weekends and vacations with personalized travel and leisure recommendations.
**Industry:** Real Estate
**Languages:** English
Import this agent →
***
## Quick Reference
| Agent | Industry | Languages | Import |
| ------------------- | ----------- | --------------- | ------------------------------------------------------------------- |
| Customer Support | E-Commerce | English + Hindi | [Import →](https://bolna.ai/a/4f0d937f-3d07-479b-9352-9f3271285d8a) |
| Cart Abandonment | E-Commerce | English + Hindi | [Import →](https://bolna.ai/a/57ad261e-2bbc-4fb4-aefd-74b92ed1bed5) |
| COD Confirmation | E-Commerce | English + Hindi | [Import →](https://bolna.ai/a/42a04bee-a4e9-442c-bf85-c6e6064ad976) |
| Recruitment Agent | Recruitment | English + Hindi | [Import →](https://bolna.ai/a/9a2faf53-00b8-4213-8f8c-cad6011d9f9b) |
| Lead Qualification | Ed Tech | English + Hindi | [Import →](https://bolna.ai/a/a8ff62ed-a86e-4881-80cd-5593d1391afb) |
| Onboarding Agent | Health Tech | English + Hindi | [Import →](https://bolna.ai/a/3f5b1997-17cc-4a14-9e02-a90ba0dfeb5c) |
| Announcements Agent | BFSI | English + Hindi | [Import →](https://bolna.ai/a/09344ad0-0991-440b-89ff-51ba4fe7d7b1) |
| Reminders Agent | BFSI | English + Hindi | [Import →](https://bolna.ai/a/88bb2f3c-cfc0-4f3d-b0a2-6ac962ba9737) |
| Front Desk Agent | Hospitality | English + Hindi | [Import →](https://bolna.ai/a/98183718-4bb6-457f-8e0f-9c0fa322bbba) |
| Surveys Agent | Hospitality | English + Hindi | [Import →](https://bolna.ai/a/e3f31313-c28c-452e-9026-70edd7042691) |
| Salon Booking Agent | Hospitality | English | [Import →](https://bolna.ai/a/547e8f2d-d231-4fc6-a9f1-b90801d672b8) |
| Property Tech Agent | Real Estate | English | [Import →](https://bolna.ai/a/d3dbc421-b964-4c12-8afa-e087e440cb3e) |
| Weekend Planner | Real Estate | English | [Import →](https://bolna.ai/a/00b05a0f-d451-4afe-b55f-7e2a3fa4896d) |
| Sales - Credit Card | BFSI | English | [Import →](https://bolna.ai/a/68762ade-7e39-4b06-96e6-0d98863fbd0b) |
| Sales - Loans | BFSI | English | [Import →](https://bolna.ai/a/29780b7b-876e-40a6-96bd-069b8409dedb) |
***
## Next Steps
Build a custom agent from scratch
Import or duplicate existing agents
Configure prompts, voice, and tools
# Create Voice AI Agent API (deprecated)
Source: https://www.bolna.ai/docs/api-reference/agent/create
POST /agent
Learn how to create new agents with Bolna APIs, enabling customized tasks, prompts, and configurations for Bolna voice AI agents.
These APIs have now been deprecated.
Please use the latest [**v2 APIs**](/docs/api-reference/agent/v2/overview).
# Retrieve Voice AI Agent Details API (deprecated)
Source: https://www.bolna.ai/docs/api-reference/agent/get
GET /agent/{agent_id}
Retrieve detailed Voice AI agent information, including configuration, status, and tasks, using Bolna APIs.
These APIs have now been deprecated.
Please use the latest [**v2 APIs**](/docs/api-reference/agent/v2/overview).
# List all Voice AI Agents API (deprecated)
Source: https://www.bolna.ai/docs/api-reference/agent/get_all
GET /agent/all
List all Voice AI agents under your account, along with their names, statuses, and creation dates, using Bolna APIs.
These APIs have now been deprecated.
Please use the latest [**v2 APIs**](/docs/api-reference/agent/v2/overview).
# Get All Voice AI Agent Executions API
Source: https://www.bolna.ai/docs/api-reference/agent/get_all_agent_executions
GET /agent/{agent_id}/executions
Access all execution records for a specific agent, providing insights into performance and past interactions with Bolna APIs.
# Bolna Voice AI Agent APIs Overview (deprecated)
Source: https://www.bolna.ai/docs/api-reference/agent/overview
Explore Bolna Voice AI Agent APIs overview, featuring endpoints for creating, managing, and executing autonomous voice agents.
These APIs have now been deprecated.
Please use the latest [**v2 APIs**](/docs/api-reference/agent/v2/overview).
## Endpoints
```
POST /agent
GET /agent
PUT /agent/:agent_id
PATCH /agent/:agent_id
GET /agent/all
```
## Agent Object Attributes
### `agent_config`
* `agent_name` *string* **(required)**
Name of the agent
* `agent_welcome_message` *string* **(required)**
Initial agent welcome message. you can pass dynamic values here using variables encloed within `{}`
* `webhook_url` *string* **(required)**
Get real-time details of the call progress and call data on a webhook. All supported events are listed in [Poll call data using webhooks](/docs/guides/post-call/polling-call-status-webhooks)
* `tasks` *array* **(required)**
Definitions and configuration for the agentic tasks
### `agent_prompts`
Prompts to be provided to the agent.
# Patch Update to Voice AI Agent API (deprecated)
Source: https://www.bolna.ai/docs/api-reference/agent/patch_update
PATCH /agent/{agent_id}
Learn how to partially update properties. Update Bolna Voice AI agent name, welcome message, webhook URL, voice settings, and prompts, using this endpoint.
These APIs have now been deprecated.
Please use the latest [**v2 APIs**](/docs/api-reference/agent/v2/overview).
# Update Voice AI Agent API (deprecated)
Source: https://www.bolna.ai/docs/api-reference/agent/update
PUT /agent/{agent_id}
Update agent configurations, tasks, and prompts to refine behavior and capabilities using Bolna Voice AI agent APIs.
These APIs have now been deprecated.
Please use the latest [**v2 APIs**](/docs/api-reference/agent/v2/overview).
# Create Voice AI Agent API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/create
POST /v2/agent
Learn how to create new agents with Bolna APIs, enabling customized tasks, prompts, and configurations for Bolna voice AI agents.
Creates a new voice AI agent. Returns HTTP **201** with `{ "agent_id": "...", "state": "created" }`.
The quickest path is creating an agent in the [dashboard](https://platform.bolna.ai) (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:
```json Minimal request body theme={"system"}
{
"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-5.4-mini",
"max_tokens": 150,
"temperature": 1
}
},
"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."
}
}
}
```
```json 201 Response theme={"system"}
{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"state": "created"
}
```
## Common 400 errors
| Message | Fix |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `agent_config is required` | Wrap your config in `{ "agent_config": { ... } }` |
| `tasks is required` | The `tasks` array must have at least one entry |
| `toolchain.pipelines must be array of arrays` | Use `[["transcriber","llm","synthesizer"]]`, not `["transcriber","llm","synthesizer"]` |
| `For GPT-5 models, temperature must be 1` | Send `"temperature": 1` in `llm_config`. GPT-5-series models accept no other value, and the field defaults to `0.1` when omitted |
| `reasoning_effort '' is not supported for model ''` | Use an effort the model accepts — see the [per-model table](/docs/providers/llm-model/openai#reasoning-effort) |
## Next steps
After creating an agent, place a call with `POST /call` using the returned `agent_id`. See the [API Quickstart](/docs/quickstarts/api) for a complete end-to-end example.
# Delete Voice AI Agent API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/delete
DELETE /v2/agent/{agent_id}
Use Bolna APIs to delete agents and their related data, ensuring proper cleanup of batches, executions, and configurations.
This deletes **ALL** agent data including all batches, all executions, etc.
# Retrieve Voice AI Agent Details API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/get
GET /v2/agent/{agent_id}
Retrieve detailed Voice AI agent information, including configuration, status, and tasks, using Bolna APIs.
# Retrieve Voice AI Agent Execution API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/get_agent_execution
GET /agent/{agent_id}/execution/{execution_id}
Fetch specific execution details of a Voice AI agent, including conversation times, statuses, and metrics, via Bolna APIs.
# List all Voice AI Agents API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/get_all
GET /v2/agent/all
List all Voice AI agents under your account, along with their names, statuses, and creation dates, using Bolna APIs.
# Get All Voice AI Agent Executions API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/get_all_agent_executions
GET /v2/agent/{agent_id}/executions
Access all execution records for a specific agent, providing insights into performance and past interactions with Bolna APIs.
## Pagination
This API supports pagination using the `page_number` and `page_size` query parameters. You can utilize `has_more` in the API response to determine if you should fetch the next page. You can learn more about it from the [pagination documentation](/docs/api-reference/pagination).
## Date filtering
The `from` and `to` query parameters are **required** to filter executions by date.
You can filter executions by their `created_at` timestamp using the `from` and `to` query parameters. The following rules apply:
* Both `from` and `to` are **required** and must be passed **together**.
* The maximum allowed range between `from` and `to` is **7 days**.
* Dates must be in **UTC ISO 8601** format (e.g. `2026-06-07T00:00:00.000Z`).
# Bolna Voice AI Agent APIs Overview
Source: https://www.bolna.ai/docs/api-reference/agent/v2/overview
Explore Bolna Voice AI Agent APIs overview, featuring endpoints for creating, managing, and executing autonomous voice agents.
## Endpoints
```
POST /v2/agent
GET /v2/agent
PUT /v2/agent/:agent_id
GET /v2/agent/all
```
## Agent Object Attributes
### `agent_config`
* `agent_name` *string* **(required)**
Name of the agent
* `agent_welcome_message` *string* **(required)**
Initial agent welcome message. you can pass dynamic values here using variables encloed within `{}`
* `webhook_url` *string* **(required)**
Get real-time details of the call progress and call data on a webhook. All supported events are listed in [Poll call data using webhooks](/docs/guides/post-call/polling-call-status-webhooks)
* `tasks` *array* **(required)**
Definitions and configuration for the agentic tasks
### `agent_prompts`
Prompts to be provided to the agent.
# Patch Update to Voice AI Agent API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/patch_update
PATCH /v2/agent/{agent_id}
Learn how to partially update properties. Update Bolna Voice AI agent name, welcome message, webhook URL, voice settings, calling guardrails, telephony provider, and prompts, using this endpoint.
Partially update an existing agent. Unlike the [full update](/docs/api-reference/agent/v2/update) (`PUT`), which replaces the entire agent configuration, `PATCH` only touches the attributes you include in the request body — everything else is left unchanged.
Returns HTTP **200** with `{ "message": "success", "state": "updated" }`.
Use `PATCH` for small, targeted edits (renaming an agent, swapping a voice, updating a webhook URL). Use [`PUT`](/docs/api-reference/agent/v2/update) when you need to rewrite tasks, toolchains, or the full prompt structure.
## Updatable attributes
Only the following attributes can be updated via `PATCH`. Any other field in the body is ignored.
| Attribute | Location | Description |
| ----------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent_name` | `agent_config` | Display name of the agent. |
| `agent_welcome_message` | `agent_config` | First message the agent speaks when a call connects. |
| `webhook_url` | `agent_config` | URL that receives the [execution payload](/docs/api-reference/executions/get_execution) as call status changes. Whitelist source IP `13.203.39.153`. Pass `null` to remove it. |
| `synthesizer` | `agent_config` | Text-to-speech configuration (provider, voice, model, etc.). |
| `ingest_source_config` | `agent_config` | CRM ingestion source for inbound agents (`api`, `csv`, or `google_sheet`). |
| `telephony_provider` | `agent_config` | Telephony provider. Changing it auto-updates the audio format. |
| `calling_guardrails` | `agent_config` | Time-based restrictions for outbound calls. |
| `agent_prompts` | top-level | Prompts per task, keyed as `task_1`, `task_2`, … |
All agent-config attributes go inside the `agent_config` object. `agent_prompts` is a top-level key, a sibling of `agent_config`.
## calling\_guardrails
Restrict when your agent places outbound calls. Calls triggered outside the allowed window are automatically rescheduled to the next allowed start time in the **recipient's** timezone. It accepts two keys:
| Key | Type | Description |
| ----------------- | -------------- | ------------------------------------------------------------------------------- |
| `call_start_hour` | integer (0–23) | Start of the allowed calling window, 24-hour format. |
| `call_end_hour` | integer (0–23) | End of the allowed calling window, 24-hour format. Must be `≥ call_start_hour`. |
```json Update calling guardrails theme={"system"}
{
"agent_config": {
"calling_guardrails": {
"call_start_hour": 9,
"call_end_hour": 21
}
}
}
```
Hours use 24-hour format: `0` = midnight, `9` = 9 AM, `17` = 5 PM, `21` = 9 PM. See the [Calling Guardrails guide](/docs/guides/outbound/calling-guardrails) for rescheduling behavior and regional calling regulations.
## telephony\_provider
Switch the telephony provider the agent uses. When changed, the agent's audio input/output format is updated automatically to match the provider (`wav` for `twilio`/`plivo`/`exotel`/`vobiz`, `ulaw` for `sip-trunk`).
Accepted values: `twilio`, `plivo`, `exotel`, `vobiz`, `sip-trunk`, `default`.
```json Switch to SIP trunk theme={"system"}
{
"agent_config": {
"telephony_provider": "sip-trunk"
}
}
```
If you patch `telephony_provider` to `sip-trunk`, the next step is to [set the inbound agent](/docs/api-reference/inbound/agent) so your SIP trunk phone number maps to this agent for receiving inbound calls.
## Examples
```json Rename + new welcome message theme={"system"}
{
"agent_config": {
"agent_name": "Support Agent v2",
"agent_welcome_message": "Hi! Thanks for calling. How can I help?"
}
}
```
```json Update webhook URL theme={"system"}
{
"agent_config": {
"webhook_url": "https://your-server.com/bolna-webhook"
}
}
```
```json Change the voice theme={"system"}
{
"agent_config": {
"synthesizer": {
"provider": "elevenlabs",
"provider_config": {
"voice": "Nila",
"voice_id": "V9LCAAi4tTlqe9JadbCo",
"model": "eleven_turbo_v2_5"
},
"stream": true,
"buffer_size": 250,
"audio_format": "wav"
}
}
}
```
```json Update a task prompt theme={"system"}
{
"agent_prompts": {
"task_1": {
"system_prompt": "You are a helpful support agent. Keep replies short."
}
}
}
```
You can also combine multiple attributes in a single request:
```json Combined patch theme={"system"}
{
"agent_config": {
"agent_name": "Sales Agent",
"webhook_url": "https://your-server.com/bolna-webhook",
"telephony_provider": "plivo",
"calling_guardrails": {
"call_start_hour": 9,
"call_end_hour": 21
}
},
"agent_prompts": {
"task_1": {
"system_prompt": "You are an outbound sales agent. Be concise and friendly."
}
}
}
```
```json 200 Response theme={"system"}
{
"message": "success",
"state": "updated"
}
```
## Next steps
Replace the entire agent configuration, tasks, and prompts.
Control outbound call timing and rescheduling.
Map a phone number to an agent for inbound calls.
Receive call results without polling.
# Stop Agent Queued Calls API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/stop
POST /v2/agent/{agent_id}/stop
Use Bolna APIs to stop all queued calls for a specific agent, preventing any pending calls from being executed.
This stops **ALL** the queued calls for a given agent.
This endpoint stops all queued calls for the specified agent. Any calls that are currently in the queue waiting to be executed will be cancelled and will not be processed.
# Update Voice AI Agent API
Source: https://www.bolna.ai/docs/api-reference/agent/v2/update
PUT /v2/agent/{agent_id}
Update agent configurations, tasks, and prompts to refine behavior and capabilities using Bolna Voice AI agent APIs.
# Create Batch API
Source: https://www.bolna.ai/docs/api-reference/batches/create
POST /batches
Discover how to create a batch for Bolna Voice AI agent by uploading a CSV file containing user contact numbers and prompt variable details for users.
Creates a new batch campaign by uploading a CSV of recipients. Returns HTTP **201** with a `batch_id`. The batch does not start calling until you call `POST /batches/{batch_id}/schedule`.
## CSV format
```csv theme={"system"}
contact_number,customer_name,appointment_day
+919876543210,Asha,Friday
+919812345678,Ravi,Monday
```
* `contact_number` is **required** — E.164 format
* Any other column becomes a `{variable}` available in your agent's prompt and welcome message
* The per-call execution stores these columns in `context_details.recipient_data`
## Example request
Use `multipart/form-data` — **not** JSON.
```bash curl theme={"system"}
curl https://api.bolna.ai/batches \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-F "agent_id=123e4567-e89b-12d3-a456-426655440000" \
-F "file=@recipients.csv"
```
```python Python (stdlib) theme={"system"}
import os, urllib.request
from io import BytesIO
# See public/examples/bolna_batch_test.py for a complete implementation
```
```json 201 Response theme={"system"}
{
"batch_id": "3c90c3cc0d444b5088888dd25736052a",
"state": "created"
}
```
## Next step: schedule the batch
A created batch is idle until scheduled. Call `POST /batches/{batch_id}/schedule` with a `scheduled_at` timestamp:
```json Schedule request (form-data) theme={"system"}
scheduled_at=2026-06-23T18:30:00+00:00
```
Use a **numeric UTC offset** like `+00:00` — the `Z` suffix is rejected with a 500. The time must be at least 2 minutes in the future, and Bolna rounds the start up to the next 10-minute mark.
See the [Batch Quickstart](/docs/quickstarts/batch) for a complete walk-through including scheduling and result retrieval.
# Delete Batch API
Source: https://www.bolna.ai/docs/api-reference/batches/delete
DELETE /batches/{batch_id}
Understand how to delete a specific batch using its ID, effectively removing it from your scheduled or active batches.
# List Batch Executions API
Source: https://www.bolna.ai/docs/api-reference/batches/executions
GET /batches/{batch_id}/executions
Learn how to retrieve all executions from a batch, providing detailed information on each call's outcome and metrics.
# Get Batch API
Source: https://www.bolna.ai/docs/api-reference/batches/get_batch
GET /batches/{batch_id}
Find out how to retrieve details of a specific batch, including its creation time, status, call status and scheduled execution time.
# List All Batches API
Source: https://www.bolna.ai/docs/api-reference/batches/get_batches
GET /batches/{agent_id}/all
Explore how to list all batches associated with a particular Bolna Voice AI agent, providing an overview of their statuses, schedules and other relevant details
# Batch APIs Overview
Source: https://www.bolna.ai/docs/api-reference/batches/overview
Understand how to create and schedule multiple Bolna Voice AI calls together using Bolna Batch APIs for efficient call management.
## Endpoints
```
POST /batches
POST /batches/schedule
POST /batches/:batch_id/stop
GET /batches/:batch_id
GET /batches/:batch_id/executions
GET /batches/:agent_id
DELETE /batches/:batch_id
```
# Schedule Batch API
Source: https://www.bolna.ai/docs/api-reference/batches/schedule
POST /batches/{batch_id}/schedule
Learn how to schedule a batch for calling via Bolna Voice AI agent by specifying the batch ID and the desired execution time.
# Stop Batch API
Source: https://www.bolna.ai/docs/api-reference/batches/stop
POST /batches/{batch_id}/stop
Understand how to stop a running batch using its ID, allowing you to halt ongoing calls in the batch.
# Make Voice AI Call API
Source: https://www.bolna.ai/docs/api-reference/calls/make
POST /call
Learn how to initiate outbound phone calls using Bolna Voice AI agents. Start making phone calls using the agent ID and recipient's phone number.
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.
```json Minimal request theme={"system"}
{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+919876543210"
}
```
```json Response theme={"system"}
{
"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"):
```json Request with personalization theme={"system"}
{
"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](/docs/api-reference/executions/get_execution).
## Common 400 errors
| Message | Fix |
| ------------------------------------ | ------------------------------------------------------- |
| `agent_id is required` | Include a valid UUID `agent_id` |
| `recipient_phone_number is required` | Phone number must be E.164 format, e.g. `+919876543210` |
| Invalid `from_phone_number` | Must be a number purchased in your Bolna account |
# Calling APIs overview
Source: https://www.bolna.ai/docs/api-reference/calls/overview
Explore Bolna Calling APIs to invoke outbound Voice AI phone calls from your agents. This overview provides the available endpoints and their functionalities.
## Endpoints
```
POST /call
```
# Stop a Previously Initiated Voice AI Call API
Source: https://www.bolna.ai/docs/api-reference/calls/stop_call
POST /call/{execution_id}/stop
Learn how to stop a call when its status is `queued` or `scheduled` This API allows you to cancel pending calls before they are executed.
# Bulk Create Dispositions API
Source: https://www.bolna.ai/docs/api-reference/dispositions/bulk-create
POST /dispositions/bulk
Atomically create and link multiple dispositions to an agent in a single request.
Use bulk create when setting up a new agent with a complete set of dispositions, or when importing a disposition configuration from another source. Either all dispositions are created and linked, or none are — partial results are not possible.
# Create Disposition API
Source: https://www.bolna.ai/docs/api-reference/dispositions/create
POST /dispositions/
Create a new disposition and link it to an agent in a single request. `agent_id` is required.
At least one of `is_subjective` or `is_objective` must be `true`. When `is_objective` is `true`, you must provide `objective_options`. See the [ObjectiveOption schema](/docs/api-reference/dispositions/overview#objectiveoption-schema) for the full structure including nested `sub_options`.
# Delete Disposition API
Source: https://www.bolna.ai/docs/api-reference/dispositions/delete
DELETE /dispositions/{disposition_id}
Delete a disposition from your account. Only the owner can delete a disposition.
Deletion is permanent and cannot be undone. Historical call execution results that already contain this disposition's output are not affected — only future calls will stop evaluating it.
### Authorization
* **Regular users** can only delete dispositions they own (`created_by` matches their user ID).
* **Admins** can delete any disposition.
# Get Disposition API
Source: https://www.bolna.ai/docs/api-reference/dispositions/get
GET /dispositions/{disposition_id}
Retrieve a single disposition by ID, optionally scoped to a specific agent.
# List Dispositions API
Source: https://www.bolna.ai/docs/api-reference/dispositions/list
GET /dispositions/
Retrieve all dispositions accessible to your account, optionally scoped to a specific agent.
# Dispositions API Overview
Source: https://www.bolna.ai/docs/api-reference/dispositions/overview
Create and manage dispositions — the individual extraction units that power the Extractions feature in Bolna.
## What are Dispositions?
**Extractions** is the Bolna feature that automatically captures structured data from call transcripts after every call. Each extraction is configured as one or more **dispositions** — individual questions posed to an LLM against the transcript — grouped under named **categories**.
So the hierarchy is:
```
Agent
└── Extractions (feature)
└── Category (e.g. "Lead Quality")
└── Disposition (e.g. "Call Outcome")
```
Each disposition asks a single question and returns a **Free Text** response (`subjective`), a **Pre-defined** value selected from options you configure (`objective`), or both.
## Key Features
* **Organized by category**: Dispositions are grouped under categories, which appear as sections in the extraction results
* **Two answer types**: Free Text (`is_subjective`) and Pre-defined (`is_objective`), configurable independently or together
* **Typed free-text responses**: Constrain free-text answers to a specific format — `timestamp`, `numeric`, `boolean`, `email`, or a custom `regex` pattern — with automatic post-LLM validation
* **Confidence & reasoning**: Every result includes a confidence score (0.0–1.0) and an explanation of why the LLM produced that answer
* **Bulk creation**: Create and link multiple dispositions to an agent atomically in a single request
* **Copy-on-write updates**: Editing a shared disposition via a scoped agent automatically creates a private copy, keeping other agents unaffected
* **Model selection**: Choose the LLM model used for evaluation per disposition
## Endpoints
```
GET /dispositions/ List dispositions
GET /dispositions/{disposition_id} Get a single disposition
POST /dispositions/ Create a disposition
POST /dispositions/bulk Bulk-create dispositions for an agent
PUT /dispositions/{disposition_id} Update a disposition (copy-on-write aware)
DELETE /dispositions/{disposition_id} Delete a disposition
POST /v2/agent/{agent_id}/dispositions/test Test all dispositions for an agent against a transcript
```
## Disposition Object
```json theme={"system"}
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Call Outcome",
"question": "What was the outcome of the call?",
"system_prompt": "You are analyzing a sales call transcript.",
"category": "Lead Quality",
"model": "gpt-4.1-mini",
"is_subjective": true,
"is_objective": true,
"subjective_type": "text",
"subjective_type_config": null,
"objective_options": [
{ "value": "interested", "condition": "Customer expressed genuine interest and agreed to a next step" },
{ "value": "not_interested", "condition": "Customer declined all proposals" },
{ "value": "follow_up", "condition": "Customer asked to be contacted again later" }
],
"agent_ids": ["agt_abc123"],
"created_by": "user_abc123",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-15T14:30:00Z"
}
```
### Field Reference
| Field | Type | Description |
| ------------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------- |
| `id` | UUID | Unique identifier |
| `name` | string | Display name shown in extraction results |
| `question` | string | The prompt sent to the LLM to evaluate the transcript |
| `system_prompt` | string | System context for the LLM (optional) |
| `category` | string | Category this disposition belongs to (default: `"General"`) |
| `model` | string | LLM used for evaluation (default: `"gpt-4.1-mini"`) |
| `is_subjective` | bool | Enable Free Text response |
| `is_objective` | bool | Enable Pre-defined value selection |
| `subjective_type` | string | Format constraint for free-text responses: `text` (default), `timestamp`, `numeric`, `boolean`, `email`, or `regex` |
| `subjective_type_config` | object \| null | Configuration for `regex` subjective type. Must include `pattern` (required) and optionally `description` |
| `objective_options` | array \| null | Required when `is_objective` is `true` |
| `agent_ids` | array | Agent IDs this disposition is linked to |
| `created_by` | string | ID of the user who created this disposition |
| `created_at` | string | ISO 8601 timestamp when the disposition was created |
| `updated_at` | string | ISO 8601 timestamp of the last update |
### ObjectiveOption Schema
```json theme={"system"}
{
"value": "interested",
"condition": "Customer expressed genuine interest and agreed to a next step",
"sub_options": []
}
```
`sub_options` is optional and supports the same recursive `ObjectiveOption` structure for hierarchical classifications.
For a full walkthrough of the Extractions feature, answer types, output format, and best practices, see the [Using Extractions](/docs/guides/prompting/using-extractions) guide.
# Test Dispositions API
Source: https://www.bolna.ai/docs/api-reference/dispositions/test
POST /v2/agent/{agent_id}/dispositions/test
Test all dispositions linked to an agent against a transcript to preview results before live calls.
Runs **all dispositions linked to the specified agent** against a provided transcript and returns the grouped results. Useful for validating your disposition setup before going live.
The response `extracted_data` is grouped by category and disposition name, in the same format as post-call execution data.
# Update Disposition API
Source: https://www.bolna.ai/docs/api-reference/dispositions/update
PUT /dispositions/{disposition_id}
Update a disposition. When scoped to an agent, shared dispositions are copied before editing to protect other agents.
## Scoped vs. Unscoped Mode
### Scoped mode (recommended) — `agent_id` provided
The API checks whether the disposition is **exclusive** to the specified agent (i.e., not shared with other agents):
* **Case 1: Disposition is exclusive to this agent → Edit in place.** Returns `200 OK`.
* **Case 2: Disposition is shared → Copy-on-write.** A new private copy is created for this agent, and the agent is re-linked to the copy. The original disposition is unchanged. Returns `201 Created`.
A `201` response means a **new disposition ID was created**. If you're storing the disposition ID (e.g., in your own database), update your reference to the new ID returned in the response. The original `disposition_id` now belongs to other agents; your agent uses the new copy.
### Unscoped mode — no `agent_id`
* Admins can update any disposition in place.
* Non-admin users can only update dispositions they own.
# Errors & Status Codes
Source: https://www.bolna.ai/docs/api-reference/errors
HTTP status codes, error response shapes, execution status enums, and batch status enums for the Bolna API.
## HTTP status codes
| Code | Meaning | When you see it |
| ----- | --------------------- | ------------------------------------------------------------------------------------------------------ |
| `200` | OK | Successful GET / action (stop, schedule, etc.) |
| `201` | Created | `POST /v2/agent`, `POST /batches` — resource created |
| `400` | Bad Request | Invalid or missing parameter — check `message` in the response body |
| `401` | Unauthorized | Missing or invalid API key — add `Authorization: Bearer ` |
| `403` | Forbidden | Valid key but insufficient permissions |
| `404` | Not Found | Resource ID doesn't exist or belongs to another account |
| `429` | Too Many Requests | Rate limit hit — back off and retry with exponential backoff |
| `500` | Internal Server Error | Unexpected server error — also returned when `scheduled_at` uses the `Z` suffix (use `+00:00` instead) |
## Error response shape
All 4xx/5xx responses return JSON:
```json theme={"system"}
{
"error": 1001,
"message": "agent_id is required"
}
```
The `error` integer is an internal code; `message` is human-readable. The `message` field is the most useful for debugging.
## Execution status enum
Returned in `GET /executions/{id}` and webhook payloads as the `status` field.
| Status | Type | Description |
| ------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `scheduled` | Intermediate | Call is scheduled for a future time |
| `prepared` | Intermediate | Execution record created and validated (recipient number, from/to number assigned) but not yet handed off to the dial queue |
| `queued` | Intermediate | Call accepted and waiting to dial |
| `rescheduled` | Intermediate | Call was rescheduled (e.g. due to guardrails) |
| `initiated` | Intermediate | Dialing has started |
| `ringing` | Intermediate | Recipient's phone is ringing |
| `in-progress` | Intermediate | Call answered, conversation active |
| `call-disconnected` | **Soft terminal** | Line dropped — data still finalizing; `completed` follows |
| **`completed`** | **Terminal ✓** | Call finished; all fields populated |
| `no-answer` | Terminal | Recipient didn't pick up |
| `busy` | Terminal | Line was busy |
| `failed` | Terminal | Telephony provider error |
| `canceled` | Terminal | Call canceled before answer |
| `stopped` | Terminal | Manually stopped via API |
| `error` | Terminal | Internal error |
| `balance-low` | Terminal | Insufficient wallet balance to place call |
**`call-disconnected` is not the final state.** `conversation_duration`, `total_cost`, `recording_url`, and `extracted_data` are `null` or `0` at this point. Wait for **`completed`** (or any other terminal status above) before reading those fields.
### Polling pattern
```python theme={"system"}
TERMINAL = {"completed","no-answer","busy","failed","canceled","stopped","error","balance-low"}
while True:
data = get_execution(execution_id)
if data["status"] in TERMINAL:
break # safe to read all fields now
time.sleep(5)
```
## Batch status enum
Returned by `GET /batches/{batch_id}` as the `status` field.
| Status | Description |
| ----------- | -------------------------------------------------------------------------------------- |
| `created` | Batch created, not yet scheduled |
| `processed` | CSV parsed and per-call records generated; batch is ready to run (no calls dialed yet) |
| `scheduled` | Scheduled and waiting for start time |
| `running` | Calls are actively being placed |
| `completed` | All calls finished |
| `stopped` | Manually stopped |
| `failed` | Error prevented execution |
## Per-call status in a batch
Each execution inside `GET /batches/{batch_id}/executions` has an individual `status` from the execution enum above. The batch's `execution_status` field gives a summary count: `{ "completed": 5, "no-answer": 2, "running": 3 }`.
## Scheduling errors
| Scenario | HTTP | Message |
| --------------------------------- | ----- | ---------------------------------------------------------- |
| `scheduled_at` uses `Z` suffix | `500` | Internal server error |
| `scheduled_at` \< 2 minutes ahead | `400` | "Scheduled time should be atleast 2 minutes in the future" |
| Invalid ISO 8601 format | `400` | Parsing error |
**Fix:** always use a numeric offset: `2026-06-23T18:30:00+00:00`.
# Get Batch Executions API
Source: https://www.bolna.ai/docs/api-reference/executions/get_batch_executions
GET /batches/{batch_id}/executions
Retrieve all executions for specific batches using Bolna APIs. This endpoint provides detailed information on each call's outcome and metrics within the batch.
# Retrieve Voice AI Execution API
Source: https://www.bolna.ai/docs/api-reference/executions/get_execution
GET /executions/{execution_id}
Fetch details of a specific phone call execution by its ID using Bolna APIs. This includes information such as conversation time, status, and telephony data.
Retrieves a single call execution by its ID. Returns the full call record including transcript, cost breakdown, recording URL, and extracted data.
## Status lifecycle
A call moves through these statuses. **Always wait for `completed`** (or a hard-failure terminal) before reading `conversation_duration`, `total_cost`, `recording_url`, or `extracted_data` — these fields are `null` or `0` until then.
| Status | Meaning |
| ------------------- | ----------------------------------------- |
| `queued` | Call accepted, waiting to dial |
| `initiated` | Dialing started |
| `ringing` | Recipient's phone is ringing |
| `in-progress` | Call answered, conversation active |
| `call-disconnected` | Line dropped — data still being finalized |
| **`completed`** | **✓ Terminal — all fields populated** |
| `no-answer` | Recipient didn't pick up |
| `busy` | Line busy |
| `failed` | Telephony error |
| `canceled` | Call canceled before answer |
| `stopped` | Call stopped mid-execution |
| `error` | Internal error during processing |
| `balance-low` | Insufficient wallet balance |
## Completed execution example
```json Completed execution theme={"system"}
{
"id": "b7140255-af33-4608-8e97-04dd944b8e48",
"agent_id": "5bc97541-e320-4d95-a3a5-242cfe45621d",
"status": "completed",
"conversation_duration": 16,
"total_cost": 3.23,
"transcript": "assistant: Hi! How is your day going?\nuser: Good thanks.\nassistant: Glad to hear it!",
"user_number": "+919876543210",
"agent_number": "+918035739222",
"extracted_data": {
"General": {
"Call Summary": {
"subjective": "Customer confirmed appointment for Friday.",
"confidence_label": "High"
}
}
},
"telephony_data": {
"duration": 16,
"recording_url": "https://api.bolna.ai/recordings/call/b7140255-af33-4608-8e97-04dd944b8e48",
"call_type": "outbound",
"provider": "plivo",
"hangup_by": "Plivo",
"hangup_reason": "inactivity_timeout"
},
"cost_breakdown": {
"platform": 2,
"network": 1,
"transcriber": 0.23,
"llm": 0,
"synthesizer": 0
},
"latency_data": {
"time_to_first_audio": 189.69
}
}
```
## Production pattern: webhook instead of polling
For production workloads, set `webhook_url` on your agent and Bolna will POST the execution payload to you automatically — no polling needed. Whitelist source IP `13.203.39.153`. See [Webhooks](/docs/guides/post-call/polling-call-status-webhooks).
```python Poll until completed (Python) theme={"system"}
import os, time, urllib.request, json
TERMINAL = {"completed","no-answer","busy","failed","canceled","stopped","error","balance-low"}
key = os.environ["BOLNA_API_KEY"]
exec_id = "YOUR_EXECUTION_ID"
while True:
req = urllib.request.Request(
f"https://api.bolna.ai/executions/{exec_id}",
headers={"Authorization": f"Bearer {key}"},
)
data = json.load(urllib.request.urlopen(req))
if data["status"] in TERMINAL:
print(data["transcript"])
break
time.sleep(5)
```
# Retrieve Voice AI Execution Raw Logs API
Source: https://www.bolna.ai/docs/api-reference/executions/get_execution_raw_logs
GET /executions/{execution_id}/log
Fetch raw logs of a specific phone call execution by its ID using Bolna APIs. This includes prompts, requests, responses, and optional LLM reasoning summaries when available.
For each item in `data`, when **`component`** is **`llm`** and **`type`** is **`response`**, the assistant text is in **`data`**. If the model exposed traceable reasoning for that turn, **`reasoning_content`** is also set; otherwise the field is omitted. Use this to debug or display model thinking alongside the spoken reply.
# Get All Voice AI Agent Executions API
Source: https://www.bolna.ai/docs/api-reference/executions/get_executions
GET /v2/agent/{agent_id}/executions
Retrieve all executions performed by a specific agent using Bolna APIs. This endpoint provides a comprehensive history of the agent's calls and conversations.
## Pagination
This API supports pagination using the `page_number` and `page_size` query parameters. You can utilize `has_more` in the API response to determine if you should fetch the next page. You can learn more about it from the [pagination documentation](/docs/api-reference/pagination).
## Date filtering
The `from` and `to` query parameters are **required** to filter executions by date.
You can filter executions by their `created_at` timestamp using the `from` and `to` query parameters. The following rules apply:
* Both `from` and `to` are **required** and must be passed **together**.
* The maximum allowed range between `from` and `to` is **7 days**.
* Dates must be in **UTC ISO 8601** format (e.g. `2026-06-07T00:00:00.000Z`).
# Executions APIs overview
Source: https://www.bolna.ai/docs/api-reference/executions/overview
Access your Voice AI agents call and conversation history using Bolna Executions APIs. This page details the available endpoints for managing call executions.
## Endpoints
```
GET /executions/:execution_id
GET /batch/:batch_id/executions
GET /v2/agent/:agent_id/executions
GET /executions/:execution_id/log
```
# Set Inbound Agent API
Source: https://www.bolna.ai/docs/api-reference/inbound/agent
POST /inbound/setup
Configure Bolna Voice AI agent to handle inbound calls automatically by associating it with a specific phone number using Bolna APIs.
# Inbound Bolna Voice AI Agent APIs Overview
Source: https://www.bolna.ai/docs/api-reference/inbound/overview
Discover how to set up Bolna Voice AI agents to answer inbound calls, enabling responsive communication channels.
## Endpoints
```
POST /inbound/setup
POST /inbound/unlink
```
# Remove Inbound Agent API
Source: https://www.bolna.ai/docs/api-reference/inbound/unlink
POST /inbound/unlink
Remove and unlink a Bolna Voice AI agent from a specific phone number to disable automated inbound voice call answering by AI agents.
# Bolna API Documentation
Source: https://www.bolna.ai/docs/api-reference/introduction
Use and leverage Bolna Voice AI using APIs through HTTP requests from any language in your applications and workflows.
## What is the Bolna API?
The Bolna API enables you to programmatically create, configure, and manage Voice AI agents from your own applications. Whether you are building complex workflows, automating customer support, or integrating voice capabilities into your existing products, our REST API provides everything you need.
The API uses predictable, resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes and authentication.
You must have an active Bolna account to generate and use API keys. If you don't have one, [sign up here](https://platform.bolna.ai).
***
## Authentication
All Bolna API endpoints require authentication using an API key. You must include this key in the `Authorization` header of all your HTTP requests using the `Bearer` scheme.
### How to generate an API Key
Log in to the [Bolna Dashboard](https://platform.bolna.ai). From the left sidebar navigation menu, select the **Developers** tab.
Click the **Create a new API Key** button to generate your unique authentication credentials.
Your newly generated API key will be displayed in a pop-up modal. **Copy this key and save it securely.**
**For your security, the API key will only be shown once.** If you lose your API key, you will need to delete it and generate a new one.
API keys generated for a **Subaccount** will start with `sa-`.
***
# Create Knowledgebase API
Source: https://www.bolna.ai/docs/api-reference/knowledgebase/create
POST /knowledgebase
Upload a PDF document or provide a URL to create a knowledgebase, enhancing your Bolna Voice AI agent's information base and response accuracy.
# Delete Knowledgebase API
Source: https://www.bolna.ai/docs/api-reference/knowledgebase/delete
DELETE /knowledgebase/{rag_id}
Remove and delete an existing knowledgebase from your Bolna account maintaining your Bolna Voice AI agents upto date.
# Get Knowledgebase API
Source: https://www.bolna.ai/docs/api-reference/knowledgebase/get_knowledgebase
GET /knowledgebase/{rag_id}
Retrieve details of a specific knowledgebase, including its ID, file name, creation time, and status, using Bolna APIs.
# List All Knowledgebases API
Source: https://www.bolna.ai/docs/api-reference/knowledgebase/get_knowledgebases
GET /knowledgebase/all
Retrieve all knowledgebases associated with your account, including their status and creation dates.
# Knowledgebases Overview
Source: https://www.bolna.ai/docs/api-reference/knowledgebase/overview
Learn how to ingest PDFs and URLs as knowledgebases for your Bolna Voice AI agents. Agents can use multiple knowledgebases simultaneously.
## Endpoints
```
POST /knowledgebase
GET /knowledgebase/:rag_id
GET /knowledgebase/all
DELETE /knowledgebase/:rag_id
```
# Limits & Quotas
Source: https://www.bolna.ai/docs/api-reference/limits
Concurrency, rate limits, batch size, CSV limits, and payload caps for the Bolna API.
## Concurrency
Concurrency is the number of simultaneous active calls your account can run. Check your current concurrency in `GET /user/me`:
```json theme={"system"}
{
"concurrency": { "max": 10, "current": 3 }
}
```
To increase your concurrency limit, contact [support@bolna.ai](mailto:support@bolna.ai) or upgrade your plan. See [Outbound Calling Concurrency](/docs/pricing/outbound-calling-concurrency) for scheduling behavior when the limit is reached.
## Rate limits
The API is rate-limited per account. If you exceed the limit you receive HTTP `429`. Apply exponential backoff and retry:
```python theme={"system"}
import time
def call_with_backoff(fn, max_retries=5):
for i in range(max_retries):
status, data = fn()
if status != 429:
return status, data
time.sleep(2 ** i)
raise Exception("Rate limit exceeded after retries")
```
## Batch limits
| Limit | Value |
| -------------------------------- | ------------------------------------------------------------------ |
| Minimum `scheduled_at` lead time | 2 minutes |
| Start rounding | Rounds up to next 10-minute mark |
| `scheduled_at` format | ISO 8601 with numeric offset (e.g. `+00:00`) — `Z` suffix rejected |
| Maximum CSV rows | Contact support for high-volume batches |
## CSV requirements
| Field | Rule |
| ----------------------- | ------------------------------------------------------ |
| `contact_number` column | **Required** — E.164 format (e.g. `+919876543210`) |
| Additional columns | Optional — become `{variable}` substitutions in prompt |
| File type | CSV (`text/csv`) |
| Encoding | UTF-8 |
## Webhook delivery
| Property | Value |
| ----------------- | ------------------------------------------------------------------------------- |
| Source IP | `13.203.39.153` — whitelist this on your server |
| Events per call | Multiple (status changes: queued → in-progress → call-disconnected → completed) |
| Expected response | HTTP `200` — return fast; Bolna retries on non-2xx or timeout |
## Wallet & balance
Calls require wallet credits. A `balance-low` execution status means the call was not placed due to insufficient balance. Top up from the [dashboard](https://platform.bolna.ai) or contact support for invoice billing.
# Pagination for Bolna APIs
Source: https://www.bolna.ai/docs/api-reference/pagination
Learn how to use pagination in Bolna Voice AI APIs using `page_number` and `page_size` to fetch results efficiently and build scalable workflows.
The endpoints also support pagination using the `page_number` and `page_size` query parameters. This allows you to fetch large sets of results in smaller, manageable chunks.
## Query Parameters
* `page_number` (integer, optional): The page of results to retrieve. Defaults to `1`. The first page starts at `1`.
* `page_size` (integer, optional): The number of results per page. Defaults to `20`. You can request up to `50` results per page.
## How it works
The API uses offset-based pagination under the hood. For example:
| page\_number | page\_size | Returned records |
| ------------ | ---------- | ---------------- |
| 1 | 10 | Records 1–10 |
| 2 | 10 | Records 11–20 |
| 3 | 5 | Records 11–15 |
## Example Request
```curl example-request theme={"system"}
GET /v2/agent/1234/executions?page_number=2&page_size=5
```
```json example-response theme={"system"}
{
"total": 38,
"page": 2,
"page_size": 5,
"has_more": true,
"data": [
{ "id": "ex_101", "status": "success", "created_at": "..." },
{ "id": "ex_102", "status": "failed", "created_at": "..." },
...
]
}
```
## Tips
* Use `has_more` to determine if you should fetch the next page.
* Combine pagination with filters supported in the API to narrow results efficiently.
# Buy Phone Numbers API
Source: https://www.bolna.ai/docs/api-reference/phone-numbers/buy
POST /phone-numbers/buy
Buy virtual phone numbers with full purchase, pricing, and provider details to use with Bolna Voice agents for outbound and inbound calls.
# Delete Phone Numbers API
Source: https://www.bolna.ai/docs/api-reference/phone-numbers/delete
DELETE /phone-numbers/{phone_number_id}
Delete a purchased phone number to stop billing and remove it permanently from your active inventory.
# List Phone Numbers API
Source: https://www.bolna.ai/docs/api-reference/phone-numbers/get_all
GET /phone-numbers/all
Retrieve all phone numbers associated with your account, including details like creation date and telephony provider like Twilio, Plivo, etc.
# Phone Numbers APIs Overview
Source: https://www.bolna.ai/docs/api-reference/phone-numbers/overview
Manage your phone numbers effectively using Bolna APIs, including buying, listing, deleting and associating numbers with Bolna Voice AI agents.
## Endpoints
```
GET /phone-numbers/all
GET /phone-numbers/search
POST /phone-numbers/buy
DELETE /phone-numbers/{phone_number_id}
```
# Search Phone Numbers API
Source: https://www.bolna.ai/docs/api-reference/phone-numbers/search
GET /phone-numbers/search
Search available phone numbers by region, locality, or pattern, with price to use them with Bolna Voice agents.
# Add a New Provider API
Source: https://www.bolna.ai/docs/api-reference/providers/add
POST /providers
Learn how to securely add a new provider to your Bolna account by specifying the provider's name and associated credentials.
You can add your own providers securely in Bolna. Please [read this page](/docs/providers) for more information about all current supported providers.
# List Providers API
Source: https://www.bolna.ai/docs/api-reference/providers/get
GET /providers
Retrieve all providers associated with your Bolna account, including their IDs, names, and creation timestamps.
# Providers APIs overview
Source: https://www.bolna.ai/docs/api-reference/providers/overview
Add and manage your own providers securely in Bolna, supporting various telephony and voice services.
You can add your own providers securely in Bolna.
Please [read this page](/docs/providers) for more information about all current supported providers.
## Endpoints
```
POST /providers
GET /providers
DELETE /providers/:provider_key_name
```
# Remove a Provider API
Source: https://www.bolna.ai/docs/api-reference/providers/remove
DELETE /providers/{provider_key_name}
Delete a previously added provider from your Bolna account, ensuring your integrations remain current.
# Rate Limiting for Bolna APIs
Source: https://www.bolna.ai/docs/api-reference/rate-limiting
Understand the API rate limits applied to Bolna API endpoints to ensure fair usage and platform stability.
All Bolna API endpoints are subject to rate limiting to ensure fair usage and maintain platform stability. Rate limits are applied per **organization** (if the user belongs to one) or per **user** otherwise.
## Rate Limits
### Endpoint-Specific Limits
The following endpoints have specific rate limits:
| Endpoint | Rate Limit |
| ------------------------------------------------------------------------- | ------------------- |
| [/v2/agent//executions](/docs/api-reference/agent/v2/get_all_agent_executions) | 500 requests/minute |
| [/v2/agent/](/docs/api-reference/agent/v2/get) | 500 requests/minute |
| [/call](/docs/api-reference/calls/make) | 500 requests/minute |
### Default Limit
All other API endpoints are subject to a default rate limit of **1000 requests per minute**.
## How Rate Limits Are Applied
* If your account is part of an **organization**, the rate limit is shared across all users within that organization.
* If your account is **not** part of an organization, the rate limit applies to your individual user account.
## Exceeding the Rate Limit
If you exceed the rate limit for an endpoint, the API will return an **HTTP 429 (Too Many Requests)** response. When this happens:
* Wait before retrying the request.
* Implement exponential backoff in your application to gracefully handle rate limit responses.
## Best Practices
* **Cache responses** where possible to reduce the number of API calls.
* **Use webhooks** instead of polling for call status updates to minimize requests to execution endpoints.
* **Spread requests** evenly over time rather than sending them in bursts.
* **Monitor your usage** and implement client-side rate limiting to stay within the allowed limits.
# Add Phone Number to Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/add_number
POST /sip-trunks/trunks/{trunk_id}/numbers
Add a DID phone number to your SIP trunk using the Bolna API. Assign numbers for inbound and outbound voice calling on your trunk.
## Next steps
After adding a phone number, [patch your agent's telephony provider to `sip-trunk`](/docs/api-reference/agent/v2/patch_update).
# Create SIP Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/create
POST /sip-trunks/trunks
Create a new SIP trunk on Bolna and register it with your gateway details. Set up your trunk for inbound and outbound voice calling.
## Next steps
After creating your trunk, [add a phone number to it](/docs/api-reference/sip-trunks/add_number).
# Delete SIP Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/delete
DELETE /sip-trunks/trunks/{trunk_id}
Permanently delete a SIP trunk and all associated resources including gateways, IP identifiers, and phone numbers.
# Get SIP Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/get
GET /sip-trunks/trunks/{trunk_id}
Get a single SIP trunk with full details including gateways, IP identifiers, and phone numbers. Look up any trunk by its ID.
# List SIP Trunks
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/get_all
GET /sip-trunks/trunks
List all SIP trunks configured in your Bolna account. Filter by active status and view trunk details including gateways and phone numbers.
# List Phone Numbers on Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/list_numbers
GET /sip-trunks/trunks/{trunk_id}/numbers
List all phone numbers associated with a SIP trunk. View assigned DID numbers and manage your trunk number inventory.
# SIP Trunk API Reference
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/overview
API endpoints for managing SIP trunks, gateways, and phone numbers on Bolna. Create, update, list, and delete trunks programmatically.
## Endpoints
### Trunks
| Method | Endpoint | Description |
| -------- | ------------------------------------------------------------------- | ---------------------- |
| `POST` | [`/sip-trunks/trunks`](/docs/api-reference/sip-trunks/create) | Create a new SIP trunk |
| `GET` | [`/sip-trunks/trunks`](/docs/api-reference/sip-trunks/get_all) | List all SIP trunks |
| `GET` | [`/sip-trunks/trunks/{trunk_id}`](/docs/api-reference/sip-trunks/get) | Get a single SIP trunk |
| `PATCH` | [`/sip-trunks/trunks/{trunk_id}`](/docs/api-reference/sip-trunks/update) | Update a SIP trunk |
| `DELETE` | [`/sip-trunks/trunks/{trunk_id}`](/docs/api-reference/sip-trunks/delete) | Delete a SIP trunk |
### Phone Numbers
| Method | Endpoint | Description |
| -------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------- |
| `POST` | [`/sip-trunks/trunks/{trunk_id}/numbers`](/docs/api-reference/sip-trunks/add_number) | Add a phone number to a trunk |
| `GET` | [`/sip-trunks/trunks/{trunk_id}/numbers`](/docs/api-reference/sip-trunks/list_numbers) | List phone numbers on a trunk |
| `DELETE` | [`/sip-trunks/trunks/{trunk_id}/numbers/{phone_number_id}`](/docs/api-reference/sip-trunks/remove_number) | Remove a phone number from a trunk |
# Remove Phone Number from Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/remove_number
DELETE /sip-trunks/trunks/{trunk_id}/numbers/{phone_number_id}
Remove a phone number from a SIP trunk. If the number was mapped to an agent, the mapping is also removed.
# Update SIP Trunk
Source: https://www.bolna.ai/docs/api-reference/sip-trunks/update
PATCH /sip-trunks/trunks/{trunk_id}
Partially update an existing SIP trunk on Bolna using a PATCH request. Only the fields you include in the request body will be changed.
# Get All Sub-Accounts Usage API
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/all_usage
GET /sub-accounts/all/usage
Retrieve usage, consumption, and billing details for all sub-accounts under the authenticated organization.
This is an `enterprise` feature.
You can read more about our enterprise offering here [Bolna enterprise](/docs/enterprise/plan).
## Summary
This endpoint returns aggregated usage data for **all sub-accounts** associated with the authenticated user's organization.\
It provides fine-grained insight into usage, consumption, and cost breakdowns for each sub-account.
## Endpoint
```yaml theme={"system"}
GET /sub-accounts/all/usage
```
# Create a new Sub-Account API
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/create
POST /sub-accounts/create
Create a new sub-account using the Bolna API to define separate workspaces with custom configurations for enterprise-level management.
This is an `enterprise` feature.
You can read more about our enterprise offering here [Bolna enterprise](/docs/enterprise/plan).
Only **organization admins** can create sub-accounts.
## Concurrency
Every sub-account is created with a concurrency envelope:
* **`min_concurrency`** — concurrency guaranteed to this sub-account even when the organization is at capacity. Use `0` for no guarantee.
* **`max_concurrency`** — the sub-account's hard cap. **Omit it for an elastic** sub-account that can burst into the organization's unused capacity; set `0` to pause the sub-account.
The request is rejected with `400` if the per-account minimums or maximums would exceed the organization's envelope. See [Concurrency management](/docs/enterprise/concurrency-management) for how guarantees, caps, and shared capacity work together.
# Deleting a Sub-account
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/delete
DELETE /sub-accounts/{sub_account_id}
Use Bolna APIs to delete a sub-account and their related data, ensuring proper cleanup of agents, batches, executions, and configurations.
This deletes **ALL** the data for that sub-account's batches, executions and agents.
# List all Sub-Accounts API
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/get_all
GET /sub-accounts/all
Retrieve all sub-accounts linked to your main account enabling centralized visibility and management.
This is an `enterprise` feature.
You can read more about our enterprise offering here [Bolna enterprise](/docs/enterprise/plan).
# Sub accounts APIs overview
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/overview
Manage multiple customers or business units with Bolna Sub-Accounts API. Create, list, and track usage with clear data separation and control.
This is an `enterprise` feature.
You can read more about our enterprise offering here [Bolna enterprise](/docs/enterprise/plan).
## Endpoints
```
POST /sub-accounts/create
GET /sub-accounts/all
GET /sub-accounts/:sub_account_id/usage
```
# Patch Update a Sub-account
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/patch_update
PATCH /sub-accounts/{sub_account_id}
Use this Bolna API endpoint to partially modify and update sub-account properties, including its name and concurrency limits.
This is a partial update — send only the fields you want to change. The following can be updated:
* `name`
* `min_concurrency` — guaranteed concurrency floor (`0` = no guarantee)
* `max_concurrency` — hard cap; omit to leave unchanged, send `null` to make the sub-account elastic, `0` to pause it
Only **organization admins** can update sub-accounts. Omitting a concurrency field leaves it unchanged; the edit is rejected with `400` if it would break the organization's concurrency envelope.
See [Concurrency management](/docs/enterprise/concurrency-management) for how guarantees, caps, and shared capacity work together.
# Track Sub-Account Usage API
Source: https://www.bolna.ai/docs/api-reference/sub-accounts/usage
GET /sub-accounts/{sub_account_id}/usage
Track usage for a specific sub-account giving you fine-grained insights into usage, consumption and billing.
This is an `enterprise` feature.
You can read more about our enterprise offering here [Bolna enterprise](/docs/enterprise/plan).
# Add a New Custom LLM Model
Source: https://www.bolna.ai/docs/api-reference/user/add_model
POST /user/model/custom
Learn how to integrate your custom Large Language Model (LLM) with Bolna Voice AI agents using Bolna APIs.
This request specifies how to add your own Custom LLM Models and use it with Bolna Voice AI agents. Please read about it more from [using-custom-llm](/docs/customizations/using-custom-llm)
# User information
Source: https://www.bolna.ai/docs/api-reference/user/info
GET /user/me
Get details like name, email, current wallet balance, concurrency limits using this API
# User APIs Overview
Source: https://www.bolna.ai/docs/api-reference/user/overview
Explore APIs related to user and account information for Bolna Voice AI agents, including endpoints for adding custom LLM models.
## Endpoints
```
GET /user/me
POST /user/model/custom
```
# List Violations API
Source: https://www.bolna.ai/docs/api-reference/violations/list
GET /violations/list
Retrieve a paginated list of violations, optionally filtered by status. Use this endpoint to monitor and manage call violations across your account.
## Pagination
This API supports pagination using the `page_number` and `page_size` query parameters. You can utilize `has_more` in the API response to determine if you should fetch the next page. You can learn more about it from the [pagination documentation](/docs/api-reference/pagination).
# Violations APIs Overview
Source: https://www.bolna.ai/docs/api-reference/violations/overview
Manage and track call violations using the Bolna Violations APIs. List violations with filtering and pagination, and submit violation evidence.
## Endpoints
```
GET /violations/list
POST /violations/submit
```
# Submit Violation API
Source: https://www.bolna.ai/docs/api-reference/violations/submit
POST /violations/submit
Submit a violation along with an evidence file (e.g., a screenshot or document). This endpoint updates the violation status and attaches the uploaded file.
# List Voices
Source: https://www.bolna.ai/docs/api-reference/voice/get_all
GET /api/v1/voice-config/tts/voices
Get a paginated list of voices for a specific TTS provider and model. Requires provider_id and model_id from the List Providers endpoint.
# List TTS Providers and Models
Source: https://www.bolna.ai/docs/api-reference/voice/get_providers
GET /api/v1/voice-config/tts
Get all supported TTS providers and their models for a given language. Returns provider IDs and model IDs needed to fetch voices.
# Voice APIs Overview
Source: https://www.bolna.ai/docs/api-reference/voice/overview
APIs for discovering TTS providers, models, and voices for use in Bolna agents.
The Voice APIs follow a two-step lookup flow:
1. **Get providers + models** — discover which TTS providers and models are available for a given language
2. **Get voices** — fetch the paginated voice list for a specific provider + model
## Endpoints
```
GET /api/v1/voice-config/tts
GET /api/v1/voice-config/tts/voices
```
## Flow
```
GET /api/v1/voice-config/tts?language=hi
→ returns providers[] each with models[]
Pick a provider.id and a model.id
GET /api/v1/voice-config/tts/voices?language=hi&provider_id=&model_id=&page=1&page_size=100
→ returns items[] of voices
```
Once you have the `voice_id` from a voice item, use it in your agent's `synthesizer_config`:
```json theme={"system"}
"synthesizer_config": {
"provider": "elevenlabs",
"voice_id": "iWNf11sz1GrUE4ppxTOL",
"model": "eleven_turbo_v2_5"
}
```
# AGENTS.md
Source: https://www.bolna.ai/docs/build-with-ai/agents-md
Machine-readable API guidance for AI coding assistants generating Bolna API code.
[AGENTS.md](/docs/AGENTS.md) encodes the non-obvious facts and gotchas an AI coding assistant needs to generate correct Bolna API code — the things most likely to produce broken code if missed. The [OpenAPI spec](/docs/api-reference/introduction) is the authoritative reference; AGENTS.md surfaces what it's easy to miss.
## Highlights
```
Base URL: https://api.bolna.ai
Auth: Authorization: Bearer
```
A missing or invalid key returns `401 Access denied`.
Both return `201 Created`. The agent-create response field is `state`, not `status`. The legacy v1 `/agent` endpoint returns `200` — only v2 returns `201`.
A trailing `Z` for UTC is rejected with a `500` error. Use a numeric offset instead, e.g. `2026-06-23T15:30:00+00:00`. Scheduling must also be at least 2 minutes in the future, and Bolna rounds up to the next 10-minute mark.
`call-disconnected` fires the instant the line drops — at that moment `conversation_duration`, `total_cost`, `recording_url`, and `extracted_data` are still null or 0. The `completed` event arrives a few seconds later with all fields populated.
Not an array of strings. Correct shape: `"pipelines": [["transcriber", "llm", "synthesizer"]]`.
Not wrapped in `{ "data": [...] }` — the response is the array directly.
Bolna sends webhooks from `13.203.39.153`. Whitelist this IP or events will be dropped.
## What else is in the file
* The full execution status lifecycle (`queued → initiated → ringing → in-progress → call-disconnected → completed`, plus terminal states)
* The batch status lifecycle
* A minimal working agent creation body
* A key endpoint summary table
Read the complete file at [/AGENTS.md](/docs/AGENTS.md).
# Example Prompts
Source: https://www.bolna.ai/docs/build-with-ai/example-prompts
Real prompts you can ask your AI assistant, and the Bolna Skill each one triggers.
Once [Bolna Skills are installed and set up](/docs/build-with-ai/setup), just ask your AI assistant what you need in plain English. The right skill loads automatically based on your request.
```
Create a Hindi voice agent for appointment booking using Plivo and Sarvam.
```
Uses the `create-agent` skill — configures LLM, TTS, STT, telephony, and system prompt in one shot.
```
Place a test call to +91XXXXXXXXXX and pass customer_name: Priya as user_data.
```
Uses the `make-call` skill — places an outbound call with dynamic variables.
```
Upload leads.csv as a Bolna batch campaign and monitor it until done.
```
Uses the `create-batch` skill — creates a CSV-driven campaign with scheduling and monitoring.
```
My Bolna call has a long silence before each response — debug it.
```
Uses the `debug-bolna-calls` skill — runs a symptom-to-fix diagnostic using execution logs.
```
Build a graph agent for payment confirmation with real-time event injection.
```
Uses the `bolna-graph-agents` skill — creates node-based call flows with deterministic routing.
```
Set up an inbound IVR that routes sales, support, and billing to three different agents.
```
Uses the `setup-inbound` skill — wires phone numbers to agents with IVR menus and caller identification.
Looking for the skill behind any of these? See the full [Skills Reference](/docs/build-with-ai/skills-reference).
# Installation
Source: https://www.bolna.ai/docs/build-with-ai/installation
Install Bolna Skills for your AI coding assistant.
Install Bolna Skills in your project with a single command:
```bash theme={"system"}
npx skills add bolna-ai/skills
```
This detects any Agent Skills-compatible assistants configured in your project and installs all 19 skills for each of them.
## Install for a specific assistant
```bash theme={"system"}
npx skills add bolna-ai/skills -a claude-code
```
```bash theme={"system"}
npx skills add bolna-ai/skills -a cursor
```
```bash theme={"system"}
npx skills add bolna-ai/skills -a codex
```
See [Supported AI Assistants](/docs/build-with-ai/supported-assistants) for the full list of compatible tools beyond these three.
## Install a single skill
If you only need one capability, install it by name instead of the full set:
```bash theme={"system"}
npx skills add bolna-ai/skills --skill create-agent
```
Browse every skill name in the [Skills Reference](/docs/build-with-ai/skills-reference).
## Next step
Once installed, connect your API key in [Setup](/docs/build-with-ai/setup) so your assistant can actually call the Bolna API.
# llms.txt & llms-full.txt
Source: https://www.bolna.ai/docs/build-with-ai/llms-txt
Machine-readable versions of these docs for feeding into an LLM's context window.
These docs publish two plain-text files built for LLMs and AI agents to consume directly, without scraping HTML.
A structured index of every page in these docs — titles and descriptions — for fast lookup by an LLM before it decides what to fetch in full.
The complete Bolna documentation concatenated into a single Markdown file, for pasting into a chat context or feeding to a RAG pipeline.
## When to use which
* Use **llms.txt** when an agent needs to decide which pages are relevant before reading them.
* Use **llms-full.txt** when you want the entire documentation set in one context window — for example, priming an LLM before asking it to write Bolna API integration code.
## Per-page AI actions
Every individual page in these docs also has its own AI actions menu:
* **Copy page** — copy the page content as Markdown
* **View as Markdown** — open the raw Markdown source for that page
* **Open in ChatGPT** — ask ChatGPT questions about that page
* **Open in Claude** — ask Claude questions about that page
For API-level integration facts an LLM needs (base URL, auth, response shapes, status lifecycles), see [AGENTS.md](/docs/build-with-ai/agents-md).
# MCP Server
Source: https://www.bolna.ai/docs/build-with-ai/mcp
Connect Claude, Cursor, Windsurf, or any MCP client to your Bolna account with the Bolna MCP server.
The Bolna MCP server connects your AI assistant directly to your Bolna account over the [Model Context Protocol](https://modelcontextprotocol.io). Once connected, you can list and inspect agents, pull call transcripts, run batch campaigns, manage dispositions, knowledgebases, phone numbers, SIP trunks, and sub-accounts, check your wallet balance, create or update agents, and place real outbound calls — all from a chat window, no dashboard tab required.
It's hosted at **[mcp.bolna.ai](https://mcp.bolna.ai)** — there's nothing to install or run locally. Point your client at the URL with your API key and you're connected.
Connect Claude, Cursor, Windsurf, Codex, Zed, or any other MCP client in under a minute
## What you can do
"List my agents", "what's my wallet balance?", "show me the numbers on my account" — quick lookups without opening the dashboard.
"Get the last 5 executions for agent X and show me the transcript for any that failed" — the assistant chains the lookups for you.
"Create a Hindi lead-qualification agent using Sarvam and GPT-4o mini", "update agent X's welcome message" — describe the change, the assistant makes the API call.
"Create a batch from this CSV and schedule it for 9am", "add a disposition that captures appointment\_time from the call" — campaign and post-call setup without leaving the chat.
"Buy me a US number and route it to my support agent", "add this number to my Twilio trunk", "what did the Acme sub-account spend this month?" — the enterprise and telephony surface, not just agents.
"Create a knowledgebase from our pricing page and check when it's done processing" — give an agent RAG over a URL without leaving the chat.
"List any pending violations on my account" — see calls flagged for content policy, regulatory, or fraud review.
"How do I set up a webhook?", "show me the MCP tool list page" — the assistant searches Bolna's documentation and reads back the actual page content, instead of guessing from training data.
## How it works
Your client sends your Bolna API key as a Bearer token to `https://mcp.bolna.ai/api/mcp`. For the 55 account tools, the server checks the key, calls the matching [Bolna REST API](/docs/api-reference/introduction) endpoint, and hands back trimmed JSON your assistant can reason about. `search_docs` and `get_doc` skip the account API entirely — they read Bolna's public documentation (`llms.txt` and its doc pages) instead.
### Switching accounts mid-conversation
Every tool also accepts an optional `api_key` argument that overrides the connected account's credential for just that one call. This is built for [sub-accounts](/docs/api-reference/sub-accounts/overview): ask the assistant to `list_sub_accounts`, grab the key (`sa-...`) for the one you want, then pass it as `api_key` on any later tool call to act as that sub-account — no reconnecting required. A sub-account key also works as the primary connection credential from the start, exactly like a main account's `bn-...` key.
```
Your client (Claude, Cursor, Windsurf...)
│ Bearer
▼
https://mcp.bolna.ai/api/mcp
│
▼
https://api.bolna.ai (agents · calls · batches · dispositions · knowledgebases · phone numbers · SIP trunks · sub-accounts · voice · violations · account)
```
No key is stored server-side — it travels with each request. The server is open source; see the [GitHub repo](https://github.com/bolna-ai/mcp) for the implementation.
## Confirm before it acts
12 tools are flagged as destructive in their tool definitions — irreversible deletes, or a real-world effect like spending balance or breaking something still in use. Most clients ask you to confirm before running them: `update_agent`, `delete_agent`, `start_outbound_call`, `schedule_batch`, `delete_batch`, `delete_disposition`, `buy_phone_number`, `delete_phone_number`, `delete_sip_trunk`, `delete_sub_account`, `remove_provider`, and `delete_knowledgebase` — see the [Tool List](/docs/build-with-ai/mcp-tool-list) for what makes each one destructive.
## Reference
Every tool the server exposes, grouped by agents, calls, batches, dispositions, knowledgebases, phone numbers, SIP trunks, sub-accounts, voice, violations, and account
Copy-paste prompts for common tasks — works in any client, chat-only included
## For coding agents
Requires Claude Code, Cursor, Windsurf, or another agent that can write and run files — use the MCP server to explore your data, then have it build a small dashboard around it
A code-native alternative — teaches the same operations to Claude Code, Cursor, and Codex directly, no MCP connection needed
# Example: Call Monitoring Dashboard
Source: https://www.bolna.ai/docs/build-with-ai/mcp-example-app
Use the Bolna MCP server to explore your account, then have your AI assistant build a small local dashboard around it.
The MCP server is best used two ways in the same session: **interactively**, to explore your account from chat, and as a **spec source**, to hand your assistant real field names and response shapes when it writes code. This walkthrough builds a small local dashboard — one page showing your agents, wallet balance, and recent call outcomes — that talks to the real Bolna API directly, so it keeps working with no MCP connection required at runtime.
This walkthrough needs an agent that can write and run files — **Claude Code**, **Cursor**, **Windsurf**, or **Codex CLI**. A chat-only client like Claude Desktop can do everything in the [Prompt Cheatsheet](/docs/build-with-ai/mcp-prompts), but can't carry out the codegen steps below.
The shipped dashboard calls `api.bolna.ai` with your `BOLNA_API_KEY` directly, from a small local server — it doesn't depend on the MCP server. MCP is the tool you and your assistant use *while building it*.
### Prerequisites
* A Bolna account with at least one agent that has placed calls
* A coding-capable agent (Claude Code, Cursor, Windsurf, or Codex CLI) with the [Bolna MCP server connected](/docs/build-with-ai/mcp-quickstart)
* Node.js 18+
Ask your assistant, connected via MCP:
```
Which of my agents have gotten calls in the last week?
```
This chains `list_agents` → `list_agent_executions` behind the scenes, so you can see real agent IDs and call volume before writing a line of code.
Now ask it to build the app — talk to it the way you'd brief a teammate, not a spec doc:
```
Build me a simple local dashboard for my Bolna account: my agents,
my wallet balance, and recent calls for whichever agent I pick.
Use the real Bolna API, not the MCP server, and keep my API key on
the server — never send it to the browser.
```
It should land on something like an Express backend proxying `api.bolna.ai`, with a static frontend that only talks to your own server. Expect a route close to this for the calls list:
```js theme={"system"}
app.get("/api/calls/:agentId", async (req, res) => {
const to = new Date().toISOString();
const from = new Date(Date.now() - 7 * 86400_000).toISOString();
const bolnaRes = await fetch(
`https://api.bolna.ai/v2/agent/${req.params.agentId}/executions?from=${from}&to=${to}`,
{ headers: { Authorization: `Bearer ${process.env.BOLNA_API_KEY}` } }
);
const { data } = await bolnaRes.json();
res.json(data.map(({ id, status, conversation_duration, created_at }) => (
{ id, status, conversation_duration, created_at }
)));
});
```
If it puts the key in frontend code or skips a field you need, just say so — that's a normal follow-up, not a failure.
Pick a failed execution ID from the table and ask, back in the MCP-connected chat:
```
Execution failed — what happened?
```
Then fold the fix into the app:
```
Highlight failed calls in red, and show the reason on hover.
```
```
Add a call button next to each agent, but block it if my wallet
balance is under ₹100.
```
This mirrors the `get_user_info` → `start_outbound_call` pattern from the [Prompt Cheatsheet](/docs/build-with-ai/mcp-prompts#chained-multi-step), now baked into the dashboard itself.
## What to build next
* **Webhook receiver** that pushes live call events into the dashboard instead of polling — see [Setup Webhooks](/docs/build-with-ai/skills-reference) via the `setup-webhook` Skill
* **Slack alert on low balance** using the same `/api/balance` route this dashboard already exposes
* **Batch-status view** for campaigns — `create_batch`, `schedule_batch`, and `list_batch_executions` cover the create/schedule/monitor side over MCP too now; see the `create-batch` Skill for the code-native equivalent
Every field and endpoint this example calls
More prompts to extend this dashboard
# Prompt Cheatsheet
Source: https://www.bolna.ai/docs/build-with-ai/mcp-prompts
Copy-paste prompts for common tasks with the Bolna MCP server.
Paste any of these into a connected client. Each one links to the tool it triggers — see the [Tool List](/docs/build-with-ai/mcp-tool-list) for the full schema.
## Agents
```
List my Bolna agents.
```
Triggers `list_agents`.
```
Show me the full config for agent .
```
Triggers `get_agent`.
```
Create a Hindi appointment-booking agent using Plivo and Sarvam TTS,
with a welcome message that greets the caller by name.
```
Triggers `create_agent`.
```
Update agent 's welcome message to mention our new return policy.
```
Triggers `update_agent` — most clients ask you to confirm first.
```
Cancel every queued call for agent — we're pausing the campaign.
```
Triggers `stop_agent_queued_calls`.
```
Delete the test agent I created yesterday.
```
Triggers `delete_agent` — irreversible, most clients ask you to confirm first.
## Calls & executions
```
Call +91XXXXXXXXXX using my sales agent and pass customer_name: Priya as context.
```
Triggers `start_outbound_call` — spends account balance, most clients ask you to confirm first.
```
Cancel the call I scheduled for execution .
```
Triggers `stop_call`.
```
Show me agent 's last 20 calls from this week.
```
Triggers `list_agent_executions`.
```
Pull the transcript and cost for execution .
```
Triggers `get_execution`.
```
Pull the raw pipeline logs for execution and tell me
whether the transcriber, LLM, or synthesizer was slow.
```
Triggers `get_execution_raw_logs`.
## Batches
```
Create a batch on my collections agent from this CSV of recipients.
```
Triggers `create_batch`.
```
Schedule batch to start calling at 9am tomorrow.
```
Triggers `schedule_batch` — starts real calls and spends balance, most clients ask you to confirm first.
```
What's the status and contact count for batch ?
```
Triggers `get_batch`.
```
List every execution in batch and tell me how many failed.
```
Triggers `list_batch_executions`.
```
Stop batch — we found an error in the recipient list.
```
Triggers `stop_batch`.
```
Delete batch , it was a test run.
```
Triggers `delete_batch` — irreversible, most clients ask you to confirm first.
## Dispositions
```
What dispositions are configured on agent ?
```
Triggers `list_dispositions`.
```
Add a disposition to agent that captures appointment_time
as a timestamp from the call.
```
Triggers `create_disposition`.
```
Add dispositions for lead_qualified (boolean), sentiment (pre-defined:
positive/neutral/negative), and consent_captured (boolean) to agent .
```
Triggers `bulk_create_dispositions`.
```
Run agent 's dispositions against this sample transcript
and show me what it would extract.
```
Triggers `test_dispositions`.
```
Update the sentiment disposition on agent to also flag "mixed".
```
Triggers `update_disposition`. Ask to delete one and it triggers `delete_disposition` instead — irreversible, most clients ask you to confirm first.
## Knowledgebase (RAG)
```
Create a knowledgebase from https://www.example.com/faq and let me
know when it's done processing.
```
Chains `create_knowledgebase` → `get_knowledgebase` to check status.
```
List my knowledgebases and show me the status of the one named "FAQ".
```
Chains `list_knowledgebases` → `get_knowledgebase`.
```
Delete the "old-pricing" knowledgebase, it's out of date.
```
Triggers `delete_knowledgebase` — irreversible, most clients ask you to confirm first.
## Phone numbers & inbound
```
What phone numbers do I have, and which agent is each one linked to?
```
Triggers `list_phone_numbers`.
```
Find me available US numbers with area code 415.
```
Triggers `search_phone_numbers`.
```
Buy that first number you found.
```
Triggers `buy_phone_number` — spends account balance (\$5/month), most clients ask you to confirm first.
```
Set up my support agent to answer inbound calls on +1XXXXXXXXXX.
```
Triggers `setup_inbound_agent`.
```
Remove the inbound routing on +1XXXXXXXXXX, we're decommissioning that line.
```
Triggers `unlink_inbound_agent`.
```
Delete the phone number +1XXXXXXXXXX, we don't need it anymore.
```
Triggers `delete_phone_number` — irreversible, most clients ask you to confirm first.
## SIP trunks
```
Create a SIP trunk pointed at my Twilio Elastic SIP termination URI,
using IP-based auth.
```
Triggers `create_sip_trunk`.
```
List my SIP trunks and show me the config for the one named "primary".
```
Chains `list_sip_trunks` → `get_sip_trunk`.
```
Add +1XXXXXXXXXX to my "primary" trunk.
```
Triggers `add_trunk_number`. Ask to remove one and it triggers `remove_trunk_number` instead.
```
What numbers are attached to my "primary" trunk?
```
Triggers `list_trunk_numbers`.
```
Delete the SIP trunk named "old-vendor".
```
Triggers `delete_sip_trunk` — irreversible, most clients ask you to confirm first.
## Sub-accounts
```
Create a sub-account called "Acme Corp".
```
Triggers `create_sub_account`.
```
List my sub-accounts.
```
Triggers `list_sub_accounts`.
```
Get the API key for my "Acme Corp" sub-account, then use it to list
that sub-account's agents.
```
Chains `list_sub_accounts` → `list_agents` with the returned key passed as `api_key` — no reconnecting needed. See [Calling tools with a different account](/docs/build-with-ai/mcp-tool-list#calling-tools-with-a-different-account).
```
What did the "Acme Corp" sub-account spend this month?
```
Triggers `get_sub_account_usage`.
```
Show me usage for all of my sub-accounts.
```
Triggers `get_all_sub_accounts_usage`.
```
Delete the "Acme Corp" sub-account, the engagement ended.
```
Triggers `delete_sub_account` — irreversible, most clients ask you to confirm first.
## Voice & providers
```
What telephony, LLM, and voice providers are connected to my account?
```
Triggers `list_providers`.
```
What TTS providers and voices do I have available? I want a
calm female Hindi voice.
```
Chains `list_tts_providers` → `list_voices`.
```
Remove my old ElevenLabs connection.
```
Triggers `remove_provider` — breaks any agent still using it, most clients ask you to confirm first.
## Violations
```
List any pending violations on my account.
```
Triggers `list_violations`. Ask for a different status ("accepted", "rejected", "submitted") and it filters accordingly.
## Account
```
What's my current wallet balance and concurrency limit?
```
Triggers `get_user_info`.
## Documentation
```
How do I set up a webhook in Bolna?
```
Triggers `search_docs`.
```
Show me the full content of the MCP tool list doc.
```
Chains `search_docs` → `get_doc`.
## Chained, multi-step
These touch more than one tool in a single request — the assistant chains the lookups itself.
```
Check agent 's last 10 calls — for any that didn't
complete, tell me why.
```
Chains `list_agent_executions` → `get_execution`.
```
If my wallet balance is above ₹500, call +91XXXXXXXXXX with my
onboarding agent.
```
Chains `get_user_info` → `start_outbound_call`.
```
Which of my agents don't have a webhook set up?
```
Chains `list_agents` → `get_agent` per agent.
```
Delete any agents I made today with "test" in the name.
```
Chains `list_agents` → `delete_agent`; expect a confirmation prompt per delete.
```
Find me an available number in area code 415, buy it, and route
it to my support agent.
```
Chains `search_phone_numbers` → `buy_phone_number` → `setup_inbound_agent`; expect a confirmation prompt before the purchase.
How the server works and what you can do with it
Use these prompts to explore your data, then have your assistant build a small dashboard around it
# Quickstart
Source: https://www.bolna.ai/docs/build-with-ai/mcp-quickstart
Connect the Bolna MCP server to Claude, Cursor, Windsurf, or any other MCP client.
Every client needs the same two things — there's nothing to install, the server is hosted at `mcp.bolna.ai`:
```
URL: https://mcp.bolna.ai/api/mcp
Header: Authorization: Bearer
```
Grab it from the [Bolna Dashboard → Developers](https://platform.bolna.ai). Keep it secret — anyone with the key can read your account data and place calls that spend your balance.
A [sub-account](/docs/api-reference/sub-accounts/overview) key (`sa-...`) works here too, exactly like a main account's `bn-...` key — connect with it directly, or switch per-call later with the `api_key` argument described in the [Tool List](/docs/build-with-ai/mcp-tool-list#calling-tools-with-a-different-account).
```bash theme={"system"}
claude mcp add --transport http bolna https://mcp.bolna.ai/api/mcp \
--header "Authorization: Bearer " \
--scope user
```
Desktop only launches local (stdio) servers, so reaching this remote HTTP server needs the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge. Add to `claude_desktop_config.json`:
```json theme={"system"}
{
"mcpServers": {
"bolna": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.bolna.ai/api/mcp",
"--header", "Authorization: Bearer "
]
}
}
}
```
Restart Claude Desktop after saving.
Add to `.cursor/mcp.json`:
```json theme={"system"}
{
"mcpServers": {
"bolna": {
"url": "https://mcp.bolna.ai/api/mcp",
"headers": { "Authorization": "Bearer " }
}
}
}
```
Add to `~/.codeium/windsurf/mcp_config.json`:
```json theme={"system"}
{
"mcpServers": {
"bolna": {
"serverUrl": "https://mcp.bolna.ai/api/mcp",
"headers": { "Authorization": "Bearer " }
}
}
}
```
Reads the key from an environment variable:
```bash theme={"system"}
export BOLNA_API_KEY=""
codex mcp add bolna \
--url https://mcp.bolna.ai/api/mcp \
--bearer-token-env-var BOLNA_API_KEY
```
Add to `settings.json`. Zed doesn't support environment-variable interpolation in headers yet, so the key goes in directly:
```json theme={"system"}
{
"context_servers": {
"bolna": {
"url": "https://mcp.bolna.ai/api/mcp",
"headers": { "Authorization": "Bearer " }
}
}
}
```
Point it at the URL and header above. If it only launches local (stdio) servers, bridge it with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote):
```bash theme={"system"}
npx -y mcp-remote https://mcp.bolna.ai/api/mcp \
--header "Authorization: Bearer "
```
Start a new conversation and ask:
```
List my Bolna agents
```
A real list back means you're connected.
claude.ai (web/mobile) isn't supported yet — its custom-connector UI has no field for a personal Bearer token. The options above are the only self-serve paths until OAuth support ships.
## Troubleshooting
Check the header reads exactly `Authorization: Bearer ` — a missing space after `Bearer`, or quotes baked in from copy-paste, will break it. An invalid key surfaces as a `403` from the underlying Bolna API.
Some clients (Claude Desktop is the common one) only support locally-run stdio servers — use the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge shown above.
Test it directly with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
```bash theme={"system"}
npx @modelcontextprotocol/inspector
```
Connect with transport **Streamable HTTP**, URL `https://mcp.bolna.ai/api/mcp`, header `Authorization: Bearer `, and check all 57 tools appear under "List Tools".
Every tool the server exposes
Copy-paste prompts for common tasks
# Tool List
Source: https://www.bolna.ai/docs/build-with-ai/mcp-tool-list
Every tool the Bolna MCP server exposes, grouped by agents, calls, batches, dispositions, knowledgebases, phone numbers, SIP trunks, sub-accounts, voice, violations, and account.
57 tools. 55 are backed one-to-one by the [Bolna REST API](/docs/api-reference/introduction) and act on your account. The remaining 2 (`search_docs`, `get_doc`) read Bolna's public documentation instead — no account data involved.
| Type | Meaning |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Read` | Looks something up. No side effects. |
| `Write` | Creates or changes something. Reversible or low-risk (e.g. `create_agent` just adds a new agent). |
| `Write ⚠` | Flagged **destructive** in the tool's own definition (`destructiveHint: true`) — irreversible, or has a real-world effect like spending balance or breaking something still in use. Most clients pause for your confirmation before running these. |
The 12 `⚠` tools are `update_agent`, `delete_agent`, `start_outbound_call`, `schedule_batch`, `delete_batch`, `delete_disposition`, `buy_phone_number`, `delete_phone_number`, `delete_sip_trunk`, `delete_sub_account`, `remove_provider`, and `delete_knowledgebase` — see each one's row below for what makes it destructive.
## Calling tools with a different account
Every tool below also accepts an optional `api_key` argument. Pass it on any single call to run that call against a different account than the one your client connected with — without reconnecting.
This is for [sub-accounts](/docs/api-reference/sub-accounts/overview): call `list_sub_accounts` to get a sub-account's key (`sa-...`), then pass it as `api_key` on any later tool call to act as that sub-account for just that call. A sub-account key also works as the primary connection credential from the start, exactly like a main account's `bn-...` key — see the [Quickstart](/docs/build-with-ai/mcp-quickstart).
## Agents
| Tool | Type | Description | API |
| ------------------------- | ------- | ------------------------------------------------------------------ | ------------------------------------------------------- |
| `list_agents` | Read | List agents in the account — ID, name, status, created date | [List Agents](/docs/api-reference/agent/v2/get_all) |
| `get_agent` | Read | Full config of one agent — prompts, LLM, voice, telephony, tools | [Get Agent](/docs/api-reference/agent/v2/get) |
| `create_agent` | Write | Create a new agent, returns its ID | [Create Agent](/docs/api-reference/agent/v2/create) |
| `update_agent` | Write ⚠ | Patch an agent's name, prompts, welcome message, webhook, or voice | [Patch Update](/docs/api-reference/agent/v2/patch_update) |
| `delete_agent` | Write ⚠ | Permanently delete an agent and its history | [Delete Agent](/docs/api-reference/agent/v2/delete) |
| `stop_agent_queued_calls` | Write | Cancel every queued or scheduled call for one agent | [Stop Agent Queued Calls](/docs/api-reference/agent/v2/stop) |
## Calls & executions
| Tool | Type | Description | API |
| ------------------------ | ------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `start_outbound_call` | Write ⚠ | Place a real outbound call, spends account balance | [Make Call](/docs/api-reference/calls/make) |
| `stop_call` | Write | Cancel a single queued or scheduled call | [Stop Call](/docs/api-reference/calls/stop_call) |
| `list_agent_executions` | Read | Call history for one agent, defaults to the last 7 days | [Get Executions](/docs/api-reference/agent/v2/get_all_agent_executions) |
| `get_execution` | Read | Full call detail — transcript, status, cost, telephony data | [Get Execution](/docs/api-reference/executions/get_execution) |
| `get_execution_raw_logs` | Read | Raw per-component pipeline logs for one call — transcriber, LLM, synthesizer timing | [Raw Logs](/docs/api-reference/executions/get_execution_raw_logs) |
| `list_batch_executions` | Read | Every call execution within one batch | [Batch Executions](/docs/api-reference/executions/get_batch_executions) |
## Batches
| Tool | Type | Description | API |
| ---------------- | ------- | ---------------------------------------------------------------- | ------------------------------------------------- |
| `list_batches` | Read | Batch campaigns for one agent — status and schedule | [Get Batches](/docs/api-reference/batches/get_batches) |
| `create_batch` | Write | Create a batch of outbound calls from a recipient list | [Create Batch](/docs/api-reference/batches/create) |
| `get_batch` | Read | One batch's status, schedule, and contact counts | [Get Batch](/docs/api-reference/batches/get_batch) |
| `schedule_batch` | Write ⚠ | Start calling every recipient in a batch, spends account balance | [Schedule Batch](/docs/api-reference/batches/schedule) |
| `stop_batch` | Write | Halt a running or scheduled batch | [Stop Batch](/docs/api-reference/batches/stop) |
| `delete_batch` | Write ⚠ | Permanently delete a batch and its recipient list | [Delete Batch](/docs/api-reference/batches/delete) |
## Dispositions
Dispositions turn a call transcript into structured, typed data — lead qualified, appointment time, sentiment — surfaced as `extracted_data` on executions and webhook payloads.
| Tool | Type | Description | API |
| -------------------------- | ------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `list_dispositions` | Read | Dispositions configured for one agent | [List Dispositions](/docs/api-reference/dispositions/list) |
| `get_disposition` | Read | One disposition's field type, validation, and prompt | [Get Disposition](/docs/api-reference/dispositions/get) |
| `create_disposition` | Write | Add a single disposition to an agent | [Create Disposition](/docs/api-reference/dispositions/create) |
| `bulk_create_dispositions` | Write | Add several dispositions to an agent in one call | [Bulk Create Dispositions](/docs/api-reference/dispositions/bulk-create) |
| `update_disposition` | Write | Change a disposition's field, validation, or prompt | [Update Disposition](/docs/api-reference/dispositions/update) |
| `delete_disposition` | Write ⚠ | Permanently delete a disposition | [Delete Disposition](/docs/api-reference/dispositions/delete) |
| `test_dispositions` | Write | Run an agent's dispositions against a sample transcript and preview the extracted output | [Test Dispositions](/docs/api-reference/dispositions/test) |
## Knowledgebase (RAG)
| Tool | Type | Description | API |
| ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `list_knowledgebases` | Read | Every knowledgebase on the account | [List All Knowledgebases](/docs/api-reference/knowledgebase/get_knowledgebases) |
| `get_knowledgebase` | Read | One knowledgebase's file name, status, and settings, by ID | [Get Knowledgebase](/docs/api-reference/knowledgebase/get_knowledgebase) |
| `create_knowledgebase` | Write | Create a knowledgebase by scraping a URL for RAG. Processing is async — check progress with `get_knowledgebase` | [Create Knowledgebase](/docs/api-reference/knowledgebase/create) |
| `delete_knowledgebase` | Write ⚠ | Permanently delete a knowledgebase | [Delete Knowledgebase](/docs/api-reference/knowledgebase/delete) |
`create_knowledgebase` only accepts a URL to scrape — the Bolna API also supports uploading a PDF directly, but a raw file doesn't map cleanly to a chat tool argument. For PDF-based knowledgebases, use the [dashboard](https://platform.bolna.ai) or call the [Create Knowledgebase API](/docs/api-reference/knowledgebase/create) directly.
## Phone numbers & inbound
| Tool | Type | Description | API |
| ---------------------- | ------- | ----------------------------------------------------------------- | ----------------------------------------------------------- |
| `list_phone_numbers` | Read | Phone numbers on the account and their linked agent | [Get All](/docs/api-reference/phone-numbers/get_all) |
| `search_phone_numbers` | Read | Search available numbers to buy, by country or pattern | [Search Phone Numbers](/docs/api-reference/phone-numbers/search) |
| `buy_phone_number` | Write ⚠ | Purchase a phone number, spends account balance (flat \$5/month) | [Buy Phone Numbers](/docs/api-reference/phone-numbers/buy) |
| `delete_phone_number` | Write ⚠ | Permanently release a phone number back to the pool | [Delete Phone Numbers](/docs/api-reference/phone-numbers/delete) |
| `setup_inbound_agent` | Write | Route inbound calls on a number to an agent, with an optional IVR | [Set Inbound Agent](/docs/api-reference/inbound/agent) |
| `unlink_inbound_agent` | Write | Remove the inbound routing from a phone number | [Remove Inbound Agent](/docs/api-reference/inbound/unlink) |
## SIP trunks
For bringing your own telephony (BYOT) — Twilio Elastic SIP, Plivo Zentrunk, Telnyx, and other standards-compliant trunks.
| Tool | Type | Description | API |
| --------------------- | ------- | ------------------------------------------------------- | ------------------------------------------------------------------- |
| `create_sip_trunk` | Write | Register a SIP trunk with its gateway and auth settings | [Create SIP Trunk](/docs/api-reference/sip-trunks/create) |
| `get_sip_trunk` | Read | One trunk's gateway, auth, and transport config | [Get SIP Trunk](/docs/api-reference/sip-trunks/get) |
| `list_sip_trunks` | Read | SIP trunks on the account | [List SIP Trunks](/docs/api-reference/sip-trunks/get_all) |
| `update_sip_trunk` | Write | Change a trunk's gateway, auth, or transport settings | [Update SIP Trunk](/docs/api-reference/sip-trunks/update) |
| `delete_sip_trunk` | Write ⚠ | Permanently delete a SIP trunk | [Delete SIP Trunk](/docs/api-reference/sip-trunks/delete) |
| `add_trunk_number` | Write | Attach a DID number to a trunk | [Add Number to Trunk](/docs/api-reference/sip-trunks/add_number) |
| `remove_trunk_number` | Write | Detach a DID number from a trunk | [Remove Number from Trunk](/docs/api-reference/sip-trunks/remove_number) |
| `list_trunk_numbers` | Read | DID numbers attached to one trunk | [List Numbers on Trunk](/docs/api-reference/sip-trunks/list_numbers) |
## Sub-accounts
Enterprise feature — isolated workspaces with their own auto-provisioned API key (`sa-...`), agents, calls, and phone numbers, for agencies, multi-tenant platforms, or regulated data boundaries.
| Tool | Type | Description | API |
| ---------------------------- | ------- | --------------------------------------------------------- | -------------------------------------------------------- |
| `create_sub_account` | Write | Create a sub-account and provision its API key | [Create Sub-Account](/docs/api-reference/sub-accounts/create) |
| `list_sub_accounts` | Read | Sub-accounts on the account, including their API keys | [List Sub-Accounts](/docs/api-reference/sub-accounts/get_all) |
| `update_sub_account` | Write | Patch a sub-account's name or settings | [Patch Update](/docs/api-reference/sub-accounts/patch_update) |
| `delete_sub_account` | Write ⚠ | Permanently delete a sub-account and everything inside it | [Delete Sub-Account](/docs/api-reference/sub-accounts/delete) |
| `get_sub_account_usage` | Read | Call volume and cost for one sub-account | [Track Usage](/docs/api-reference/sub-accounts/usage) |
| `get_all_sub_accounts_usage` | Read | Usage for every sub-account on the account, in one call | [All Usage](/docs/api-reference/sub-accounts/all_usage) |
## Voice & providers
| Tool | Type | Description | API |
| -------------------- | ------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `list_tts_providers` | Read | Text-to-speech providers and models available to the account | [List TTS Providers and Models](/docs/api-reference/voice/get_providers) |
| `list_voices` | Read | Voices available across connected TTS providers | [List Voices](/docs/api-reference/voice/get_all) |
| `list_providers` | Read | Telephony, LLM, transcriber, and TTS providers connected to the account | [List Providers](/docs/api-reference/providers/get) |
| `remove_provider` | Write ⚠ | Disconnect a provider's credentials — breaks any agent still using it | [Remove a Provider](/docs/api-reference/providers/remove) |
## Violations
| Tool | Type | Description | API |
| ----------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `list_violations` | Read | Flagged call violations — content policy, regulatory, or fraud — optionally filtered by status (`pending`/`accepted`/`rejected`/`submitted`), paginated | [List Violations](/docs/api-reference/violations/list) |
## Account
| Tool | Type | Description | API |
| --------------- | ---- | --------------------------------------------------- | ------------------------------------- |
| `get_user_info` | Read | Account profile, wallet balance, concurrency limits | [User Info](/docs/api-reference/user/info) |
## Documentation
These two don't touch your account at all — they read Bolna's own docs, so the assistant can look things up instead of guessing.
| Tool | Type | Description | Source |
| ------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| `search_docs` | Read | Searches Bolna's documentation index ([`llms.txt`](https://www.bolna.ai/docs/llms.txt)) and returns ranked matches with title, URL, and description | `llms.txt` |
| `get_doc` | Read | Fetches a documentation page's full Markdown content, given a bare path (e.g. `/docs/build-with-ai/mcp`) or a full URL | `www.bolna.ai/docs/*.md` |
Not connected yet? See the [Quickstart](/docs/build-with-ai/mcp-quickstart) for setup and troubleshooting.
Full source, endpoint-verification notes, and issue tracker
# Build with AI
Source: https://www.bolna.ai/docs/build-with-ai/overview
Use AI coding assistants and LLM-friendly docs to build, deploy, and operate Bolna voice agents faster.
Bolna's documentation and tooling are built to work with AI coding assistants and LLM-based agents, so you can go from a plain-English prompt to a working voice agent without leaving your editor.
Get started by [installing Bolna Skills](/docs/build-with-ai/installation) and [connecting your API key](/docs/build-with-ai/setup).
## AI coding assistants
Structured instructions that teach Claude Code, Cursor, Codex, and other assistants to create agents, make calls, run batch campaigns, and debug issues from natural-language prompts
## Bolna MCP Server
A remote MCP server at [mcp.bolna.ai](https://mcp.bolna.ai) that lets Claude, Cursor, Windsurf, or any MCP client list agents, pull call transcripts, check your wallet balance, create or update agents, and place real outbound calls — directly from a chat window
## AI inside the dashboard
Go from a short description or uploaded document to a production-grade, call-ready voice agent in 5–8 minutes — no prompt writing required
## Docs for LLMs and agents
A structured page index and a full single-file dump of these docs, built for LLMs
Machine-readable API guidance — base URL, auth, response shapes, and gotchas
## Ask AI, right from any page
Every page in these docs includes an AI actions menu:
* **Copy page** — copy the page content as Markdown
* **View as Markdown** — open the raw Markdown source
* **Open in ChatGPT** — ask ChatGPT questions about the page
* **Open in Claude** — ask Claude questions about the page
# Setup
Source: https://www.bolna.ai/docs/build-with-ai/setup
Connect your Bolna API key so your AI assistant can call the Bolna API.
Get your API key from the [Bolna Dashboard → Developers](https://platform.bolna.ai) and export it:
```bash theme={"system"}
export BOLNA_API_KEY="your-api-key"
```
You can also add it to a `.env` file in your project:
```bash theme={"system"}
BOLNA_API_KEY=your-api-key
```
Make sure `.env` is listed in your `.gitignore` to avoid committing secrets.
That's it — your AI assistant now has everything it needs to create agents, place calls, and manage your Bolna account. Try one of the [example prompts](/docs/build-with-ai/example-prompts) to see it in action.
# Bolna Skills
Source: https://www.bolna.ai/docs/build-with-ai/skills
Teach your AI coding assistant to build, deploy, and operate Bolna voice agents using Agent Skills.
## What are Bolna Skills?
Bolna Skills are a set of structured instructions that teach AI coding assistants — such as **Claude Code**, **Cursor**, **Codex**, and others that support the [Agent Skills](https://agentskills.io) format — how to work with the Bolna platform.
Once installed, your AI assistant can create agents, make calls, run batch campaigns, set up inbound numbers, debug issues, and more — all from natural language prompts inside your editor or terminal.
Create and configure voice agents with prompts, voices, and tools
Place outbound calls, run batch campaigns, and set up inbound numbers
Pull transcripts, set up webhooks, extract data, and troubleshoot calls
***
## Get started
Install Bolna Skills ([Installation](/docs/build-with-ai/installation)) and connect your API key ([Setup](/docs/build-with-ai/setup)). Then just ask your AI assistant what you need in plain English — the right skill loads automatically based on your request. See it in action in [Example Prompts](/docs/build-with-ai/example-prompts).
Every skill is listed in the [Skills Reference](/docs/build-with-ai/skills-reference), and every compatible tool is listed in [Supported AI Assistants](/docs/build-with-ai/supported-assistants).
***
## Resources
Browse source code, report issues, and contribute
Learn about the Agent Skills standard
Full Bolna REST API documentation
Manage agents, API keys, and billing
# Skills Reference
Source: https://www.bolna.ai/docs/build-with-ai/skills-reference
All 19 Bolna Skills, grouped by build, call, monitor, and advanced categories.
Every skill below can be installed on its own with `npx skills add bolna-ai/skills --skill `, or all together per [Installation](/docs/build-with-ai/installation).
## Build agents
| Skill | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setup-api-key` | Generate, store, and verify your `BOLNA_API_KEY` |
| `add-provider` | Bring your own OpenAI, Anthropic, Azure, ElevenLabs, Cartesia, Sarvam, Deepgram, Twilio, Plivo, Vobiz, or Exotel credentials |
| `create-agent` | Create a voice agent end-to-end — LLM, voice, transcriber, telephony, knowledge bases, and function tools |
| `manage-agents` | List, update, delete, or stop queued calls for an agent |
| `prompt-writing` | Author production voice prompts — sectioned structure, Hindi-first/English-second scripted lines, FAQ in YAML, multilingual entries with per-language STT/TTS |
## Make calls
| Skill | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| `make-call` | Place a single outbound call — immediate or scheduled, with dynamic variables, voice overrides, and auto-retry |
| `create-batch` | Run CSV-driven outbound campaigns at scale — schedule, monitor, stop |
| `setup-inbound` | Wire phone numbers to agents, with IVR menus, caller identification, and multilingual auto-switching |
| `manage-phone-numbers` | Search and buy US (Twilio) or India (Plivo, Vobiz) phone numbers |
| `setup-sip-trunk` | Bring your own SIP trunk — Twilio Elastic, Plivo Zentrunk, Telnyx, Vonage, and any standards-compliant carrier |
## Monitor and improve
| Skill | Description |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `get-executions` | Pull transcripts, recordings, costs, hangup codes, and raw logs from any call |
| `setup-webhook` | Stream call updates to your backend in real time for CRM sync and dashboards |
| `create-disposition` | Extract structured data from every transcript — lead quality, appointment times, sentiment, consent captured |
| `manage-violations` | List compliance flags and submit evidence files for review |
| `debug-bolna-calls` | Symptom-to-fix runbook for slow responses, robotic voice, interruptions, missed webhooks, SIP no-audio, batch failures, and more |
## Advanced
| Skill | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `bolna-graph-agents` | Build deterministic, node-based call flows with LLM, expression, and event-driven transitions; push real-time events into live calls |
| `setup-tools` | Give agents function-calling tools — live transfer, Cal.com booking, any HTTP API, and DTMF keypad input |
| `create-knowledgebase` | Add RAG over PDFs or URLs, including multilingual document support |
| `manage-subaccounts` | Multi-tenant workspaces for agencies and enterprise teams, with auto-provisioned API keys |
Browse the full source of every skill, report issues, or contribute
# Supported AI Assistants
Source: https://www.bolna.ai/docs/build-with-ai/supported-assistants
Every AI coding assistant Bolna Skills works with.
Bolna Skills work with any tool that supports the [Agent Skills](https://agentskills.io) format.
## Primary assistants
These are the assistants most Bolna developers use, and the ones with a dedicated `-a` install flag in [Installation](/docs/build-with-ai/installation):
* [Claude Code](https://claude.ai/code)
* [Cursor](https://cursor.com)
* [OpenAI Codex](https://openai.com/codex)
* [Gemini CLI](https://geminicli.com)
* [Amp](https://ampcode.com)
* [Goose](https://block.github.io/goose)
## Also compatible
The installer (`npx skills add bolna-ai/skills`) also detects and installs to any of the following Agent Skills-compatible clients found on your machine:
Antigravity, Antigravity CLI, Cline, Deep Agents, GitHub Copilot, Kimi Code CLI, OpenCode, Warp, Zed, AiderDesk, AstrBot, Autohand Code CLI, Augment, IBM Bob, OpenClaw, CodeArts Agent, CodeBuddy, Codemaker, Code Studio, CommandCode, Continue, Cortex Code, Crush, Devin for Terminal, Droid, ForgeCode, Hermes Agent, inference.sh, Jazz, Junie, iFlow CLI, KiloCode, Kiro CLI, Kode, Lingma, MCPJam, Mistral Vibe, Moxby, Mux, OpenHands, Ona, Pi, Qoder, Qoder CN, Qwen Code, Reasonix, Rovo Dev, Roo Code, Tabnine CLI, Terramind, Tinycloud, Trae, Trae CN, Windsurf, Zencoder, Zenflow, Neovate, and Pochi.
This ecosystem grows continuously. For the exact, current list, run `npx skills add bolna-ai/skills` yourself — it detects what's installed on your machine — or browse the live registry at [agentskills.io/clients](https://agentskills.io/clients).
See [Installation](/docs/build-with-ai/installation) for the install command, including the `-a` flag for Claude Code, Cursor, and Codex specifically.
# Bolna AI Updates for April, 2025
Source: https://www.bolna.ai/docs/changelog/april-2025
Explore the latest features, improvements, and API updates introduced in April 2025 for Bolna Voice AI agents.
## Call Frequency Limiting
* Set a limit on the maximum number of inbound calls allowed from a unique phone number to a given destination number. Call frequency limiting helps prevent spam, abuse, or unintended repeated calls.
## Improvements
* All inbound and outbound calls to have a maximum limit of `25KB` for injecting context.
* Learn more on [injecting context for inbound calls](/docs/customizations/identify-incoming-callers) for inbound calls.
* Learn more on [injecting context for outbound calls](/docs/guides/prompting/using-context) for outbound calls).
## Inbound Whitelist Control
* Configure inbound rules to allow calls only from specific whitelisted phone numbers. Inbound whitelist control ensures that only trusted callers can initiate conversations with your agents.
## Improvements
* Latency improvements for agents using [guardrails](/docs/guardrails).
* Tool information will now be available in the post call analysis like [extraction](/docs/guides/prompting/using-extractions) & summarization.
## Deepgram Aura-2 TTS Support
* Added support for [Deepgram's](/docs/providers/voice/deepgram) Aura-2 TTS model `aura-2`.
## Improvements
* Transcripts will now be more [accurate by incorporating interruptions](/docs/customizations/capturing-precise-transcripts).
## OpenAI GPT-4.1 Model Support
* Added support for OpenAI's **GPT-4.1** family of models: `gpt-4.1`, `gpt-4.1-mini` & `gpt-4.1-nano`.
## Improvements
* Ability to remove voices from your account
* Audio recordings are now stored in `dual` (stereo) mode for both inbound & outbound calls.
# Bolna AI Updates for April, 2026
Source: https://www.bolna.ai/docs/changelog/april-2026
Explore the latest features and improvements introduced in April 2026 for Bolna Voice AI agents.
## Conversation Rating & Feedback
You can now rate and leave feedback on individual conversations directly from the dashboard. After reviewing a call, score it from 1 (Poor) to 4 (Excellent) and optionally add a note to capture what went well or what needs improvement.
Scores and notes stay internal to your team, making it easy to track agent quality over time and share context during reviews.
## Import custom functions from cURL
You can now paste a `curl` request while creating a custom function in the **Tools** tab and use it to generate a draft configuration automatically. This makes it much faster to bring existing API requests into Bolna without rebuilding the function setup from scratch.
Learn more in the [Custom Functions documentation](/docs/tool-calling/custom-function-calls#import-from-curl).
## LLM reasoning in execution logs
The [Get execution raw logs](/docs/api-reference/executions/get_execution_raw_logs) API now includes optional **`reasoning_content`** on LLM response rows when the underlying model returns traceable reasoning (for example OpenAI reasoning summaries or Gemini thinking). It appears alongside the usual **`data`** field for assistant turns.
In the dashboard, use **Call history → Trace Data** ([Call history](/docs/agent-setup/call-history)) to inspect execution logs while debugging.
## Extraction Confidence, Reasoning & Typed Responses
Extraction results now include richer signal to help you trust and act on post-call data:
* **Confidence score** — every extraction result carries a `confidence` score (0.0–1.0) and a `confidence_label` (`"High"` ≥ 0.8, `"Medium"` ≥ 0.5, `"Low"` \< 0.5). Use these to route low-confidence results for human review before pushing data downstream.
* **Reasoning** — `reasoning_subjective` and `reasoning_objective` explain exactly why the LLM produced each answer, making it much easier to audit unexpected results.
* **Expected Format for free text** — you can now constrain free-text responses to a specific type: `timestamp` (ISO 8601), `numeric`, `boolean`, `email`, or a **custom regex** pattern. Responses are validated post-LLM; mismatches are flagged in a `validation` field while the original answer is still preserved.
```json theme={"system"}
{
"subjective": "user@example.com",
"objective": null,
"confidence": 0.95,
"confidence_label": "High",
"reasoning_subjective": "Customer clearly provided their email address during the call.",
"validation": { "is_valid": true, "expected_type": "email" }
}
```
Learn more in the [Using Extractions documentation](/docs/guides/prompting/using-extractions) and [Dispositions API reference](/docs/api-reference/dispositions/overview).
## Multilingual Agent Support
You can now launch multilingual agents with language-specific configuration across prompts, speech recognition, and text-to-speech. This makes it easier to set up agents that can operate cleanly across multiple languages from a single workflow.
Learn more in the [Multilingual voice agents documentation](/docs/customizations/multilingual-languages-support).
## Region-Based Indian Phone Number Search
You can now search Indian phone numbers by region directly in the dashboard. This makes it easier to find numbers for a specific geography.
Learn more in the [Phone Numbers API documentation](/docs/api-reference/phone-numbers/search).
## Unified Voice Configuration in Agent Setup
You can now configure TTS voices from a single place in agent setup with a unified selector for provider, model, and voice. This makes it easier to find and apply the right voice without jumping across multiple controls.
The updated voice selector includes:
* Search across available voices by name
* Gender filters for `male`, `female`, and `neutral` voices
* Inline voice sample playback while selecting a voice
Learn more in the [Audio Tab documentation](/docs/agent-setup/audio-tab).
# Bolna AI Updates for August, 2025
Source: https://www.bolna.ai/docs/changelog/august-2025
Explore the latest features, improvements, and API updates introduced in August 2025 for Bolna Voice AI agents.
## Support for scheduling calls at a future timestamp in `/call` endpoint.
* If `scheduled_at` is provided, the call will be queued and executed at that timestamp. Refer [docs](https://www.bolna.ai/docs/api-reference/calls/make#body-scheduled-at).
## Instantly Clone Voices with a Single Click
* You can now create high-quality AI clones of any voice directly from the Voice Lab.
* Simply provide a name and a 1-2 minute audio sample to generate a new, unique voice for your agents.
* Voice cloning is powered by leading providers like ElevenLabs to ensure top-tier quality. Learn more in our [new guide to cloning voices](https://www.bolna.ai/docs/clone-voices).
## Added `OpenRouter` support
* Support for the following models via [OpenRouter](/docs/providers/llm-model/openrouter). Learn more about OpenRouter from their [official website](https://openrouter.ai).
1. `gpt-4.1` OpenRouter OpenAI
2. `gpt-4.1-mini` OpenRouter OpenAI
3. `gpt-4.1-nano` OpenRouter OpenAI
4. `gpt-4o` OpenRouter OpenAI
5. `gpt-4o-mini` OpenRouter OpenAI
6. `gpt-4` OpenRouter OpenAI
## Add your own `OpenRouter` API keys
* Use your own OpenRouter account by adding your API Key to the [OpenRouter provider](https://www.bolna.ai/docs/providers).
# Bolna AI Updates for August, 2026
Source: https://www.bolna.ai/docs/changelog/august-2026
Explore the latest features and improvements introduced in August 2026 for Bolna Voice AI agents.
## Cartesia Sonic 3.6 is available for voice agents
Cartesia's newest Sonic model can now be selected as a synthesizer, as `sonic-preview` in the API and **Sonic 3.6 (Beta)** in the dashboard. It supports **42 languages** and works with every Cartesia voice available in Bolna.
Sonic 3.5 remains the recommended choice for production agents while 3.6 is in beta.
[Cartesia voice synthesis](/docs/providers/voice/cartesia)
## Eleven v3 is available for voice agents
ElevenLabs' most expressive model, `eleven_v3_conversational`, can now be selected as a synthesizer. It supports **74 languages**, including Hindi, Tamil, Bengali, Marathi, Gujarati, Kannada, Malayalam, Telugu and Punjabi, and every ElevenLabs voice available in Bolna works with it.
One thing to know before switching an agent over: `speed`, `style` and `similarity_boost` have no effect on v3, and `temperature` maps to three stability presets (`0.0` creative, `0.5` natural, `1.0` robust).
Turbo remains the default and the lower-latency option.
[ElevenLabs voice synthesis](/docs/providers/voice/elevenlabs)
## Sarvam saaras:v4 Transcriber Support
Bolna now supports Sarvam's **saaras:v4** transcriber model — the latest Saaras speech-to-text model, transcribing directly in the original spoken language with automatic language detection support. Supports all 11 Indian languages.
Learn more in the [Sarvam STT documentation](/docs/providers/transcriber/sarvam).
## 🔌 Bolna joins viaSocket's app directory
If you build automations in [viaSocket](https://viasocket.com/integrations/bolna), Bolna is now a first-class app you can drop into any flow — connect your API key once, no custom code needed.
Six actions are live today:
* **Make a Phone Call** — kick off an outbound call from any workflow
* **Get All Executions** — pull call history and details into your flow
* **List Voice AI Agents** — see every agent on your account
* **List Phone Numbers** — see every number on your account
* **List Knowledgebases** — see every knowledge base on your account
* **List Providers** — see every provider connected to your account
📘 [viaSocket integration overview](/docs/tutorials/viasocket/overview) · [Create a Bolna API connection with viaSocket](/docs/tutorials/viasocket/create-bolna-api-connection)
## 🛠️ The MCP server now controls nearly your whole account
When the [Bolna MCP server](/docs/build-with-ai/mcp) launched, it covered the basics — agents, calls, transcripts, account info. It's grown into something closer to a full remote control. From the same chat window, you can now say things like:
* "Buy me a US number and route it to my support agent" — search, purchase, and set up inbound call routing
* "Create a batch campaign from this CSV and schedule it for 9am" — batches can now be created, scheduled, stopped, or deleted, not just listed
* "Add a disposition that pulls appointment\_time out of every call" — structured, typed data out of every transcript
* "Set up a SIP trunk for my Twilio account and attach these numbers" — bring your own telephony
* "Cancel every queued call for this agent" — stop one call or a whole agent's queue
* "What did my Acme Corp sub-account spend this month?" — check and manage sub-accounts, and switch between them mid-conversation with a key you already have on hand
Anything that deletes something, spends money, or places a real call still pauses for your confirmation first, same as before.
📘 [MCP Overview](/docs/build-with-ai/mcp) · [Tool List](/docs/build-with-ai/mcp-tool-list) · [Prompt Cheatsheet](/docs/build-with-ai/mcp-prompts)
## 🎙️ Maya joins Bolna as a new voice synthesizer
[Maya Research](https://www.mayaresearch.ai/)'s `Maya 2 Native` model is now available as a text-to-speech provider, with two voices — **Ananya** and **Arjun** — each covering all 11 supported languages, including Indian English.
* Runs over a persistent WebSocket, so LLM output is spoken as it streams in rather than in fixed chunks
* Language can switch mid-call without dropping the connection
* Supports both telephony (mu-law) and web (native 24 kHz) audio
📘 [Maya voice provider docs](/docs/providers/voice/maya)
# Bolna AI Updates for December, 2024
Source: https://www.bolna.ai/docs/changelog/december-2024
Explore the latest features, improvements, and API updates introduced in December 2024 for Bolna Voice AI agents.
## Batch Management Enhancements
* Download batches that have been uploaded
* Display batch call status breakdown for better tracking
## API Updates
* Batches APIs - Added breakdown for batches executions ([API doc](/docs/api-reference/batches/get_batch))
## New Features
* Added Cartesia TTS support for voice synthesis
* Implemented voicemail detection for Twilio & Plivo calls
* Enabled call hangup using prompts (see [hangup live calls on Bolna](/docs/guides/outbound/hangup-calls))
* Introduced multi-agent prompt building (see [multi-agent prompt](/docs/multi-agent-prompt))
## Major Platform Updates
* Added support for over 40+ languages (see [supported languages](/docs/customizations/multilingual-languages-support))
* Knowledgebases are now functional in all supported languages and work together with LLM-driven context (see [ingesting and using KBs](/docs/getting-started/knowledge-base))
* Revamped batches for simpler processing and management (see [using batches](/docs/guides/outbound/batch-calling))
* Added call hangup information for all calls
## Improvements & Migrations
* Changed `execution_id` notation from `{agent_id}#{timestamp}` to a unique `{uuid}` format.
* The execution ID overhaul addresses previous scaling issues and product complications.
## API Updates
#### New APIs
* Get call details using only `execution_id` ([API doc](/docs/api-reference/executions/get_execution))
* Set inbound agent programmatically ([API doc](/docs/api-reference/inbound/agent))
* Get a list of all added voices for your account ([API doc](/docs/api-reference/voice/get_all))
#### API changes
* Call APIs - Outbound calls will now return the unique `execution_id` ([API doc](/docs/api-reference/calls/make))
* Batches APIs - removed redundant need of `agent_id` wherever applicable ([API doc](/docs/api-reference/batches/overview))
* Execution APIs - removed redundant need of `agent_id` wherever applicable ([API doc](/docs/api-reference/executions/overview))
# Bolna AI Updates for December, 2025
Source: https://www.bolna.ai/docs/changelog/december-2025
Explore the latest features, improvements, and API updates introduced in December 2025 for Bolna Voice AI agents.
## Mention function calls using '@' in agent prompts
You can now mention function calls directly in your agent prompt using the `@` symbol. Simply type `@` followed by the function name to reference it in your instructions, making it easier to guide your agent on when to use specific functions.
## New Transcriber Integration: Pixa
Bolna's transcriber lineup grows with **[Pixa](/docs/providers/transcriber/pixa)**. Use it as an additional transcription backend to pick the provider that best matches your agent's domain and reliability needs.
## New Transcriber Integration: Gladia
You can now plug **[Gladia](/docs/providers/transcriber/gladia)** into Bolna for speech-to-text. This adds another strong choice for teams that want flexibility across languages and scenarios.
## New Transcriber Integration: ElevenLabs Scribe
**[ElevenLabs Scribe](/docs/providers/transcriber/elevenlabs)** is now available as a transcriber option in Bolna. This provides more flexibility for building voice AI agents across different languages and use cases.
## URL support for Knowledgebases
Knowledgebases now support [website URLs](/docs/getting-started/knowledge-base) as data sources, allowing you to ingest and reference content directly from web links.
## Improved Knowledgebase support
* Added support for multiple PDF documents which can be used together.
* Fixed issues with function calls while using knowledgebases.
* Improved retrieval accuracy and reduced response latency.
# Bolna AI Updates for February, 2025
Source: https://www.bolna.ai/docs/changelog/february-2025
Explore the latest features, improvements, and API updates introduced in February 2025 for Bolna Voice AI agents.
## Webcall Support
* Added webcall support to help users build and test their Bolna Voice AI agents directly in the browser.
## Voice Import Integration
* Integrated support for [importing voices](/docs/import-voices) from multiple providers like ElevenLabs and Cartesia, along with custom voice options — making voice agent personalization on Bolna AI smoother and more flexible than ever.
## Deepgram Nova-3 Model Support
* Added [Deepgram `nova-3` model](/docs/providers/transcriber/deepgram#4-list-of-deepgram-models-supported-on-bolna-ai) for speech to text capabilities.
## ElevenLabs Flash v2.5 Model Support
* Added [ElevenLabs `eleven_flash_v2_5` model](/docs/providers/voice/elevenlabs#4-list-of-elevenlabs-models-supported-on-bolna-ai) for text to speech capabilities.
## Improvements
* Hangup live calls automatically on [detecting silence](/docs/hangup-calls#1-using-time-based-call-hangup) and [using LLM prompts](/docs/hangup-calls#2-using-prompts-to-hangup-calls).
* Add a [hangup message](/docs/hangup-calls#adding-a-hangup-message) to be spoken while disconnecting the call
# Bolna AI Updates for February, 2026
Source: https://www.bolna.ai/docs/changelog/february-2026
Explore the latest features, improvements, and API updates introduced in February 2026 for Bolna Voice AI agents.
## Override Agent Config in /call API
The `/call` API now supports an `agent_data` parameter that lets you override agent configuration properties at call time. Currently, overriding the `voice_id` (for the same provider) is supported.
This allows you to dynamically change the voice used for a specific call without modifying the agent's default configuration.
```json Example theme={"system"}
{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+919876543210",
"agent_data": {
"voice_id": "Sam"
}
}
```
Learn more in the [Make a Phone Call API documentation](/docs/api-reference/calls/make).
## Sarvam v3 Models Support
Bolna now supports **Sarvam v3** models:
* **saaras:v3** — New transcriber model configured for direct transcription in the original spoken language. Supports all 11 Indian languages.
* **bulbul:v3** — New Sarvam TTS voice model for improved Indian language speech synthesis.
Learn more about Sarvam transcriber models in the [Sarvam STT documentation](/docs/providers/transcriber/sarvam) and voice models in the [Sarvam TTS documentation](/docs/providers/voice/sarvam).
## Deepgram: New Indian Languages Added
Bolna now supports additional **Deepgram** Indian languages for speech recognition:
* **bn** — Bengali
* **kn** — Kannada
* **mr** — Marathi
* **te** — Telugu
## API Rate Limiting
Bolna APIs now enforce rate limits to ensure fair usage and platform stability. Rate limits are applied per **organization** (if the user belongs to one) or per **user** otherwise.
**Endpoint-specific limits:**
| Endpoint | Rate Limit |
| --------------------------------- | ------------------- |
| `/v2/agent/{agent_id}/executions` | 500 requests/minute |
| `/v2/agent/{agent_id}` | 500 requests/minute |
| `/call` | 500 requests/minute |
All other API endpoints are subject to a default rate limit of **1000 requests per minute**.
Requests exceeding the limit will receive an HTTP 429 response. Learn more in the [rate limiting documentation](/docs/api-reference/rate-limiting).
## Truecaller Verification
Bolna now supports **Truecaller Verification** — users can get their phone numbers **verified on Truecaller**, so your calls show a verified identity to recipients. This helps build trust and can improve answer rates by making it clearer who’s calling.
Learn more in the [Truecaller Verification documentation](https://www.bolna.ai/docs/truecaller-verification).
# Bolna AI Updates for January, 2025
Source: https://www.bolna.ai/docs/changelog/january-2025
Explore the latest features, improvements, and API updates introduced in January 2025 for Bolna Voice AI agents.
## Bug fixes
* Execution `status` wasn't getting updated for few incoming calls with connected Twilio telephony
## API Updates
* Agent APIs - Added functionality to programmatically delete agents via APIs ([API doc](/docs/api-reference/agent/v2/delete))
## Bug fixes
* Few executions were erroneously loosing the `batch_id` mapping
# Bolna AI Updates for January, 2026
Source: https://www.bolna.ai/docs/changelog/january-2026
Explore the latest features, improvements, and API updates introduced in January 2026 for Bolna Voice AI agents.
## Vobiz Telephony Integration
* Introducing native Vobiz integration for Voice AI calling in India and global markets
* Connect your existing Vobiz account securely to Bolna for complete control over your telephony infrastructure
* Make outbound AI calls and receive inbound calls using your own Vobiz phone numbers
* Support for both dashboard-based calling and programmatic API integration
* Learn more in the [Vobiz integration documentation](/docs/vobiz)
## Auto-Retry for Failed Calls
Automatically retry calls that fail due to no-answer, busy signals, or errors. Configure retry attempts, delays, and which statuses trigger retries.
**Key features:**
* Up to 3 automatic retry attempts
* Configurable delays between retries
* Works with single calls and batch campaigns
* Webhook notifications include retry status
Learn more in the [auto-retry documentation](/docs/guides/outbound/auto-retry).
## IVR Support for Inbound Calls
Bolna now supports IVR (Interactive Voice Response) for Plivo inbound calls. Route callers to different Voice AI agents based on their menu selections.
**Key features:**
* **Menu steps** - Present options and route based on digit pressed
* **Collect steps** - Gather multi-digit input (account numbers, PINs)
* **Multi-agent routing** - Different agent per menu option
* **Conditional branching** - Build complex flows with language selection
* **Context passing** - All collected data sent to agent as context
Configure IVR via the `/inbound/setup` API by adding `ivr_config` to your request. Learn more in the [IVR documentation](/docs/guides/inbound/ivr-inbound-calls).
```json theme={"system"}
{
"ivr_config": {
"enabled": true,
"voice": "Polly.Aditi",
"welcome_message": "Welcome to Acme Corp.",
"steps": [
{
"step_id": "department",
"type": "menu",
"prompt": "Press 1 for Sales. Press 2 for Support.",
"field_name": "department",
"options": [
{"digit": "1", "label": "Sales", "agent_id": "sales-agent-id"},
{"digit": "2", "label": "Support", "agent_id": "support-agent-id"}
]
}
]
}
}
```
## Multilingual Message Auto Switching
Bolna now automatically detects the language your users speak and adapts system messages accordingly. Bolna agents analyze conversation patterns and intelligently switche messages to match the detected language.
Bolna agents are now able to identify the dominant language while handling real-world conversational scenarios where users mix languages. This ensures messages are delivered in the language users actually prefer for substantive communication.
**Currently supported message types:**
* **User online check message** - The "are you still there?" prompt when checking if users are on the call
* **Call hangup message** - Closing messages when the agent ends a call
* **Pre-function call message** - Brief wait messages while executing custom tools or API calls
Configure multilingual variants using language codes (e.g., `en`, `hi`, `ta`, etc) and Bolna handles the rest. Learn more in the [language detection documentation](/docs/customizations/auto-switch-multilingual-messages).
## Noise Cancellation During Calls
Bolna now supports noise cancellation during calls, providing clearer audio quality by filtering out background noise for both the agent and the caller.
## Auto Reschedule
Automatically reschedule calls when a user asks to be called at a specific time. The agent will intelligently detect scheduling requests and handle the rescheduling process seamlessly.
# Bolna AI Updates for July, 2025
Source: https://www.bolna.ai/docs/changelog/july-2025
Explore the latest features, improvements, and API updates introduced in July 2025 for Bolna Voice AI agents.
## Bolna AI Data Residency
* [Introducing India Data Residency](/docs/enterprise/data-residency) for enterprise-grade Voice AI, now hosted in India for compliance and improved performance.
## Phone Number Management APIs
* Search available phone numbers [using APIs](/docs/api-reference/phone-numbers/search).
* Buy available phone numbers [using APIs](/docs/api-reference/phone-numbers/buy).
* Delete and remove phone numbers [using APIs](/docs/api-reference/phone-numbers/delete).
## Rime TTS Voice Support
* Added [Rime TTS](/docs/providers/voice/rime) voices and models:
* `arcana` models and voices
* `mistv2` models and voices
## Sarvam Bulbul v2 WebSocket Integration
* Incorporated websockets for Sarvam `bulbul:v2` model to improve real-time performance.
# Bolna AI Updates for July, 2026
Source: https://www.bolna.ai/docs/changelog/july-2026
Explore the latest features and improvements introduced in July 2026 for Bolna Voice AI agents.
## 📚 Search and read the docs from your AI assistant or the terminal
You can now search and read Bolna's documentation without opening a browser — right from your AI assistant or the CLI, no login needed.
* **AI assistant:** connected over the [MCP server](/docs/build-with-ai/mcp)? Just ask something like "how do I set up a webhook?" and it finds the right page and reads it back to you, instead of guessing.
* **Terminal:** `bolna docs search ` finds the page you need, and `bolna docs fetch ` prints it right there in your terminal.
Handy when you're heads-down in code or a chat and don't want to break flow to go dig through the docs site.
📘 [MCP Tool List](/docs/build-with-ai/mcp-tool-list) · [docs search](/docs/cli/commands/docs-search) · [docs fetch](/docs/cli/commands/docs-fetch)
## 🎙️ Talk to your agent right from the browser
Want callers to talk to your voice agent without dialing a number? The new **Web Call SDK** (`@bolna/web-call`) lets you drop a live, spoken conversation straight into any web page: a landing page, a support widget, an in-app "talk to us" button, anywhere your users already are.
It's built to stay simple on the surface. Mint a short-lived call session from your own backend, point the SDK at it, and call `start()` from a button click. Your Bolna API key never has to touch the browser, and the SDK handles microphone permissions, connection setup, and cleanup for you.
A few things that make it easier to build on:
* **Copy-paste starter templates** for Next.js (deploys as-is on Vercel) and plain HTML plus Node, so you can go from nothing to a working call button in minutes.
* **A small, predictable event set,** including `call-start`, `call-end`, `error`, and `volume-level`, so you can drive your own UI instead of fighting the SDK's.
* **Practical guardrails**, like clear error codes for capacity limits and blocked autoplay, with an FAQ for the issues developers actually hit.
This is a beta release, available for any account on request. Reach out on [Slack](https://join.slack.com/t/bolnabuilders/shared_invite/zt-42zi57jyd-3yt1XDWq3kWBLj1puqq2fQ) or email [support@bolna.dev](mailto:support@bolna.dev) to have it enabled.
📘 [Web Call SDK docs](/docs/sdks/web-call)
## 🚀 Bolna CLI Beta — manage your voice agents from the terminal
We're excited to announce the public beta of the **Bolna CLI** (`bolna`), bringing agent, call, and account management to your terminal — and a full-screen dashboard when you'd rather look than type.
```bash theme={"system"}
go install github.com/bolna-ai/cli/cmd/bolna@latest
```
**What you can do**
* **Manage agents end-to-end** — list, view, create, update, and delete agents, with a before/after diff and confirmation on every change.
* **Place and track calls** — start a real outbound call, list history, and pull a full transcript, without opening the dashboard.
* **Script and pipe** — every list command supports `--json` or `--csv`, and `-q` prints bare IDs for piping into `xargs` and CI.
* **Watch it visually when you want to** — run `bolna` with no arguments for a full-screen dashboard: live wallet balance, a command palette, and a guided call-start flow.
**Built for developers**
* **Same tools as MCP** — every command maps 1:1 to a tool in the [Bolna MCP server](/docs/build-with-ai/mcp)'s list, so a script and an AI assistant work against the exact same operations.
* **Never spends money silently** — starting a call always shows your current wallet balance and asks for confirmation, unless a script explicitly passes `--yes`.
This is a beta release — commands and flags may still change as we gather feedback. Report an issue or contribute on [GitHub](https://github.com/bolna-ai/cli).
📘 [CLI Overview](/docs/cli/introduction) · [Installation](/docs/cli/installation) · [Quickstart](/docs/cli/quickstart) · [Changelog](/docs/cli/changelog)
## Bolna MCP Server — connect any AI assistant to your account
The Bolna MCP server exposes agents, calls, phone numbers, batches, and account info as typed tools to Claude, Cursor, Windsurf, Codex, Zed, or any other MCP client. Point your client at the URL, then prompt your way through the integration — no dashboard tab required.
```
URL: https://mcp.bolna.ai/api/mcp
Header: Authorization: Bearer
```
* **Check on your account** → "List my agents", "what's my wallet balance?" — quick lookups without opening the dashboard.
* **Debug a call** → "Get the last 5 executions for agent X and show me the transcript for any that failed" — the assistant chains the lookups for you.
* **Build and change agents** → "Create a Hindi lead-qualification agent using Sarvam and GPT-4o mini" — describe the change, the assistant makes the call.
* **Confirm before it acts** → `update_agent`, `delete_agent`, and `start_outbound_call` are flagged destructive in their tool definitions — most clients pause for your confirmation before running them.
No key is stored server-side — it travels with each request — and the server is [open source](https://github.com/bolna-ai/mcp).
📘 [MCP Overview](/docs/build-with-ai/mcp) · [Quickstart](/docs/build-with-ai/mcp-quickstart) · [Tool List](/docs/build-with-ai/mcp-tool-list) · [Prompt Cheatsheet](/docs/build-with-ai/mcp-prompts)
## New OpenAI models: GPT-5.6 and GPT-5.5 Pro
GPT-5.6 (Sol, Terra, Luna) and GPT-5.5 Pro are now available as LLMs for your voice agents. `gpt-5.6-sol` is the flagship for the hardest reasoning and coding, `gpt-5.6-terra` balances quality and cost for high-volume production agents, and `gpt-5.6-luna` is a fast, low-cost option for everyday voice. `gpt-5.5-pro` targets maximum quality on complex reasoning, though its latency makes it unsuitable for real-time calls.
Select any of them as the model in your agent's LLM config. See [OpenAI models](/docs/providers/llm-model/openai) for the full list and guidance.
## Multilingual static messages for graph agents
Static nodes in a [graph agent](/docs/graph-agent/static-nodes) can now hold a per-language message. Instead of a single string, `static_message` accepts a `{ "language_code": "text" }` map, and the node speaks the variant that matches the caller's active language.
Highlights:
* One pre-cached clip per language, each rendered with that language's voice, so playback stays instant with zero LLM or TTS cost at call time
* Automatically follows [language auto-switch](/docs/customizations/auto-switch-multilingual-messages), so a caller who moves to Hindi or Tamil hears the matching-language clip on the next static node
* Fully backward compatible: a plain-string `static_message` behaves exactly as before
Learn more in [Static nodes](/docs/graph-agent/static-nodes#multilingual-static-messages).
## Filter Webhooks by Call Status
You can now choose which call statuses trigger your webhook, instead of receiving a POST for every status change. This cuts noise for integrations that only care about specific outcomes (for example, only firing on `completed`).
To set it up:
* Open your agent and go to the **Extractions** tab.
* Enter your **Webhook URL** under Webhook Configuration.
* Use **Trigger on statuses** to select the statuses you want webhooks for. By default, **all statuses** are sent.
Learn more in the [Using Webhooks](/docs/guides/post-call/polling-call-status-webhooks) guide and the [Extractions Tab](/docs/agent-setup/analytics-tab) documentation.
## Router nodes for graph agents
Graph agents now support **router nodes**: silent dispatch nodes that pick the next node and hand off without ever speaking. Use them to branch on call data or caller intent, at the start of a flow or mid-flow, without adding a spoken turn.
A router node evaluates its edges in order (deterministic [expression](/docs/graph-agent/edges-and-routing) edges first, then intent-based edges, then a required catch-all) and immediately transitions to the chosen node.
Learn more in [Router nodes](/docs/graph-agent/router-nodes).
# Bolna AI Updates for June, 2025
Source: https://www.bolna.ai/docs/changelog/june-2025
Explore the latest features, improvements, and API updates introduced in June 2025 for Bolna Voice AI agents.
## Bolna AI On-Premise Offering
* Rolling out Bolna AI [On-Premise offering](/docs/enterprise/on-premise-deployments) in Private Beta for enterprise customers.
## Agent Data Ingestion Configuration
* Exposed `ingest_source_config` for agents, enabling inbound calls to ingest user data via APIs.
* The following APIs have been updated to reflect these changes:
* Get Agent API [API reference doc](/docs/api-reference/agent/v2/get)
* Create Agent API [API reference doc](/docs/api-reference/agent/v2/create)
* Update Agent API [API reference doc](/docs/api-reference/agent/v2/update)
* Patch update Agent API [API reference doc](/docs/api-reference/agent/v2/patch_update)
* List Agents API [API reference doc](/docs/api-reference/agent/v2/get_all)
## TTS Model Switching in UI Dashboard
* Enabled TTS model switching directly from the UI Dashboard for easier voice model management.
## Sub-Account API Endpoints
* Added the following APIs for sub-account management:
* Create sub-account API [API reference doc](/docs/api-reference/sub-accounts/create)
* List all sub-accounts API [API reference doc](/docs/api-reference/sub-accounts/get_all)
* Track sub-accounts usage API [API reference doc](/docs/api-reference/sub-accounts/usage)
# Bolna AI Updates for June, 2026
Source: https://www.bolna.ai/docs/changelog/june-2026
Explore the latest features and improvements introduced in June 2026 for Bolna Voice AI agents.
## Per-account concurrency for sub-accounts
Organizations can now split their concurrency pool across the main account and each sub-account using two settings per account:
* **`min_concurrency`** — concurrency guaranteed to an account even when the organization is at capacity
* **`max_concurrency`** — the account's hard cap; leave it unset for an **elastic** account that bursts into the organization's unused capacity, or set `0` to pause it
Guarantees are honored first each scheduling cycle, spare capacity is then shared fairly among accounts that still have calls waiting, and anything that doesn't fit is queued and dialed as capacity frees up. Edits are validated so per-account minimums and maximums always stay within the organization envelope.
Set the limits when you [create](/docs/api-reference/sub-accounts/create) or [update](/docs/api-reference/sub-accounts/patch_update) a sub-account (organization admins only). Learn more in [Concurrency management](/docs/enterprise/concurrency-management).
## Soniox Real-Time Transcriber (Speech to Text)
Bolna now supports **Soniox** as a streaming transcriber, powered by its real-time `stt-rt-v5` model. A single Soniox model transcribes whatever is spoken — including mid-sentence switches between English and a regional language (Hinglish and similar) — over one connection, with no per-language switching.
Highlights:
* **Native multilingual + code-switching** in a single stream
* **Semantic endpoint detection** for low-latency, natural turn-taking
* **Per-token language identification**
* Works for both telephony and web calls
Select **Soniox v5** in the Audio tab and choose the multilingual option (auto-detect) or a specific language such as Hindi. Learn more in the [Soniox transcriber documentation](/docs/providers/transcriber/soniox).
## Typed Variables for Graph Agent Routing
Expression edges in graph agents can now declare the **type** of the values they compare. Add a `variable_types` map to the graph config and both sides of a comparison are converted before matching, so a value that arrives as a string (like `"18"` or `"true"`) still compares correctly against a number or boolean.
```json theme={"system"}
"variable_types": {
"recipient_data.age": "number",
"recipient_data.hold_status": "boolean"
}
```
Supported types are `string`, `number`, and `boolean`. Learn more in [Edges & Routing](/docs/graph-agent/edges-and-routing#typed-variables).
## Per-Node Tools and Call Ending for Graph Agents
Graph agent tools can now be limited to specific nodes. Add `scope: "node"` and a `nodes` list to a tool in `tools_params`, and the LLM only sees that tool while the call is on those nodes. This prevents wrong tool calls and keeps each step focused.
```json theme={"system"}
"fetch_order_status": {
"scope": "node",
"nodes": ["collect_order", "confirm_order"]
}
```
The same control applies to ending the call: set `function_call: "end_call"` on a node (with `hangup_after_LLMCall: false`) and the call only hangs up from the nodes you choose. Learn more in [Tools & Knowledge Base](/docs/graph-agent/tools-and-rag#limiting-a-tool-to-specific-nodes).
## Visual editor for graph agents
Graph agents now have a visual editor in the dashboard. Build and edit your flow on a canvas: add nodes, draw transitions, set per-node instructions, manage variables, test the flow, and track versions, all without hand-editing JSON.
Learn more in [Using the editor](/docs/graph-agent/using-the-editor).
## Pre-call Webhooks for the Transfer Call Tool
The built-in **Transfer Call** tool can now fire a **pre-call webhook** — a notification sent to a URL of your choice *before* the call is transferred. A typical use case is sending the transfer reason to your system so a human agent has context the moment the call connects.
It uses the same two optional fields as custom tools:
* `pre_call_webhook_param` — the JSON body template to send. This is the on/off switch; if it is not set, no pre-call webhook fires.
* `pre_call_webhook_url` — where to send it. If left blank, the agent-level Webhook URL is used.
The body template supports `%(field)s` substitution from the transfer tool's runtime arguments — `%(reason)s`, `%(summary)s`, `%(call_transfer_number)s`, and `%(call_sid)s` (missing fields are sent empty). The webhook is fire-and-forget, so a slow or failing endpoint never blocks the transfer. The body is the same execution record as the post-call execution webhook, merged with your `pre_call_webhook_param` fields. In the dashboard, the Transfer Call modal adds a **Send a pre-call webhook before transfer** toggle that reveals the URL and parameters inputs.
Learn more in the [Transfer Call documentation](/docs/tool-calling/transfer-calls#pre-call-webhook).
## Global Knowledge Base for Graph Agents
Graph agents can now use one knowledge base across every node. Set `rag_config` once at the top level of the graph config and all nodes use it, while any node can still override it with its own `rag_config`. You can also search several collections at once by passing `vector_ids` instead of a single `vector_id`.
```json theme={"system"}
"rag_config": {
"vector_store": {
"provider_config": { "vector_ids": ["policies_v1", "faqs_v2"] }
},
"similarity_top_k": 10
}
```
Learn more in [Tools & Knowledge Base](/docs/graph-agent/tools-and-rag#knowledge-base).
## Studio — Production-Ready Agents from a Short Brief
Introducing **Studio** — Bolna's AI-powered prompt generation tool. Go from a short description of your use case to a fully structured, production-grade voice AI agent — no prompt engineering required.
How it works:
* Fill in a 3-step form (Identity & Goal → Conversation → Closing) or upload a document (PDF, DOCX, TXT, CSV) and let the builder extract the details automatically
* The more context you provide, the better the agent — you can do both
* The pipeline selects the right modules, writes the full prompt, runs a safety check, and auto-selects the best voice for your language and gender settings
* The agent is saved and ready to make calls when done
Click **+ New Agent → Auto Build Agent** in the dashboard to get started.
Learn more in the [Studio documentation](/docs/agent-setup/agent-builder).
## Pre-call Webhooks for Custom Function Tools
Custom function tools can now fire a **pre-call webhook** — a notification sent to a URL of your choice *before* the tool's main API call runs. A typical use case is a tool that transfers the call, where your system needs the transfer reason *before* the transfer happens.
Two new optional fields on every custom tool:
* `pre_call_webhook_param` — the JSON body template to send. This is the on/off switch; if it is not set, no pre-call webhook fires.
* `pre_call_webhook_url` — where to send it. If omitted, the agent-level Webhook URL is used.
The webhook is fire-and-forget, so a slow or failing endpoint never blocks the function call. The body is the same execution record as the post-call execution webhook, merged with your `pre_call_webhook_param` fields. The dashboard's custom tool configuration adds matching **Pre-call webhook URL** and **Pre-call webhook parameters** inputs.
Learn more in the [Pre-call Webhooks documentation](/docs/tool-calling/custom-function-calls#pre-call-webhooks).
## Bolna Skills — AI Coding Assistant Integration
Introducing [Bolna Skills](/docs/build-with-ai/skills) — structured instructions that teach AI coding assistants like **Claude Code**, **Cursor**, and **Codex** to build, deploy, and operate Bolna voice agents using natural language prompts.
Install with a single command:
```bash theme={"system"}
npx skills add bolna-ai/skills
```
Once installed, your AI assistant can:
* **Create agents** — configure LLM, voice, transcriber, telephony, and tools in one shot
* **Make calls** — place outbound calls with dynamic variables and auto-retry
* **Run batch campaigns** — launch CSV-driven outbound campaigns at scale
* **Set up inbound numbers** — wire phone numbers to agents with IVR menus
* **Debug calls** — run symptom-to-fix diagnostics using execution logs
* **Build graph agents** — create node-based call flows with deterministic routing
20 skills are available across build, call, monitor, and advanced categories. Supports Claude Code, Cursor, Codex, and any assistant compatible with the [Agent Skills](https://agentskills.io) format.
Learn more in the [Bolna Skills documentation](/docs/build-with-ai/skills).
# Bolna AI Updates for March, 2025
Source: https://www.bolna.ai/docs/changelog/march-2025
Explore the latest features, improvements, and API updates introduced in March 2025 for Bolna Voice AI agents.
## Improvements
* Enabling `strict` mode for custom tools to ensure function calls reliably adhere to the function schema, instead of being best effort.
* Updating the UI for the custom tools and improving the [documentation with examples](/docs/tool-calling/custom-function-calls).
## Dynamic Caller Identification
* Bolna Voice AI agents can now dynamically identify incoming callers in real time via:
1. using [your internal APIs](/docs/customizations/identify-incoming-callers#1-internal-api-integration-real-time-lookup) which returns records mapped to a phone number,
2. using uploaded [CSV files](/docs/customizations/identify-incoming-callers#2-csv-uploads) or
3. using publicly linked [Google Sheets](/docs/customizations/identify-incoming-callers#3-google-sheets-integration).
## Azure Transcriber Support
* Added Azure's transcriber models for speech to text.
## Improvements
* Infrastructure changes & updates to improve initial conversational latencies.
## Bolna Status Page Launch
* Launched the [Bolna Status page](https://status.bolna.ai) where you can track real-time system updates, maintenance notices, and any ongoing outage updates.
## Bug fixes
* Bolna Voice AI agents will now have the context about current `timestamp` & `timezone` automatically by default which can be used. This helps the agent compute times accurately based on your local setting.
* This can be [overridden](/docs/using-context#injecting-current-time) by passing the `timezone` as well.
# Bolna AI Updates for March, 2026
Source: https://www.bolna.ai/docs/changelog/march-2026
Explore the latest features, improvements, and API updates introduced in March 2026 for Bolna Voice AI agents.
## Custom Ambient Noise Tracks
You can now upload your own **custom ambient noise tracks** in addition to the existing presets. This gives you full control over the background soundscape of your calls.
**What's new:**
* **Upload custom tracks** via `POST /ambient-sounds/custom` — supports `wav` and `mp3` formats, up to **10 MB**
* **Delete custom tracks** via `DELETE /ambient-sounds/{sound_id}`
* **List all tracks** via `GET /ambient-sounds` — returns both presets and your custom tracks, each with a `type` field (`preset` or `custom`)
**What's changed:**
* `ambient_noise_track` now accepts the **id** of an ambient sound record instead of a preset name enum
* The three preset tracks remain available with the same IDs: `coffee-shop`, `office-ambience`, `call-center`
Ambient noise continues to be supported with **Plivo** and **Vobiz** telephony providers.
Read more in the [Call Tab documentation](/docs/agent-setup/call-tab#ambient-noise).
## Extractions - Capture Structured Data from Call Transcripts
We've added **Extractions** to automatically pull structured data from your call transcripts. Instead of manually reviewing conversations, you can set up categories and questions to extract things like lead quality, appointment details, or customer sentiment.
Here's what you can do:
* **Organize by category** - Group related extractions together (like "Visit Details" or "Lead Qualification")
* **Choose your answer format** - Use free text for open-ended responses or pre-defined options with conditional logic
* **Use variables** - Reference call data like `{name}`, `{email}`, or `{candidate_name}` in your extraction prompts
* **Test before deploying** - Try out your extractions on sample transcripts or paste in custom ones
* **Multiple access methods** - Available via Dashboard, Executions API, Webhooks, and Batch Executions
Extractions return data in this format:
```json theme={"system"}
{
"extracted_data": {
"Category Name": {
"Extraction Name": {
"subjective": "Free text response from LLM",
"objective": "Pre-defined value or null"
}
}
}
}
```
Use it for lead scoring, syncing appointments, preventing churn, compliance auditing, or general call intelligence.
Learn more in the [Using Extractions documentation](/docs/guides/prompting/using-extractions) and [Dispositions API reference](/docs/api-reference/dispositions/overview).
## Prompt Variables for Date, Time & Timezone
You can now use `{current_date}`, `{current_time}`, and `{timezone}` as variables directly in your agent prompts for more control over placement and formatting of date/time information.
| Variable | Description | Example Value |
| ---------------- | ----------------------------------- | --------------------------- |
| `{current_date}` | Current date in the user's timezone | `Wednesday, March 18, 2026` |
| `{current_time}` | Current time in the user's timezone | `02:30:15 PM` |
| `{timezone}` | Timezone name per tz database | `Asia/Kolkata` |
Read more in the [Using Context documentation](/docs/using-context#date-time--timezone).
## Ambient Noise for Calls
You can now add background ambient noise to your calls for a more natural, human-like experience. Use the `ambient_noise_track` parameter to select a preset track.
Available tracks:
* **`coffee-shop`** — Background sounds of a coffee shop environment
* **`office-ambience`** — Subtle office background noise
* **`call-center`** — Call center ambient sounds
Set `ambient_noise_track` to `None` to disable ambient noise (default).
Ambient noise is supported with **Plivo** and **Vobiz** telephony providers.
***
## In-Call Reschedule Validation
When a user asks to reschedule a call to a specific time during a conversation, the system now validates the requested time against the agent's allowed calling window before scheduling it.
**Priority order for validation:**
1. **`calling_guardrails`** — explicit `call_start_hour` / `call_end_hour` config always takes precedence
2. **Agent prompt** — if no explicit guardrails are set, the LLM reads the agent's system prompt for any mentioned time restrictions
3. **Default window (9 AM – 9 PM)** — fallback if neither of the above is configured
If the requested reschedule time falls outside the allowed window, the request is rejected entirely.
Read more in the [Calling Guardrails documentation](/docs/calling-guardrails#in-call-reschedule-validation).
***
## Vobiz Telephony Number Buying
You can now search and purchase phone numbers from **Vobiz** directly via the API and the dashboard UI. The `provider` parameter has been added to phone number search and purchase endpoints, supporting `twilio`, `plivo`, and `vobiz`.
Read more in the [Phone Numbers API documentation](/docs/api-reference/phone-numbers/search).
## Google Gemini Flash Models Support
Bolna now supports **Google Gemini** Flash models as LLM providers for voice AI agents. The following models are available:
* **gemini-2.5-flash** — Production-ready, best speed and quality balance. 1M token context window.
* **gemini-2.5-flash-lite** — Most cost-effective in the Gemini 2.5 family, optimized for low latency.
* **gemini-3-flash-preview** — Next-generation Gemini model with improved reasoning (released Dec 2025).
* **gemini-3.1-flash-lite-preview** — Fastest throughput at 363 tokens/sec, ideal for high-volume workloads (released Mar 2026).
All models support **English, Hindi, Gujarati, French, Italian, and Spanish**.
Learn more in the [Google Gemini documentation](/docs/providers/llm-model/gemini).
## Multilingual Knowledge Base Support
Knowledge bases now support **multilingual** language mode. When creating a knowledge base, set `language_support` to `multilingual` to enable cross-lingual retrieval across 100+ languages.
This enables:
* Uploading documents in any language (Hindi, Spanish, French, etc.)
* Cross-lingual retrieval — query in one language, retrieve from documents in another
Set the `language_support` parameter via the [Create Knowledgebase API](/docs/api-reference/knowledgebase/create) or through the dashboard when adding a new knowledge base.
Read more in the [Knowledge Base documentation](/docs/getting-started/knowledge-base#multilingual-knowledge-bases).
## Provision to purchase 140 & 160 series phone numbers
Bolna agents can now be triggered with 140 & 160 series phone numbers to comply with TRAI regulations.
Read about procuring these phone numbers on [Purchase special phone numbers documentation](/docs/guides/inbound/obtaining-regulated-phone-numbers).
# Bolna AI Updates for May, 2025
Source: https://www.bolna.ai/docs/changelog/may-2025
Explore the latest features, improvements, and API updates introduced in May 2025 for Bolna Voice AI agents.
## Latency Improvements for Azure TTS
* We've optimized our Azure TTS integration for significantly lower end-to-end latency, resulting in faster voice generation and snappier response times for live calls.
## Smallest.ai Lightning-v2 TTS Support
* Added support for Smallest.ai's latest `lightning-v2` TTS model for Bolna AI voice agents.
## Extended Call Duration Limit
* Extended maximum call duration to 40 minutes, allowing for longer interviews or conversations without interruption.
## Azure OpenAI Model Updates
* Added support for the following Azure OpenAI clusters:
1. `gpt-4.1` Azure OpenAI
2. `gpt-4.1-mini` Azure OpenAI
3. `gpt-4.1-nano` Azure OpenAI
4. `gpt-4o` Azure OpenAI
5. `gpt-4o-mini` Azure OpenAI
6. `gpt-4` Azure OpenAI
## ElevenLabs Multi-Context WebSocket Integration
* Updated ElevenLabs to use [`Multi-Context WebSocket`](https://elevenlabs.io/docs/cookbooks/multi-context-web-socket) for improved latency and fluency.
* The Multi-Context WebSocket greatly improves websocket handling, closures, and session contexts.
## Multilingual Support Expansion
* Bolna now supports over 100+ different languages including English (India), English (United States), English (United Kingdom), and many more.
## Updates
* Users can now top up for **\$1000 USD** in one go.
* Users can now opt for auto recharge.
## Improvements
* Latency improvements across the AI voice call stack.
* Execution pages now support filters and column selections.
## viaSocket Integration
* Added [viaSocket](/docs/integrations#external-integrations) integration with Bolna Voice AI agents.
* Tutorial: Learn how to [create a Bolna API connection with viaSocket](/docs/tutorials/viasocket/create-bolna-api-connection).
## Sarvam TTS Bulbul-v2 Support
* Added [Sarvam TTS](/docs/providers/voice/sarvam) `bulbul-v2` model for Bolna Voice AI agents.
# Bolna AI Updates for May, 2026
Source: https://www.bolna.ai/docs/changelog/may-2026
Explore the latest features and improvements introduced in May 2026 for Bolna Voice AI agents.
## Custom SIP Headers on Inbound BYOT Calls
Inbound calls on **BYOT SIP trunks** can now map custom `X-` headers from the carrier's `INVITE` (e.g. `X-CALLERNO`, `X-UCID`, `X-ACCOUNT`) into prompt variables on the agent.
Declare the headers you care about on the agent, reference them as `{caller_no}`, `{ucid}`, etc. in the prompt, and optionally use a header value as the lookup key into a CSV / API / Google Sheet data source.
Only active when the agent's telephony provider is **SIP Trunk**.
Learn more in the [Inbound SIP headers documentation](/docs/sip-trunking/byot-inbound-headers).
## Async CSV reports for large agents and batches
CSV exports from **Call History → Download Records** are now generated asynchronously when the result set is large. For these reports, Bolna queues the job, builds the CSV in the background, uploads it to secure storage, and emails the requester a download link when it is ready.
* Long-running exports no longer time out the dashboard request
* You receive an email with a download link once the report is ready
* Smaller exports continue to download inline, with no change
## Transfer Phone Number Between Sub-Accounts
You can now transfer a phone number from one sub-account (or your main account) to any other sub-account in your organisation directly from the dashboard. Click the **Transfer** action on any number in the phone numbers list, select the destination account, and confirm.
If the number is currently linked to an agent, the dialog shows a warning about the existing link before completing the transfer.
Learn more in the [Phone Numbers documentation](/docs/api-reference/phone-numbers/overview).
## Welcome Message: Ignore User Speech Now Available to All
The **Ignore user speech before welcome message** toggle in the Agent tab is now available to all accounts. When enabled, any speech from the user before the agent delivers its opening greeting is discarded, preventing premature interruptions on calls where the agent speaks first.
Learn more in the [Agent Tab documentation](/docs/agent-setup/agent-tab).
## Search Call History by Phone Number
The call history filter now includes a phone number search field. Enter a number to filter executions to calls involving that number.
## Call History: Multi-Select Filters and Agent Search
The call history page has been updated with several improvements:
* **Multi-select filters:** Filter by status, call type, provider, batch ID, and date range using multi-select controls.
* **Searchable agent picker:** The agent dropdown now has a live search field so you can find the right agent quickly regardless of how many agents are in your account.
* **Execution detail view:** Clicking an execution opens a dedicated detail panel.
Learn more in the [Call History documentation](/docs/agent-setup/call-history).
## Improved Prompt Editor
We’ve made the following improvements to enhance the prompt-writing experience:
* **Typed inline chips:** Variables (e.g. `{name}`, `{email}`) and function-tool references are inserted as chips with scope-aware colours, making the structure of your prompt visible at a glance.
* **Prompt library modules splice in:** Inserting a module from the prompt library copies its content directly into the editor. No live link is kept, so module updates don't silently change deployed agent prompts.
* **Live token counter:** An estimated token count updates as you type, helping you stay within model context limits.
* **Module tags and categories:** The prompt library picker now shows tags and category badges on each module for faster scanning.
* **Multilingual:** All language tabs in multilingual agents use the rich editor.
Learn more in the [Agent Tab documentation](/docs/agent-setup/agent-tab).
## SIP trunks — TCP, TLS, and audio encryption
You can now create BYOT SIP trunks over TCP or TLS, and turn on end-to-end audio encryption on TLS trunks. See [SIP trunk setup](/docs/sip-trunking/byot-setup).
## Recording URLs Moving to Bolna-Hosted Endpoint — Action Required by June 1
Direct Amazon S3 recording URLs will stop working after **June 1, 2026**. If your integration stores, parses, or fetches recording URLs, you must update it before that date.
Starting June 1, call recording URLs will be served through a stable Bolna-hosted endpoint instead of raw Amazon S3 URLs.
**New endpoint format:**
```
https://api.bolna.ai/recordings/call/{execution-id}
https://api.bolna.ai/recordings/transfer/{execution-id}
```
Use the `transfer` variant if the call included a transfer leg.
**Previous format (will stop working after June 1):**
```
https://bolna-recordings-india.s3.amazonaws.com/{vendor}/{file}.mp3
```
**Where the new URLs appear:**
* `GET /executions/{execution-id}` — `telephony_data.recording_url` and `transfer_call_data.recording_url`
* Post-call webhook payloads — the `recording_url` field
* Dashboard — already updated
The Bolna endpoint is permanent and stable. The **resolved pre-signed link it returns expires after 24 hours** — do not store or cache it. Store the `execution-id` and call the endpoint fresh each time you need playback or download access.
**What to do before June 1:**
1. Audit anywhere your system stores, forwards, parses, or fetches recording URLs — CRMs, dashboards, post-call webhooks, data pipelines.
2. Update base URL handling to call `https://api.bolna.ai/recordings/call/{execution-id}` instead of the raw S3 URL.
3. Remove any caching of the resolved pre-signed link; always fetch fresh.
4. Test your updated integration while direct S3 URLs are still active.
**Why this change?** Recordings are stored in private S3 buckets that require a signed URL for access. The new endpoint handles signing on your behalf, removes direct exposure of bucket structure, and enforces access controls at the Bolna layer.
If you have questions, contact [support@bolna.ai](mailto:support@bolna.ai).
## OpenAI Realtime Transcriber — GA with gpt-realtime-whisper
The OpenAI Realtime transcriber is now generally available on Bolna using the `gpt-realtime-whisper` model. This replaces the previous alpha model (`gpt-transcribe-alpha-walrus`) and connects via OpenAI's GA `?intent=transcription` WebSocket endpoint.
**What's new:**
* Model updated to `gpt-realtime-whisper` — OpenAI's natively streaming transcription model
* Server-side VAD is built into the model — no manual endpointing configuration required
* Streaming interim transcript deltas arrive as the caller speaks
* `effort` parameter renamed to `delay` for clarity (controls latency vs accuracy trade-off)
* Optional near-field noise reduction toggle
Set `provider: "openai"` and `model: "gpt-realtime-whisper"` in your transcriber configuration to use it.
Learn more in the [OpenAI Realtime Transcriber documentation](/docs/providers/transcriber/openai).
## Deepgram Flux Transcriber — Now Available
Bolna now supports **Deepgram Flux**, a next-generation transcription engine built for real-time voice AI. Flux models have turn detection built directly into the model, replacing external VAD-based endpointing with a richer event stream that lets agents respond sooner and handle barge-ins more accurately.
**Two models are available:**
* `flux-general-en` — English-optimised Flux model
* `flux-general-multi` — Multilingual Flux model with built-in Language Identification
**What's new:**
* **Configurable EndOfTurn Threshold** (`eot_threshold`) — control how confident the model must be before committing to a final transcript
* **EndOfTurn Timeout** (`eot_timeout_ms`) — maximum silence window before forcing a turn end, from 300 ms to 3 s
* **Eager EndOfTurn** — Bolna can start an LLM request speculatively on `EagerEndOfTurn`, cutting perceived response latency; if the speaker continues (`TurnResumed`), the request is cancelled
* **Language Identification** (`flux-general-multi` only) — detected languages are returned per turn, enabling dynamic multilingual handling without pre-configuring a language
Learn more in the [Deepgram Flux Transcriber documentation](/docs/providers/transcriber/deepgram-flux).
## Custom Headers for Webhooks
You can now send **custom HTTP headers** along with your execution-data webhook from the agent's **Extractions** tab. Toggle **Add headers** next to the webhook URL and provide a JSON object of header key-value pairs — Bolna will include them on every webhook delivery for that agent.
This makes it easier to authenticate webhook requests against your own services (for example, by sending an `Authorization` token, an API key, or a tenant identifier) without needing a proxy in front of your endpoint.
Learn more in the [Extractions Tab documentation](/docs/agent-setup/analytics-tab).
## Graph Agents
Build structured, multi-step voice conversations as a graph of **nodes** instead of one large prompt. Each node has its own instructions and transition rules, so you control exactly what the agent does at each step and when it moves on.
Launch highlights:
* **Static nodes**: pre-cached audio for fixed messages like greetings, confirmations, and goodbyes that play instantly with zero LLM or TTS cost
* **Event injection**: drive proactive transitions from external events mid-call
* Per-node prompts, edges, and transition conditions for precise control of the flow
Learn more in [Graph Agents](/docs/graph-agent/introduction).
# Bolna AI Updates for November, 2025
Source: https://www.bolna.ai/docs/changelog/november-2025
Explore the latest features, improvements, and API updates introduced in November 2025 for Bolna Voice AI agents.
## Support for AiSensy WhatsApp messaging
Bolna now supports **AiSensy** for sending WhatsApp messages, enabling seamless WhatsApp outreach as part of your workflows and campaigns.
## Configurable Style exaggeration parameter for ElevenLabs
We've added **Style Exaggeration** controls for ElevenLabs voices, allowing you to fine-tune how expressive and stylistic the generated speech sounds.
* Increase exaggeration for more dramatic, expressive delivery.
* Reduce it for a more neutral and natural speaking style.
## Revamped workflows and campaigns
Bolna workflows and campaigns have been refreshed for a smoother build-and-run experience. Follow the step-by-step guide in [this doc](/docs/workflows-and-campaigns#creating-workflows) to create and launch workflows.
* Build multi-step outreach flows with calls, WhatsApp, and email automation.
## Detailed latency metrics for Voice AI calls
Bolna now provides comprehensive latency metrics for every Voice AI call. Learn more in the [latencies](/docs/concepts/call-latencies) documentation.
* Monitor and optimize the performance of your conversational AI agents.
* Gain clear visibility into where time is spent across the conversation pipeline.
* Analyze latency using overall averages and percentiles such as P50, P90, and P95.
## We've added new configurable voice parameters for finer control over ElevenLabs TTS output:
* **Similarity Boost** – Adjusts how closely the generated voice matches the original reference voice.
* **Stability** – Controls variation in tone and expression, helping balance naturalness with consistency.
## Voice cloning available for Cartesia `sonic-3` models
* You can now clone your voices using Cartesia's latest `sonic-3` text-to-speech model for the following languages:
| Language | Language code | BCP Format |
| --------- | ------------- | ---------- |
| English | en | bn-IN |
| Bengali | bn | bn-IN |
| Gujarati | gu | gu-IN |
| Hindi | hi | hi-IN |
| Kannada | kn | kn-IN |
| Malayalam | ml | ml-IN |
| Marathi | mr | mr-IN |
| Punjabi | pa | pa-IN |
| Tamil | ta | ta-IN |
| Telugu | te | te-IN |
# Bolna AI Updates for October, 2025
Source: https://www.bolna.ai/docs/changelog/october-2025
Explore the latest features, improvements, and API updates introduced in October 2025 for Bolna Voice AI agents.
## Stop Agent Queued Calls API
* Introducing a new API endpoint to stop all queued calls for a specific agent
* Prevents any pending calls from being executed, giving you better control over agent call management
* Use this endpoint to cancel all calls currently in the queue waiting to be executed
* Useful for scenarios where you need to immediately halt all pending operations for an agent
* Learn more in the [Stop Agent Queued Calls API documentation](/docs/api-reference/agent/v2/stop)
## Unsiloed Document Parser Integration
* Integrated [Unsiloed](https://unsiloed.ai) as the parsing engine for knowledgebase PDFs, alongwith [LlamaParse](https://www.llamaindex.ai/llamaparse) as fallback.
* Significantly improved accuracy for documents with complex tables, forms, and structured data
* Uses UnsiloedHawk OCR engine with semantic layout detection for better text extraction
* High-resolution processing ensures accurate capture of details from charts, diagrams, and small text
* Learn more in the [Knowledgebases documentation](/docs/getting-started/knowledge-base)
## Cartesia Sonic-3-Preview Model Support for Indian multilingual voices
* Added support for Cartesia's latest `sonic-3-preview` text-to-speech model including support for the following languages:
| Language | Language code | BCP Format |
| --------- | ------------- | ---------- |
| English | en | bn-IN |
| Bengali | bn | bn-IN |
| Gujarati | gu | gu-IN |
| Hindi | hi | hi-IN |
| Kannada | kn | kn-IN |
| Malayalam | ml | ml-IN |
| Marathi | mr | mr-IN |
| Punjabi | pa | pa-IN |
| Tamil | ta | ta-IN |
| Telugu | te | te-IN |
* Enhanced voice quality and naturalness for AI voice agents using Cartesia TTS
* The `sonic-3-preview` model delivers improved expressiveness and prosody for conversational AI applications
* Available for all Cartesia TTS integrations in Bolna voice agents
* Learn more in the [Cartesia TTS documentation](/docs/providers/voice/cartesia)
## Exotel Telephony Integration
* Introducing native Exotel integration for Voice AI calling in India and global markets
* Connect your existing Exotel account securely to Bolna for complete control over your telephony infrastructure
* Make outbound AI calls and receive inbound calls using your own Exotel phone numbers
* Support for both dashboard-based calling and programmatic API integration
* Learn more in the [Exotel integration documentation](/docs/exotel)
## Remove Inbound Agent API
* Introducing the ability to programmatically remove and unlink Bolna Voice AI agents from phone numbers
* Use this API to remove the association between an agent and a phone number when the agent is no longer needed for handling inbound calls
* Learn more in the [Remove Inbound Agent API documentation](/docs/api-reference/inbound/unlink)
## RAG Performance & Accuracy Improvements
* **ONNX-optimized reranking**: Sub-second query times with parallel execution for faster, more accurate document retrieval
* **MPNet embeddings**: Switched to `all-mpnet-base-v2` model for better semantic understanding of user queries
* **Table extraction**: Specialized processor preserves table structure, numeric data, and formatting from PDFs
* **Multi-collection queries**: Agents can now search across multiple knowledgebases simultaneously for comprehensive context
* Learn more in the [Knowledgebases documentation](/docs/getting-started/knowledge-base)
## Sub-account Deletion API
* Introducing the ability to programmatically delete sub-accounts and all their associated data through the API
* The Sub-account Deletion API enables better account lifecycle management by allowing you to:
* Remove test or development sub-accounts that are no longer needed
* Clean up sub-accounts for clients who have churned or ended their service
* Maintain a clean organizational structure by removing inactive sub-accounts
* When a sub-account is deleted, **ALL** associated data is permanently removed, including:
* All agents configured under that sub-account
* All batch calling data and records
* All execution history and call logs
* All configurations and settings
* Learn more in the [Sub-account Deletion API documentation](/docs/api-reference/sub-accounts/delete)
# Bolna AI Updates for September, 2025
Source: https://www.bolna.ai/docs/changelog/september-2025
Explore the latest features, improvements, and API updates introduced in September 2025 for Bolna Voice AI agents.
## Phone Number Compliance Application Requirement
* Introduced mandatory compliance application process for purchasing phone numbers on Bolna platform
* Users must now submit business verification documents before purchasing dedicated phone numbers:
* CIN (Corporate Identification Number) certificate
* GST registration details and certificate
* One-time application with 12-24 hour review process
* Enhanced security and regulatory compliance for telecommunications services
* Learn more:
* [Compliance Requirements Overview](/docs/compliance-application/introduction) - Understand why compliance is required and what documents you need
* [Step-by-Step Submission Guide](/docs/compliance-application/how-to-submit-guide) - Complete walkthrough of the application process
## Added Anthropic support for LLM
* Support for the following [Anthropic](/docs/providers/llm-model/anthropic) models. Learn more about Anthropic models from their [official website](https://www.anthropic.com).
1. `claude-sonnet-4`
## Added Sarvam and AssemblyAI transcriber support
* [Sarvam](/docs/providers/transcriber/sarvam) transcriber for Speech to Text (STT) capabilities with 11 Indian languages including English, Hindi, Bengali, Tamil, Telugu, Kannada, Malayalam, Marathi, Gujarati, Punjabi, and Odia.
* [AssemblyAI](/docs/providers/transcriber/assemblyai) transcriber for Speech to Text (STT) capabilities with real-time English streaming capabilities
## Concurrency model at sub-account scope
* Concurrency limits can now be configured at the sub-account level, allowing multiple calls or batches to run in parallel instead of being queued one after another. See how to configure concurrency when creating a sub-account in the ([API doc](/docs/api-reference/sub-accounts/create))
## Batch Webhook Notifications
* Users can now attach a webhook URL to a batch at upload time. When the batch status changes — `processed`, `scheduled`, `queued`, `running`, `completed` or `stopped`, webhook updates will be sent automatically to track the progress of batches in real time.
## Voice AI Agents Template Library
The Voice AI Agents library now includes the following pre-built template agents to help you get started quickly with Bolna Voice AI:
* [Recruitment Voice AI agent](/docs/voice-agents/recruitment-agent)
* [Customer Support Voice AI agent](/docs/voice-agents/customer-support-agent)
* [Cart Abandonment Voice AI agent](/docs/voice-agents/cart-abandonment-agent)
* [Lead Qualification Voice AI agent](/docs/voice-agents/lead-qualification-agent)
* [Onboarding Voice AI agent](/docs/voice-agents/onboarding-agent)
* [Front Desk Voice AI agent](/docs/voice-agents/front-desk-agent)
* [COD Confirmation Voice AI agent](/docs/voice-agents/cod-confirmation-agent)
* [Announcements Voice AI agent](/docs/voice-agents/announcements-agent)
* [Reminders Voice AI agent](/docs/voice-agents/reminders-agent)
* [Surveys Voice AI agent](/docs/voice-agents/surveys-agent)
* [Property Tech Voice AI agent](/docs/voice-agents/property-tech-agent)
* [Dentist Appointment Voice AI agent](/docs/voice-agents/dentist-appointment-agent)
* [Salon Booking Voice AI agent](/docs/voice-agents/salon-booking-agent)
* [Weekend Planner Voice AI agent](/docs/voice-agents/weekend-planner-agent)
* [Sales Credit Card Voice AI agent](/docs/voice-agents/sales-credit-card-agent)
* [Sales Loans Voice AI agent](/docs/voice-agents/sales-loans-agent)
## API Updates
* Cumulative view of all sub-account usage ([API doc](/docs/api-reference/sub-accounts/all_usage))
## API Updates
* Outbound calls in `queued` or `scheduled` state can be stopped before executions ([API doc](/docs/api-reference/calls/stop_call))
## Passing headers in Custom Function tools
* Passing custom `headers` is now supported on [function tooling](/docs/tool-calling/custom-function-calls).
# Authentication
Source: https://www.bolna.ai/docs/cli/authentication
Set up Bolna CLI authentication using login and environment variables, including where the key is stored and the priority order the CLI uses to resolve it.
## Get Your API Key
1. Log in to the [Bolna Dashboard](https://platform.bolna.ai)
2. Go to **Developers**
3. Create a new API key or copy an existing one
## Authentication Methods
The CLI resolves authentication using this priority order:
| Priority | Method | When to Use | Duration |
| -------- | -------------------------- | ---------------------------------------- | ------------- |
| 1 | Environment Variable | **CI/CD pipelines, containers, servers** | Session-based |
| 2 | Stored login (OS keychain) | **Local, interactive use** | Persistent |
### Environment Variable
**Best for CI/CD jobs, containers, or scripts.** Define it once per session and every command uses it — no keychain lookup happens at all.
```bash theme={"system"}
export BOLNA_API_KEY="your-api-key"
```
### Stored Login
**Best for local, day-to-day use.** [`bolna login`](/docs/cli/commands/login) validates your key live, then stores it in your OS's native credential store — never in a plaintext file.
```bash theme={"system"}
bolna login
```
| Platform | Backend |
| -------- | -------------------------- |
| macOS | Keychain |
| Linux | Secret Service (via D-Bus) |
| Windows | Credential Manager |
Remove it with [`bolna logout`](/docs/cli/commands/logout).
**Multiple accounts?** Every auth command accepts `--profile ` (see [Global Flags](/docs/cli/global-flags)), so you can keep separate credentials for separate Bolna accounts side by side — `bolna login --profile client-acme`, then `bolna agents list --profile client-acme`. Omitting `--profile` uses a default profile.
***
## Never a Dead End
Any command that needs auth — including bare `bolna` opening the dashboard — checks for credentials first. If none are configured **and you're on a real terminal**, it offers to log you in right there instead of erroring out:
```
$ bolna agents list
No API key found for profile "default".
Would you like to log in now? (y/n) y
? Bolna API key: ****************************************
✓ Verified — logged in as ops@acme.com
NAME STATUS ID
Front Desk Concierge active 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
...
```
It logs in, then falls straight through into the command you originally ran. In a non-interactive context (a script, a pipe, CI), this prompt never appears — it fails fast with a clear error instead, since there's no one there to answer it.
## Security Best Practices
* **Do not commit API keys** in scripts, repositories, or configuration files.
* Prefer **environment variables** in CI/CD, since the keychain isn't available in most containers.
* **Rotate API keys regularly** and scope keys to the minimum access required.
## Commands
# Autocompletion
Source: https://www.bolna.ai/docs/cli/autocompletion
Generate shell autocompletion scripts for the Bolna CLI in bash, zsh, fish, or PowerShell so you can tab-complete commands and flags without typos.
Autocomplete commands and flags with the press of tab to avoid typos and for ease of use.
## Shell Setup
This script depends on the `bash-completion` package. If it isn't installed already, install it via your OS's package manager.
### Setup completions for current shell session
```bash theme={"system"}
source <(bolna completion bash)
```
### Persistent setup for all sessions
```bash theme={"system"}
# Linux
bolna completion bash > /etc/bash_completion.d/bolna
# macOS
bolna completion bash > $(brew --prefix)/etc/bash_completion.d/bolna
```
You'll need to start a new shell for this to take effect.
If shell completion isn't already enabled in your environment, enable it once:
```bash theme={"system"}
echo "autoload -U compinit; compinit" >> ~/.zshrc
```
### Setup completions for current shell session
```bash theme={"system"}
source <(bolna completion zsh)
```
### Persistent setup for all sessions
```bash theme={"system"}
# Linux
bolna completion zsh > "${fpath[1]}/_bolna"
# macOS
bolna completion zsh > $(brew --prefix)/share/zsh/site-functions/_bolna
```
You'll need to start a new shell for this to take effect.
### Setup completions for current shell session
```bash theme={"system"}
bolna completion fish | source
```
### Persistent setup for all sessions
```bash theme={"system"}
bolna completion fish > ~/.config/fish/completions/bolna.fish
```
You'll need to start a new shell for this to take effect.
### Setup completions for current shell session
```powershell theme={"system"}
bolna completion powershell | Out-String | Invoke-Expression
```
### Persistent setup for all sessions
Add the output of the above command to your PowerShell profile:
```powershell theme={"system"}
bolna completion powershell >> $PROFILE
```
You'll need to start a new shell for this to take effect.
***
## Flags
| Flag | Description |
| ------------------- | ------------------------------------------- |
| `--no-descriptions` | Disable completion descriptions |
| `-h, --help` | Show help for the specific shell completion |
## Verify your setup
```bash theme={"system"}
bolna
bolna agents
bolna --
```
# CLI Changelog
Source: https://www.bolna.ai/docs/cli/changelog
Browse the Bolna CLI changelog for release notes covering new commands, bug fixes, and breaking changes across every beta version.
The Bolna CLI Changelog tracks every release — new commands, bug fixes, and breaking changes. The [GitHub Releases page](https://github.com/bolna-ai/cli/releases) is the authoritative source; this page summarizes each one in the same format.
## Release History
Adds a new **Utility** command group for reading Bolna's own documentation — no `bolna login` or API key required.
* `docs search ` — search Bolna's documentation index (`llms.txt`) by title, description, and path, ranked best-match-first
* `docs fetch ` — fetch one documentation page as rendered Markdown, accepting a bare path, a path with `.md`, or a full URL
* `doctor` moves into the same **Utility** group, alongside `version` — it doesn't touch account data either
First public beta of `bolna-cli`.
* `agents` — `list`, `view`, `create`, `update`, `delete`
* `call start`, `calls list`, `calls view`
* `numbers list`, `batches list`
* `login`, `logout`, `whoami`
* `doctor`, `version`, `completion`
* Full-screen dashboard (`bolna` with no arguments), built on the [Charm](https://charm.sh) TUI stack
`bolna-cli` is pre-1.0 — expect breaking changes between beta releases. See [Versioning](/docs/cli/versioning) for what to expect and how to pin a version in CI.
# Create an agent with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/agents-create
Use the bolna agents create command to create a new agent interactively or from a JSON config file.
Create a new agent. On a real terminal with no `--file` flag, this walks you through an interactive wizard; pass `--file` to create from a raw JSON config instead. Maps to the `create_agent` MCP tool.
## Syntax
```bash theme={"system"}
bolna agents create [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `-h, --help` | Show help for the command | – |
| `--file string` | Path to a JSON file with a full `agent_config` + `agent_prompts` payload, matching the [Create Agent](/docs/api-reference/agent/v2/create) API body | – |
| `-o, --output string` | Output format: `table` or `json` | `table` |
`--file` is required in a non-interactive context (a script or CI pipe) — there's no wizard to fall back to without a terminal.
## Example
```bash theme={"system"}
# Interactive wizard
bolna agents create
# Create from a JSON config file
bolna agents create --file config.json
```
```json config.json theme={"system"}
{
"agent_config": {
"agent_name": "Front Desk Concierge",
"agent_welcome_message": "Hi, thanks for calling Acme — how can I help?",
"tasks": [
{
"tools_config": {
"llm_agent": { "provider": "openai", "model": "gpt-4o-mini" },
"synthesizer": { "provider": "sarvam", "voice": "Maya" }
}
}
]
},
"agent_prompts": {
"task_1": { "system_prompt": "## Role\nYou are a front-desk concierge for Acme Corp..." }
}
}
```
# Delete an agent with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/agents-delete
Use the bolna agents delete command to permanently delete an agent, requiring its exact name to confirm.
Permanently delete an agent and its history. Maps to the `delete_agent` MCP tool. This cannot be undone.
## Syntax
```bash theme={"system"}
bolna agents delete [flags]
```
## Flags
| Flag | Description | Default |
| ------------ | ---------------------------- | -------- |
| `-h, --help` | Show help for the command | – |
| `--yes` | Skip the confirmation prompt | Disabled |
## Example
```bash theme={"system"}
bolna agents delete 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
```
```
You are about to permanently delete:
Front Desk Concierge (3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02)
This cannot be undone. Type the agent name to confirm: Front Desk Concierge
✓ Deleted agent 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
```
```bash theme={"system"}
# Skip the name confirmation, for scripting
bolna agents delete 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 --yes
```
`--yes` skips the name-confirmation entirely. Only use it in scripts you trust with the exact agent ID — there's no dry-run flag.
# List agents with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/agents-list
Use the bolna agents list command to list every agent in the account, with options for pagination and bare-ID output.
List every agent on the account with pagination. Returns name, status, and ID. Maps to the `list_agents` MCP tool.
## Syntax
```bash theme={"system"}
bolna agents list [flags]
```
Alias: `bolna agents ls`
## Flags
| Flag | Description | Default |
| --------------------- | ---------------------------------------- | -------- |
| `-h, --help` | Show help for the command | – |
| `--page int` | Page number to fetch | `1` |
| `--page-size int` | Results per page | `20` |
| `-q, --quiet` | Print only the bare agent ID per row | Disabled |
| `-o, --output string` | Output format: `table`, `json`, or `csv` | `table` |
Use `-o json` for machine-readable output, `-o csv` for a spreadsheet. Default `-o table` prints a human-friendly table.
## Example
```bash theme={"system"}
# List agents
bolna agents list
# List with custom page size
bolna agents list --page-size 50
# Page through results
bolna agents list --page 2
# Bare IDs, piped into another command
bolna agents list -q | xargs -I{} bolna agents view {}
# Export to CSV
bolna agents list -o csv > agents.csv
```
# Bolna agents CLI commands and flags
Source: https://www.bolna.ai/docs/cli/commands/agents-overview
Reference for the bolna agents CLI commands and flags used to list, view, create, update, and delete agents from your terminal.
Manage [agents](/docs/agent-setup/overview). Subcommands let you list, view full config, create, update, and delete agents in your account. Each command maps to a tool in the [Bolna MCP server](/docs/build-with-ai/mcp)'s tool list.
## Syntax
```bash theme={"system"}
bolna agents [command]
```
## Commands
| Command | Description |
| ---------------------------------------------- | ----------------------------------------------------------- |
| [`agents list`](/docs/cli/commands/agents-list) | List agents in the account |
| [`agents view`](/docs/cli/commands/agents-view) | Get an agent's full config |
| [`agents create`](/docs/cli/commands/agents-create) | Create a new agent |
| [`agents update`](/docs/cli/commands/agents-update) | Update an agent's name, prompt, welcome message, or webhook |
| [`agents delete`](/docs/cli/commands/agents-delete) | Permanently delete an agent |
***
## Inherited Global Flags
This command also supports [Global Flags](/docs/cli/global-flags), such as:
* `-o, --output` – Output format: `table`, `json`, or `csv`
* `--profile` – Credential profile to use
* `-v, --verbose` – Verbose logging
* `-n, --no-color` – Disable color output
# Update an agent with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/agents-update
Use the bolna agents update command to change an agent's name, prompt, welcome message, or webhook, with a before/after diff and confirmation.
Update one or more fields on an existing agent. Shows a before/after diff and requires confirmation before applying. Maps to the `update_agent` MCP tool.
## Syntax
```bash theme={"system"}
bolna agents update [flags]
```
Pass at least one flag to update directly, or run with none on a real terminal for an interactive wizard.
## Flags
| Flag | Description | Default |
| ------------------ | --------------------------------------------------------- | -------- |
| `-h, --help` | Show help for the command | – |
| `--name string` | New agent name | – |
| `--welcome string` | New welcome message | – |
| `--prompt string` | New system prompt. Pass `@file.md` to read it from a file | – |
| `--webhook string` | New webhook URL for call status/execution updates | – |
| `--yes` | Skip the confirmation prompt | Disabled |
## Example
```bash theme={"system"}
# Update the welcome message
bolna agents update 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 \
--welcome "Thanks for calling Acme Support — how can I help today?"
```
```
Agent: Front Desk Concierge (3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02)
Welcome message
- Hi, thanks for calling Acme — how can I help?
+ Thanks for calling Acme Support — how can I help today?
Apply this change? (y/n) y
✓ Updated agent 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
```
```bash theme={"system"}
# Update the system prompt from a file
bolna agents update 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 --prompt @new-prompt.md
# Skip confirmation, for CI
bolna agents update 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 \
--welcome "Thanks for calling Acme — one moment." --yes
```
# View an agent with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/agents-view
Use the bolna agents view command to fetch an agent's full config, including welcome message and system prompt, by ID.
Retrieve full configuration for a single agent by ID. Returns name, status, welcome message, and system prompt, with the prompt rendered as Markdown. Maps to the `get_agent` MCP tool.
## Syntax
```bash theme={"system"}
bolna agents view [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | -------------------------------------------------------------------------------------------- | -------- |
| `-h, --help` | Show help for the command | – |
| `--png` | Also export the card as a PNG, via the [Freeze](https://github.com/charmbracelet/freeze) CLI | Disabled |
| `-o, --output string` | Output format: `table` or `json` | `table` |
## Example
```bash theme={"system"}
# View an agent
bolna agents view 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
# Export the card as a PNG
bolna agents view 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 --png
# Get raw config for scripting
bolna agents view 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 --output json
```
Not sure of the agent ID? Run [`bolna agents list`](/docs/cli/commands/agents-list) first, or open the [dashboard](/docs/cli/dashboard/overview) and press `:` to fuzzy-search by name.
# List batches with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/batches-list
Use the bolna batches list command to view batch calling campaigns for one agent, with status and schedule.
List batch calling campaigns for one agent. Returns batch ID, status, scheduled time, and created date. Maps to the `list_batches` MCP tool.
## Syntax
```bash theme={"system"}
bolna batches list [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | ---------------------------------------- | -------- |
| `-h, --help` | Show help for the command | – |
| `-q, --quiet` | Print only the bare batch ID per row | Disabled |
| `-o, --output string` | Output format: `table`, `json`, or `csv` | `table` |
## Example
```bash theme={"system"}
bolna batches list 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
```
```
BATCH ID STATUS SCHEDULED CREATED
a91c2e4f-6b3d-4a8e-9f1c-2d5b7e8a3c60 completed 2026-07-15 10:00 2026-07-14 16:22
c4d8e1f2-3a9b-4d5c-8e7f-1a2b3c4d5e60 scheduled 2026-07-22 09:00 2026-07-18 12:10
```
```bash theme={"system"}
# Any batch still running or scheduled
bolna batches list 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 --output json \
| jq -r '.[] | select(.status == "running" or .status == "scheduled")'
```
Creating, scheduling, and stopping a batch — including the CSV of recipients and per-recipient variables — is currently done through the [Batches API](/docs/api-reference/batches/overview). `bolna batches list` is read-only.
# Start a call with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/call-start
Use the bolna call start command to place a real outbound call, with a wallet balance check and confirmation before dialing.
Place a real outbound call using the given agent. Spends real account balance. Always shows your wallet balance and requires confirmation before dialing. Maps to the `start_outbound_call` MCP tool.
## Syntax
```bash theme={"system"}
bolna call start --to [flags]
```
## Flags
| Flag | Description | Default |
| --------------- | ------------------------------------------------------------------ | ------------------------- |
| `-h, --help` | Show help for the command | – |
| `--to string` | Recipient's number in E.164 format, e.g. `+14155551234` (required) | – |
| `--from string` | Caller-ID override | agent's configured number |
| `--yes` | Skip the confirmation prompt | Disabled |
## Example
```bash theme={"system"}
bolna call start 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 --to +14155551234
```
```
Agent Front Desk Concierge
Recipient +14155551234
Balance $482.19
Place this call now? (y/n) y
✓ Call started — execution b7140255-af33-4608-8e97-04dd944b8e48
Track it with:
bolna calls view b7140255-af33-4608-8e97-04dd944b8e48
```
```bash theme={"system"}
# Override the caller ID
bolna call start 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 \
--to +14155551234 --from +14155559999
# Skip confirmation, for scripting
bolna call start 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 \
--to +14155551234 --yes
```
Prefer a visual flow? Press `s` from an agent's detail view in the [dashboard](/docs/cli/dashboard/starting-a-call) for the same confirmation, guided through screens.
# List calls with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/calls-list
Use the bolna calls list command to view call history for one agent, with options to filter by date range.
List call history for one agent with pagination. Returns status, duration, recipient, and created date. Defaults to the last 7 days. Maps to the `list_agent_executions` MCP tool.
## Syntax
```bash theme={"system"}
bolna calls list [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | ---------------------------------------- | ---------- |
| `-h, --help` | Show help for the command | – |
| `--from string` | Start of the date range, ISO 8601 | 7 days ago |
| `--to string` | End of the date range, ISO 8601 | today |
| `--page int` | Page number to fetch | `1` |
| `--page-size int` | Results per page | `20` |
| `-q, --quiet` | Print only the bare execution ID per row | Disabled |
| `-o, --output string` | Output format: `table`, `json`, or `csv` | `table` |
## Example
```bash theme={"system"}
# Last 7 days, default view
bolna calls list 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
# A specific date range
bolna calls list 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 \
--from 2026-07-01 --to 2026-07-19
# Export to CSV
bolna calls list 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 -o csv > july-calls.csv
# View the transcript of every call in the window
bolna calls list 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 -q \
| xargs -I{} bolna calls view {}
```
# Bolna calls CLI commands and flags
Source: https://www.bolna.ai/docs/cli/commands/calls-overview
Reference for the bolna call/calls CLI commands and flags used to start calls, list history, and view transcripts from your terminal.
Manage [calls](/docs/guides/outbound/making-outgoing-calls). Subcommands let you start an outbound call, list call history for an agent, and view a single call's full detail and transcript. Each command maps to a tool in the [Bolna MCP server](/docs/build-with-ai/mcp)'s tool list.
## Syntax
```bash theme={"system"}
bolna call start [flags]
bolna calls [command]
```
## Commands
| Command | Description |
| ---------------------------------------- | ------------------------------------------- |
| [`call start`](/docs/cli/commands/call-start) | Place a real outbound call |
| [`calls list`](/docs/cli/commands/calls-list) | List call history for an agent |
| [`calls view`](/docs/cli/commands/calls-view) | Get full detail and transcript for one call |
***
## Inherited Global Flags
This command also supports [Global Flags](/docs/cli/global-flags), such as:
* `-o, --output` – Output format: `table`, `json`, or `csv`
* `--profile` – Credential profile to use
* `-v, --verbose` – Verbose logging
* `-n, --no-color` – Disable color output
# View a call with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/calls-view
Use the bolna calls view command to fetch full call detail, including status, cost, and the complete transcript.
Retrieve full detail for one call by execution ID. Returns status (color-coded by outcome), duration, cost, and the complete transcript rendered as Markdown. Maps to the `get_execution` MCP tool.
## Syntax
```bash theme={"system"}
bolna calls view [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | -------------------------------- | ------- |
| `-h, --help` | Show help for the command | – |
| `-o, --output string` | Output format: `table` or `json` | `table` |
## Example
```bash theme={"system"}
bolna calls view b7140255-af33-4608-8e97-04dd944b8e48
```
```
Status completed
Duration 2m 14s
Cost $0.38
Recipient +14155551234
Transcript
Agent: Hi, thanks for calling Acme — how can I help?
User: I wanted to check on my order status.
...
```
```bash theme={"system"}
# Raw execution data, e.g. for extracted_data or webhook reconciliation
bolna calls view b7140255-af33-4608-8e97-04dd944b8e48 --output json
```
[`bolna call start`](/docs/cli/commands/call-start) prints the exact `bolna calls view` command to run, execution ID already filled in.
# bolna docs fetch
Source: https://www.bolna.ai/docs/cli/commands/docs-fetch
Use the bolna docs fetch command to fetch a Bolna documentation page as rendered Markdown directly in your terminal, given a path or URL.
Fetch one documentation page and render it as formatted Markdown directly in the terminal, using the same renderer the CLI already uses for call transcripts and agent system prompts.
This is a **utility** command, not an account-management one: it reads a public Bolna doc page, not your account data, so it works without `bolna login` or an API key. Maps to the `get_doc` MCP tool.
## Syntax
```bash theme={"system"}
bolna docs fetch [flags]
```
`` accepts three equivalent forms, all normalized to the same request:
* A bare path — `bolna docs fetch agent-setup/analytics-tab`
* A path with `.md` — `bolna docs fetch agent-setup/analytics-tab.md`
* A full URL, exactly as printed by [`docs search`](/docs/cli/commands/docs-search) — `bolna docs fetch https://www.bolna.ai/docs/agent-setup/analytics-tab.md`
Only `www.bolna.ai/docs/*.md` URLs are ever fetched — a non-Bolna URL is rejected rather than requested, so this command can't be used as an open URL proxy.
## Flags
| Flag | Description | Default |
| ------------------- | --------------------------------------------------------------------------------------------------------- | ------- |
| `-h, --help` | Show help for the command | – |
| `-o, --output json` | Return `{"path": "...", "content": "..."}` with the raw Markdown, instead of the rendered terminal output | – |
## Example
```bash theme={"system"}
bolna docs fetch agent-setup/analytics-tab
```
```
# Set Up Webhooks and Post-Call Extractions
Configure webhooks, call summarization, and data extraction for Bolna Voice AI...
## What is the Extractions Tab?
The Extractions Tab is where you configure webhooks for real-time data and
post-call processing tasks...
```
```bash theme={"system"}
# Raw Markdown, for piping or saving to a file
bolna docs fetch agent-setup/analytics-tab -o json | jq -r '.content' > analytics-tab.md
```
## Errors
An invalid or nonexistent page returns a clear error instead of a partial render:
```
fetching doc page "this/does/not/exist": HTTP 404 from https://www.bolna.ai/docs/this/does/not/exist.md
```
## Workflow
```bash theme={"system"}
bolna docs search "outbound call" # find the right page
bolna docs search "outbound call" -q # just get its path
bolna docs fetch # read the full page, right in the terminal
```
Find the page path to pass here
# bolna docs search
Source: https://www.bolna.ai/docs/cli/commands/docs-search
Use the bolna docs search command to search Bolna's documentation index (llms.txt) by title, description, and path, ranked best-match-first.
Search every page title, description, and path in [Bolna's `llms.txt` index](https://www.bolna.ai/docs/llms.txt) for a query, and print matching pages ranked best-match-first — title matches are weighted higher than description or path matches.
This is a **utility** command, not an account-management one: it reads Bolna's own public documentation index, not your account data, so it works without `bolna login` or an API key. Maps to the `search_docs` MCP tool.
## Syntax
```bash theme={"system"}
bolna docs search [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | ------------------------------------------------------------ | -------- |
| `-h, --help` | Show help for the command | – |
| `-q, --quiet` | Print only the matched doc paths, one per line, nothing else | Disabled |
| `-o, --output string` | Output format: `table`, `json`, or `csv` | `table` |
Use `-q` to pipe a match straight into [`bolna docs fetch`](/docs/cli/commands/docs-fetch):
```bash theme={"system"}
bolna docs search webhook -q | head -1 | xargs bolna docs fetch
```
## Example
```bash theme={"system"}
bolna docs search webhook
```
```
TITLE PATH DESCRIPTION
Create Bolna Webhook connection with Make.com tutorials/make-com/create-bolna-webhook-connection Step-by-step tutorial on integrating Bolna Voice AI agents with Make...
Set Up Webhooks and Post-Call Extractions agent-setup/analytics-tab Configure webhooks, call summarization, and data extraction for Bolna...
Receive Bolna Voice AI call updates guides/post-call/polling-call-status-webhooks Receive real-time call status updates from Bolna Voice AI using webho...
```
```bash theme={"system"}
# Quoted, multi-word query
bolna docs search "mcp tool list"
# JSON output — full result set with Title, Path, Description per entry
bolna docs search webhook -o json
```
If nothing matches, table mode prints `No matching docs. Try different keywords.` (`json`/`csv` return an empty list instead).
Fetch the full Markdown content of a page found here
# bolna doctor
Source: https://www.bolna.ai/docs/cli/commands/doctor
Use the bolna doctor command to check your bolna-cli environment: config, keychain, auth, and API reachability.
Run a full health check of your `bolna-cli` environment, with an animated checklist on a real terminal.
## Syntax
```bash theme={"system"}
bolna doctor [flags]
```
## What it checks
| Check | What it verifies |
| ------------------- | ----------------------------------------------------- |
| Config directory | Whether the config directory exists and is writable |
| OS keychain | Whether the platform credential store is reachable |
| API key configured | Whether a key is set, and where it came from |
| Bolna API reachable | Whether `api.bolna.ai` responds |
| API key valid | Whether the configured key authenticates, and as whom |
| TUI support | Whether the current terminal supports the dashboard |
## Flags
| Flag | Description | Default |
| --------------------- | -------------------------------------------------- | ------- |
| `-h, --help` | Show help for the command | – |
| `-o, --output string` | Output format: `table` (animated) or `json` for CI | `table` |
## Example
```bash theme={"system"}
bolna doctor
```
```
✓ Config directory writable ~/.config/bolna
✓ OS keychain reachable macOS Keychain
✓ API key configured from keychain (profile: default)
✓ Bolna API reachable api.bolna.ai (142ms)
✓ API key valid authenticated as ops@acme.com
✓ Terminal supports interactive UI xterm-256color
All checks passed.
```
## In CI
```bash theme={"system"}
bolna doctor --json | jq -e '.checks[] | select(.status != "ok")' && exit 1
```
# Log in with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/login
Use the bolna login command to authenticate and store your API key in the OS credential store.
Authenticate and store your API key in your OS's native credential store. See [Authentication](/docs/cli/authentication) for how storage and profiles work.
## Syntax
```bash theme={"system"}
bolna login [flags]
```
On a real terminal, this opens an interactive form with a masked input for your API key. The key is validated live before anything is saved.
## Flags
| Flag | Description | Default |
| ------------------ | ------------------------------------------------------ | ------- |
| `-h, --help` | Show help for the command | – |
| `--api-key string` | Pass the key directly, skipping the interactive prompt | – |
Plus the [global flags](/docs/cli/global-flags) — `--profile` in particular.
## Example
```bash theme={"system"}
bolna login
```
```
? Bolna API key: ****************************************
✓ Verified — logged in as ops@acme.com
```
```bash theme={"system"}
# Non-interactive, for CI
bolna login --api-key "$BOLNA_API_KEY"
# Log in to a second, named profile
bolna login --profile client-acme
```
You rarely need to run this at all — any command that needs auth and finds none offers to log you in inline. See [Never a Dead End](/docs/cli/authentication#never-a-dead-end).
# Log out with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/logout
Use the bolna logout command to remove the stored API key for the active profile.
Remove the API key stored for the active profile from your OS credential store. Doesn't revoke the key on the Bolna platform — it only forgets it locally.
## Syntax
```bash theme={"system"}
bolna logout [flags]
```
## Flags
Only the [global flags](/docs/cli/global-flags) apply — use `--profile` to log out of a specific profile.
## Example
```bash theme={"system"}
bolna logout
```
```
✓ Logged out of profile "default"
```
```bash theme={"system"}
bolna logout --profile client-acme
```
If `BOLNA_API_KEY` is set in your environment, commands keep using it even after `bolna logout` — the environment variable always takes priority. Unset it separately to fully de-authenticate the shell.
# List phone numbers with the Bolna CLI
Source: https://www.bolna.ai/docs/cli/commands/numbers-list
Use the bolna numbers list command to view every phone number on the account, with provider, linked agent, and renewal date.
List every phone number on the account. Returns the number, telephony provider, linked agent ID, rented status, price, and renewal date. Maps to the `list_phone_numbers` MCP tool.
## Syntax
```bash theme={"system"}
bolna numbers list [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | ---------------------------------------- | -------- |
| `-h, --help` | Show help for the command | – |
| `-q, --quiet` | Print only the bare number per row | Disabled |
| `-o, --output string` | Output format: `table`, `json`, or `csv` | `table` |
## Example
```bash theme={"system"}
bolna numbers list
```
```
NUMBER PROVIDER AGENT RENTED PRICE RENEWS
+14155559999 Twilio 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02 yes $5/mo 2026-08-14
+919812345678 Plivo — yes $5/mo 2026-08-02
```
```bash theme={"system"}
# Numbers with no linked agent
bolna numbers list --output json | jq -r '.[] | select(.agent_id == null) | .number'
```
Buying a number or linking it to an agent for inbound calls is currently done through the [Phone Numbers API](/docs/api-reference/phone-numbers/overview) — `bolna numbers list` is read-only.
# bolna whoami
Source: https://www.bolna.ai/docs/cli/commands/whoami
Use the bolna whoami command to show the authenticated account's name, email, wallet balance, and concurrency limits.
Show who you're authenticated as, current wallet balance, and concurrency limits. Maps to the `get_user_info` MCP tool.
## Syntax
```bash theme={"system"}
bolna whoami [flags]
```
## Flags
| Flag | Description | Default |
| --------------------- | ---------------------------------------- | ------- |
| `-h, --help` | Show help for the command | – |
| `-o, --output string` | Output format: `table`, `json`, or `csv` | `table` |
## Example
```bash theme={"system"}
bolna whoami
```
```
Account Acme Corp
Email ops@acme.com
Balance $482.19
Concurrency 3 / 10 calls
```
```bash theme={"system"}
# Pre-flight balance check before a batch run
balance=$(bolna whoami --json | jq -r '.balance_usd')
# Check a specific profile
bolna whoami --profile client-acme
```
# Keybindings
Source: https://www.bolna.ai/docs/cli/dashboard/keybindings
Every keybinding in the bolna-cli dashboard, plus the fuzzy-searchable command palette.
## Global keybindings
These work from anywhere in the dashboard:
| Key | Action |
| -------------- | ------------------------------------- |
| `:` | Open the command palette |
| `1` | Jump to the Agents screen |
| `2` | Jump to the Numbers screen |
| `3` | Jump to the Account screen |
| `enter` | Drill into the selected row |
| `esc` | Go back one screen |
| `r` | Refresh the current screen |
| `t` | Cycle color theme (persisted to disk) |
| `q` / `ctrl+c` | Quit |
## From an agent's detail view
Once you've drilled into a specific agent, three more keys become available:
| Key | Action |
| --- | ------------------------------------------------------------------------------------ |
| `c` | View this agent's calls |
| `b` | View this agent's batches |
| `s` | Start a call with this agent — see [Starting a Call](/docs/cli/dashboard/starting-a-call) |
## Command palette
Press `:` from anywhere to open a fuzzy-searchable jump list covering **every agent and every section** at once — not just the current screen. Type a few letters of an agent's name or a section like "batches", hit `enter`, and you land directly there. No need to back out to the top level and navigate down through menus first.
```
┌─ Jump to… ─────────────────────────────────────────┐
│ > front │
│ │
│ Front Desk Concierge Agent │
│ Front Desk Concierge → Calls Section │
│ Front Desk Concierge → Batches Section │
└──────────────────────────────────────────────────────┘
```
This is the fastest way to move around once you have more than a handful of agents — faster than paging through the Agents table looking for a name.
## Themes
Press `t` to cycle through the dashboard's color themes. Your choice is written to disk and reused the next time you open `bolna` — you set it once, not every session.
## See also
Layout, screens, and the header/footer bars
The `s` keybinding, in full
# Dashboard Overview
Source: https://www.bolna.ai/docs/cli/dashboard/overview
The full-screen bolna-cli dashboard — a read-mostly mission control view of your agents, calls, and account.
Run `bolna` with no arguments on a real terminal, and instead of a help message you get a full-screen dashboard — a live, navigable view of every agent, call, phone number, and batch on your account, built entirely on the [Charm](https://charm.sh) TUI stack.
```bash theme={"system"}
bolna
```
## The splash screen
Before the dashboard appears, a "BOLNA" ASCII wordmark animates into place using spring physics (via [Harmonica](https://github.com/charmbracelet/harmonica)) — it settles, then transitions into the dashboard automatically, or immediately on any keypress if you don't want to wait.
## Layout
The whole dashboard sits inside a bordered "mission control" frame — a rounded border in Bolna's brand blue gradient, matching the wordmark color scheme at [mcp.bolna.ai](https://mcp.bolna.ai).
```
┌─ bolna ─────────────────────────────────────── Agents ───── $482.19 ─┐
│ │
│ NAME STATUS ID │
│ ▸ Front Desk Concierge active 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9… │
│ Collections Reminder active 7b2e4f10-8a3c-4d9e-b1f2-5c9a0e… │
│ Lead Qualifier (v2) draft e91c3a5f-2d4b-4a8e-9f0c-1d5b7e… │
│ │
├──────────────────────────────────────────────────────────────────── │
│ : palette 1/2/3 jump enter view r refresh q quit │
└──────────────────────────────────────────────────────────────────── ┘
```
* **Header bar** — a `bolna` badge, a breadcrumb for the current screen, and your account's real-time wallet balance in the top-right corner.
* **Footer bar** — context-sensitive keybinding hints for whatever screen is active, a loading spinner during data fetches, or an error message if something failed.
## Screens
| Screen | What it shows |
| ------------ | --------------------------------------------------------------------------------- |
| Agents | Table of every agent — name, status, ID |
| Agent Detail | Full card: welcome message and system prompt, rendered as Markdown |
| Calls | Call history table, scoped to one agent |
| Call Detail | Full transcript for one call |
| Numbers | Every phone number on the account |
| Batches | Batch campaigns for one agent |
| Account | Your profile card — balance and concurrency limits |
| Call Start | The one guided write flow — see [Starting a Call](/docs/cli/dashboard/starting-a-call) |
Jump between them with the [command palette](/docs/cli/dashboard/keybindings#command-palette) or the number keys — full keybinding reference on the [Keybindings](/docs/cli/dashboard/keybindings) page.
## Read-mostly, on purpose
Everything in the dashboard is read-only, with one exception: starting a call. Creating, editing, or deleting an agent always routes to the dedicated CLI commands — [`create`](/docs/cli/commands/agents-create), [`update`](/docs/cli/commands/agents-update), [`delete`](/docs/cli/commands/agents-delete) — which have their own wizards and confirmations.
## Non-blocking by design
Every screen's data loads independently. A slow fetch on one screen never freezes another. The footer shows a spinner while loading, or an error if something failed.
## See also
Full reference: navigation, the command palette, and themes
The one write action built into the dashboard
# Starting a Call
Source: https://www.bolna.ai/docs/cli/dashboard/starting-a-call
The one write action built into the dashboard — a guided call flow with a live, polling status view.
The dashboard is deliberately [read-mostly](/docs/cli/dashboard/overview#read-mostly-by-design) — with exactly one exception. Press `s` from an agent's detail view to place a real call, guided through a few screens instead of a single command.
This is the dashboard's equivalent of [`bolna call start`](/docs/cli/commands/call-start) — same confirmation, same balance check, same real money spent — just walked through visually instead of typed as flags.
## The flow
A prompt asks for the number to call, validated as [E.164](https://en.wikipedia.org/wiki/E.164) format (`+14155551234`) before you can continue. An invalid format is rejected right there, before anything is sent anywhere.
A confirmation screen shows the agent, the recipient, and your account's **real current wallet balance** — pulled fresh, not cached. Nothing dials until you explicitly answer `y`.
```
Start a call?
Agent Front Desk Concierge
Recipient +14155551234
Balance $482.19
(y/n)
```
This never fires automatically. There's no "skip confirmation" option inside the dashboard flow — for that, use [`bolna call start --yes`](/docs/cli/commands/call-start) from a script instead.
Once confirmed, the screen switches to a live view with an animated waveform, polling the call's status every 1.5 seconds until it reaches a final state (`completed`, `no-answer`, `failed`, etc.).
When the call ends, the same screen shows the full transcript — no separate lookup needed, no need to copy an execution ID into another command.
## See also
The same flow, scriptable from the command line
# Global Flags
Source: https://www.bolna.ai/docs/cli/global-flags
Reference for global flags in the Bolna CLI like output, no-color, profile, verbose, and quiet available with every bolna command.
## Available Flags
| Flag | Default | Env Var |
| --------------------- | --------- | ---------- |
| `-h, --help` | – | – |
| `-o, --output string` | `table` | – |
| `--json` | Disabled | – |
| `-n, --no-color` | Disabled | `NO_COLOR` |
| `--profile string` | `default` | – |
| `-v, --verbose` | Disabled | – |
| `-q, --quiet` | Disabled | – |
## Syntax and Example Usage
### --help, -h
Show help information for any command.
```bash theme={"system"}
bolna --help
bolna agents --help
bolna agents list --help
```
### --output, -o
**string**\
Default `table`. Output format: `table`, `json`, or `csv`. Use `json` or `csv` when piping results to other tools or scripts, and `table` for human-friendly interactive use.
```bash theme={"system"}
bolna agents list --output json | jq -r '.[].id'
bolna agents list -o csv > agents.csv
```
### --json
Shorthand for `--output json`.
```bash theme={"system"}
bolna whoami --json | jq -r '.balance_usd'
```
### --no-color, -n
By default, output is colored. Disable colors when piping results to scripts, log files, or CI systems where ANSI codes may cause issues. Can also be set globally via the `NO_COLOR` environment variable.
```bash theme={"system"}
bolna --no-color agents list
# Set globally via environment variable
export NO_COLOR=1
```
You rarely need this flag directly — output is already plain and colorless whenever it isn't attached to a real terminal (a pipe, a redirect, or CI). `--no-color` is for forcing that on a real terminal too.
### --profile
**string**\
Default `default`. Named credential profile to use — see [Authentication](/docs/cli/authentication#stored-login).
```bash theme={"system"}
bolna agents list --profile client-acme
```
### --verbose, -v
Verbose logging — request timing, retries, and underlying API calls. Useful when troubleshooting.
```bash theme={"system"}
bolna agents list --verbose
```
### --quiet, -q
List commands only. Prints just the bare ID of each row, one per line, nothing else — built for piping into `xargs`.
```bash theme={"system"}
bolna agents list -q | xargs -I{} bolna agents view {}
```
# Installation
Source: https://www.bolna.ai/docs/cli/installation
Install the Bolna CLI using go install or by building from source on macOS, Linux, and Windows, with version checks and Gatekeeper notes.
`bolna-cli` is a single static Go binary — no runtime, no interpreter, no CGO dependency. There's no Homebrew tap or prebuilt GitHub release binary yet, so these two paths are the only way to install it right now.
### go install (Recommended)
**Best for almost everyone** with [Go](https://go.dev/doc/install) installed locally — the binary is built on your machine, so it never triggers an OS code-signing warning.
```bash theme={"system"}
go install github.com/bolna-ai/cli/cmd/bolna@latest
```
This installs `bolna` into `$(go env GOPATH)/bin`.
```bash theme={"system"}
echo $PATH | tr ':' '\n' | grep "$(go env GOPATH)/bin"
```
If nothing prints, add it to your shell profile:
```bash theme={"system"}
export PATH="$PATH:$(go env GOPATH)/bin"
```
### Build from Source
**Best for contributors** or anyone who wants a specific commit, or wants to inspect the source before running it. Requires Go 1.21 or later.
```bash theme={"system"}
# 1. Clone the repository
git clone https://github.com/bolna-ai/cli
cd cli
# 2. Build the binary
go build -o bolna ./cmd/bolna
# 3. Move it onto your PATH
sudo mv bolna /usr/local/bin/bolna
```
## Verify Installation
```bash theme={"system"}
bolna version
```
`bolna version` prints the installed version, commit hash, and build date. `bolna-cli` is in beta — pin a version in CI if you depend on exact output shapes.
***
## macOS: "cannot be opened because the developer cannot be verified"
This Gatekeeper warning shows up on any binary that isn't signed with an Apple Developer certificate — a one-time speed bump, not a sign anything is wrong.
In Finder, right-click the `bolna` binary, choose **Open**, then confirm in the dialog. macOS remembers your choice after that.
```bash theme={"system"}
xattr -d com.apple.quarantine bolna
```
`go install` builds the binary locally, so it never picks up the quarantine attribute in the first place.
***
## Community Contribution
We welcome community contributions to `bolna-cli`. If you'd like to add features, fix bugs, or improve documentation:
* Visit the [Bolna CLI GitHub repository](https://github.com/bolna-ai/cli)
* Fork the repo and create a feature branch
* Open a Pull Request with a clear description of your changes and we'll review and merge it
# CLI Overview
Source: https://www.bolna.ai/docs/cli/introduction
Overview of the Bolna CLI for managing agents, calls, phone numbers, and batches from your terminal, and the full-screen dashboard it opens with no arguments.
`bolna-cli` is in **beta** — commands and flags may still change before a stable 1.0 release.
The **Bolna CLI** (`bolna`) is a single Go binary that lets you manage agents, calls, phone numbers, and batches directly from your terminal — no dashboard tab required. Every command maps 1:1 to a tool in the [Bolna MCP server](/docs/build-with-ai/mcp)'s tool list, so anything an AI assistant can do to your account over MCP, you can run yourself with a direct command.
Run it with no arguments on a real terminal and instead of a help message, it opens a full-screen dashboard — a live, navigable view of your account built on the [Charm](https://charm.sh) TUI stack. Run any command in a script or CI pipe and it behaves like a normal CLI: plain, non-interactive, colorless output.
***
## Benefits of using the Bolna CLI
Developers reach for a CLI because it's **fast, scriptable, and doesn't need a browser**. Instead of clicking through the dashboard, you run one command and move on.
By using the CLI, you can:
* **Script call operations** – Start calls, poll execution status, and pull transcripts from a shell script or CI job.
* **Debug without leaving the terminal** – Pull an agent's config or a call's full transcript with one command instead of navigating the dashboard.
* **Pipe into other tools** – Every list command supports `--json` or `--csv` output, so results feed straight into `jq`, `xargs`, or a spreadsheet.
* **Monitor visually when you want to** – Run `bolna` with no arguments for a full-screen dashboard with a live wallet balance and a guided call-start flow.
***
## What you can do with the Bolna CLI
* **Manage agents** – List, view, create, update, and delete agents.
* **Place and track calls** – Start an outbound call, list call history, and pull a full transcript.
* **Inspect account resources** – List phone numbers and batch campaigns linked to an agent.
* **Check account health** – Confirm authentication, keychain access, and API reachability with `bolna doctor`.
* **Look up the docs without a browser** – Search and read Bolna's documentation with [`docs search`](/docs/cli/commands/docs-search) and [`docs fetch`](/docs/cli/commands/docs-fetch) — no login required.
***
## Available commands
### Agents
Manage [agents](/docs/agent-setup/overview): list, view, create, update, and delete. Also see the [Agent API](/docs/api-reference/agent/v2/overview).
| Command | Description |
| ---------------------------------------------- | ---------------------------------------------------------------- |
| [`agents list`](/docs/cli/commands/agents-list) | List agents in the account |
| [`agents view`](/docs/cli/commands/agents-view) | Get an agent's full config, including prompt and welcome message |
| [`agents create`](/docs/cli/commands/agents-create) | Create a new agent, interactively or from a JSON file |
| [`agents update`](/docs/cli/commands/agents-update) | Update an agent's name, prompt, welcome message, or webhook |
| [`agents delete`](/docs/cli/commands/agents-delete) | Permanently delete an agent |
### Calls
Manage [calls](/docs/guides/outbound/making-outgoing-calls): start, list history, and view transcripts. Also see the [Calls API](/docs/api-reference/calls/overview).
| Command | Description |
| ---------------------------------------- | ------------------------------------------- |
| [`call start`](/docs/cli/commands/call-start) | Place a real outbound call |
| [`calls list`](/docs/cli/commands/calls-list) | List call history for an agent |
| [`calls view`](/docs/cli/commands/calls-view) | Get full detail and transcript for one call |
### Resources
| Command | Description |
| -------------------------------------------- | --------------------------------- |
| [`numbers list`](/docs/cli/commands/numbers-list) | List phone numbers on the account |
| [`batches list`](/docs/cli/commands/batches-list) | List batch campaigns for an agent |
### Account
| Command | Description |
| -------------------------------- | --------------------------------------------------- |
| [`login`](/docs/cli/commands/login) | Authenticate and store an API key |
| [`logout`](/docs/cli/commands/logout) | Remove the stored API key |
| [`whoami`](/docs/cli/commands/whoami) | Show the authenticated account, balance, and limits |
### Utility
Unlike every other group above, these commands don't manage account data and don't need `bolna login` or an API key — they help you learn the CLI and Bolna itself directly from the terminal.
| Command | Description |
| ------------------------------------------ | ------------------------------------------------------------ |
| [`doctor`](/docs/cli/commands/doctor) | Check config, keychain, and API health |
| [`docs search`](/docs/cli/commands/docs-search) | Search Bolna's documentation index for a query |
| [`docs fetch`](/docs/cli/commands/docs-fetch) | Fetch a documentation page as Markdown in your terminal |
| `version` | Print the installed CLI version, commit hash, and build date |
## Next
Install, log in, and run your first command in under a minute
Browse CLI releases and updates
# Quickstart
Source: https://www.bolna.ai/docs/cli/quickstart
Quickstart guide to install the Bolna CLI, authenticate with your API key, and run your first commands in minutes.
## Step 1: Install the CLI
Requires [Go](https://go.dev/doc/install) installed locally.
```bash theme={"system"}
go install github.com/bolna-ai/cli/cmd/bolna@latest
```
See [Installation](/docs/cli/installation) for building from source instead, and for fixing a macOS Gatekeeper warning if you hit one.
```bash theme={"system"}
bolna version
```
***
## Step 2: Authenticate
```bash theme={"system"}
bolna login
```
You'll be prompted for your Bolna API key — grab one from the [Bolna Dashboard → Developers](https://platform.bolna.ai) tab. The key is validated live, then stored in your OS's native credential store.
You can skip this step. Run any command that needs auth — including bare `bolna` — and it offers to log you in right there, then continues into what you originally asked for.
***
## Step 3: Enable Autocompletion (Optional)
Enable [autocompletion](/docs/cli/autocompletion) to get command and flag suggestions with Tab and prevent typos.
***
## You're all set!
```bash theme={"system"}
bolna agents list
```
```
NAME STATUS ID
Front Desk Concierge active 3fa8b2e1-9c4d-4a2f-8b1e-6d5c3a9f7e02
Collections Reminder active 7b2e4f10-8a3c-4d9e-b1f2-5c9a0e6d3b47
```
Or run `bolna` with no arguments to open the [dashboard](/docs/cli/dashboard/overview) instead.
# Versioning and Support Policy
Source: https://www.bolna.ai/docs/cli/versioning
Understand the Bolna CLI beta status, the semantic versioning policy planned for 1.0, and which platforms are supported.
`bolna-cli` is currently in **beta** (pre-1.0). Commands, flags, and output shapes may still change between releases — pin a version in CI if you depend on exact behavior.
## Versioning Policy
Once `bolna-cli` reaches 1.0, releases will follow **[Semantic Versioning (SemVer)](https://semver.org/)**: `MAJOR.MINOR.PATCH`.
**Major.** Breaking changes that are backward incompatible (renaming commands, changing flag names, changing output shapes).
**Minor.** New features that are backward compatible (new commands, new optional flags).
**Patch.** Backward-compatible bug fixes.
During beta (`0.x.y`), any release may include breaking changes — check the [Changelog](/docs/cli/changelog) before upgrading in CI.
## Platform Support
The CLI is a single static Go binary, buildable for macOS, Linux, and Windows on both `arm64` and `x86_64`.
## Best Practices
* **Check the version after upgrading** – Run `bolna version` to confirm what's installed.
* **Review the changelog before upgrading** – Skim the [Changelog](/docs/cli/changelog) for behavior changes, especially during beta.
* **Pin the version in CI** – Since `go install ...@latest` always resolves to the newest commit, pin an explicit tag or commit in CI pipelines to avoid unexpected differences across environments.
## Open Source
`bolna-cli` is open source, hosted on [GitHub](https://github.com/bolna-ai/cli). We welcome contributions — fork the repo, open a Pull Request, and we'll review it. See [Installation](/docs/cli/installation#community-contribution).
# Clone Your Voice
Source: https://www.bolna.ai/docs/clone-voices
Clone your voice with Bolna AI. Upload a short sample to create lifelike custom voices and personalize your AI agents with any licensed voice.
## What is Voice Cloning?
Create custom AI voices by uploading a short audio sample (1-2 minutes) of any voice you have rights to use. Perfect for brand consistency, personalized customer experiences, or using specific voice talent across all your agents.
Use the same voice across all customer touchpoints
Create unique voices for different agent personas
***
## How to Clone a Voice
Go to your agent in the Bolna Playground and click the **Audio** tab. Scroll down to the **Text-to-Speech** section and click **Add Voice +**.
Choose your voice cloning provider: **ElevenLabs** or **Cartesia**
Enter a **name** and **description** to identify your voice when building agents
Upload a high-quality audio file (MP3, WAV) that is **1-2 minutes** long
Click **"Clone Voice"** and wait for processing. Your new voice will appear in Voice Lab!
For best results, use clean audio with **no background noise** and only the voice you want to clone.
***
## Next Steps
Import custom voices from your voice provider
Configure voice settings in the Playground
Set up multilingual agents with custom voices
Access your cloned voices
# Submit Phone Number Compliance Application
Source: https://www.bolna.ai/docs/compliance-application/how-to-submit-guide
Bolna phone number compliance guide: step-by-step submission process, 12–24h review, and troubleshooting for fast approval.
Before submitting, make sure you understand the [compliance requirements](/docs/compliance-application/introduction) including required documents (CIN certificate, GST registration) and data privacy policies.
## How to Submit Your Compliance Application
Visit the [Compliance Application page](https://platform.bolna.ai/account?tab=compliance) on your Bolna dashboard and click the **"Create a new Application"** button to initiate the process.
Enter your complete information:
* **First Name**: Your legal first name
* **Last Name**: Your legal last name
* **Company Name**: Your registered business name
Click the **"Drag and drop your file here, or click to browse"** area under the CIN Certificate section.
Select your CIN certificate PDF file (must be under 10 MB). The file will be uploaded automatically.
Provide your complete GST number in the format provided by your tax authority (e.g., `ABCDEFGHIJKL1234`).
Click the upload area under the GST File section and select your GST registration certificate or proof of registration (PDF format, maximum 10 MB).
Double-check all information and uploaded documents for accuracy. Once you're satisfied, click **"Create Application"** to submit your compliance application for review.
## Application Review Process
After submitting your compliance application:
1. **Initial Review**: Our compliance team will review your application within 12-24 business hours
2. **Verification**: We verify the authenticity of your documents with relevant authorities
3. **Approval Notification**: You'll receive an email notification once your application is approved
4. **Start Purchasing**: After approval, you can immediately start [purchasing phone numbers](/docs/guides/inbound/buying-phone-numbers)
If additional information is required, our team will contact you via email. Please monitor your inbox and respond promptly to avoid delays.
## Common Issues and Solutions
Ensure your file meets these requirements:
* File format is PDF
* File size is under 10 MB
* File is not corrupted or password-protected
If issues persist, try converting your document to PDF using a different tool or compressing it to reduce file size.
The CIN (Corporate Identification Number) certificate is required for registered companies. If you're:
* **A registered company**: Contact your country's corporate registry to obtain a copy
If your GST registration is still being processed, please wait until you receive your official GST certificate before submitting the compliance application. You can still explore Bolna's features using our demo numbers.
Most applications are reviewed within 12-24 business hours. Complex cases requiring additional verification may take up to 2 business days. You'll receive email updates throughout the process.
Once submitted, you cannot directly edit your application. If you need to make changes or correct errors, contact our support team at [support@bolna.ai](mailto:support@bolna.ai) with your application details.
If your application is rejected, you'll receive an email explaining the reason. Common reasons include:
* Unclear or illegible documents
* Mismatched information
* Invalid or expired certificates
You can resubmit your application with corrected documents.
## Next Steps
After your compliance application is approved:
1. **Purchase Phone Numbers**: Browse and [buy dedicated phone numbers](/docs/guides/inbound/buying-phone-numbers) for your Voice AI agents
2. **Make Outbound Calls**: Start [making outbound calls](/docs/guides/outbound/making-outgoing-calls) using your purchased numbers
3. **Receive Inbound Calls**: Set up your agents to [handle incoming calls](/docs/guides/inbound/receiving-incoming-calls)
4. **Scale Your Operations**: Explore [batch calling](/docs/guides/outbound/batch-calling) for high-volume campaigns
***
## Related Resources
Learn about compliance requirements, required documents, and data security
Buy dedicated phone numbers after compliance approval
Use your purchased numbers for outbound calling
Frequently asked questions about Bolna Voice AI
# Phone Number Compliance Requirements for India - Bolna AI
Source: https://www.bolna.ai/docs/compliance-application/introduction
Understand India phone number compliance requirements for Bolna AI. Learn about the required documents like CIN certificate, GST, and data security standards.
## Overview
Before purchasing phone numbers on Bolna, all users must submit a compliance application. This regulatory requirement ensures proper verification and compliance with telecommunications regulations in your region.
The compliance application is a one-time requirement. Once approved, you can purchase multiple phone numbers without resubmitting your documents.
## Why Compliance is Required
Telecommunications regulations require phone number providers to verify the identity and legitimacy of businesses using phone numbers for commercial purposes. This helps:
* **Prevent fraud and abuse**: Ensures phone numbers are used by verified businesses
* **Regulatory compliance**: Meets requirements set by telecommunications authorities
* **Protect customers**: Maintains trust and security in voice communications
* **Support legitimate businesses**: Enables compliant companies to operate confidently
## Required Documents
To complete your compliance application, you'll need to prepare the following documents:
### 1. Personal Information
* **Full Name**: Your complete first and last name as it appears on official documents
* **Company Name**: Your registered business or organization name
### 2. CIN Certificate (Corporate Identification Number)
* **File Format**: PDF only
* **File Size**: Maximum 10 MB
* **Requirements**:
* Official CIN certificate issued by your country's corporate registry
* Must be clear and legible
* Should contain your company's registration details
The CIN certificate is issued by the Ministry of Corporate Affairs (or equivalent regulatory body) when you register your company. If you don't have a digital copy, you can scan or photograph the original document and convert it to PDF.
### 3. GST Registration
* **GST Number**: Your Goods and Services Tax registration number
* **GST File**:
* File Format: PDF only
* File Size: Maximum 10 MB
* Requirements: GST registration certificate or proof of registration
Ensure your GST number matches exactly with your GST certificate. Any mismatch may delay the approval process.
## Data Privacy and Security
Your compliance documents are handled with the highest standards of security:
* **Encrypted Storage**: All uploaded documents are encrypted at rest and in transit
* **Limited Access**: Only authorized compliance team members can access your documents
* **Regulatory Compliance**: We comply with data protection regulations including GDPR
* **Secure Deletion**: Documents are securely deleted after the regulatory retention period
We never share your compliance documents with third parties except as required by law or regulatory authorities.
## Ready to Submit Your Application?
Now that you understand the compliance requirements, follow our detailed step-by-step guide to submit your application:
Complete walkthrough of the submission process, review timeline, and troubleshooting common issues
## Need Help?
If you have questions about the compliance requirements or need assistance:
* **Email Support**: [support@bolna.ai](mailto:support@bolna.ai)
* **Documentation**: Visit our [FAQ page](/docs/frequently-asked-questions)
* **Schedule a Call**: [Book a consultation](https://www.bolna.ai/meet) with our team
***
## Related Resources
Step-by-step guide to buying phone numbers after compliance approval
Learn how to use your purchased numbers for outbound calling
Set up inbound call handling with your Voice AI agents
Frequently asked questions about Bolna Voice AI
# Types of Bolna Agents
Source: https://www.bolna.ai/docs/concepts/agent-types
An overview of the different agent architectures available in Bolna: conversation agents, graph agents, and IVR agents.
Bolna supports three distinct agent architectures. Each is a different way of structuring the conversation logic inside an agent.
***
## Conversation Agent
A conversation agent follows a single system prompt for the entire call. The LLM reads the prompt and the conversation history, then decides what to say next.
This is the default agent type. Most agents you create in the Bolna dashboard are conversation agents.
**Structure:**
```
Caller → Transcriber → LLM (with system prompt) → Synthesizer → Caller
```
**Characteristics:**
* Single prompt drives the entire conversation
* LLM maintains context across turns automatically
* Supports tools (function calls, knowledge base lookups, call transfers)
* Behavior is shaped by the prompt and the LLM's reasoning
See [Build & Configure Agents](/docs/agent-setup/overview) to configure a conversation agent.
***
## Graph Agent
A graph agent structures the conversation as a directed graph of nodes, where each node represents a distinct conversation state with its own prompt, tools, and routing logic.
The agent transitions between nodes based on conditions you define — for example, moving from a "greeting" node to a "qualification" node when the caller confirms their name.
**Structure:**
```
Node A (prompt A, tools A) → [condition met] → Node B (prompt B, tools B) → ...
```
**Characteristics:**
* Each node has its own system prompt and tool set
* Transitions are rule-based (explicit conditions) or LLM-decided
* Well-suited for multi-stage flows where behavior changes significantly between phases
* Supports typed variables that carry data between nodes
* Supports a global knowledge base accessible to all nodes
See [Graph Agents](/docs/graph-agent/introduction) for configuration details.
***
## IVR Agent
An IVR (Interactive Voice Response) agent uses DTMF (touch-tone) input rather than voice transcription. The caller presses keys on their phone (1 for sales, 2 for support) and the agent routes accordingly.
**Structure:**
```
Caller presses key → IVR routing logic → Play audio / transfer / end call
```
**Characteristics:**
* Triggered by key presses, not speech
* Does not use an LLM for the IVR routing layer
* Often combined with conversation agents as transfer targets
* Lower latency than speech-based agents for simple menus
See [IVR Inbound Calls](/docs/guides/inbound/ivr-inbound-calls) for configuration details.
***
## Agent Scope
Regardless of type, every Bolna agent is scoped to a set of **tasks**. A task bundles together:
* A `task_type` (e.g. `conversation`, `extraction`)
* A `toolchain` (transcriber → LLM → synthesizer pipeline)
* A `tools_config` (provider selection and settings)
* A `task_config` (timeout, silence handling)
Most agents have a single `conversation` task. Post-call extraction runs as a separate task after the call ends.
See the [Create Agent API](/docs/api-reference/agent/v2/create) for the full agent schema.
# How a Call Flows Through Bolna
Source: https://www.bolna.ai/docs/concepts/call-flow
A step-by-step walkthrough of what happens from the moment a call is placed to the moment the execution record is finalized.
This page traces the lifecycle of an outbound call placed via `POST /call`. The same stages apply to inbound calls, starting from Step 3.
***
## Full lifecycle
```
Your app → POST /call → Bolna API → Telephony provider → Recipient's phone
↓
Call answered (or not)
↓
Transcriber ← Audio stream
↓
LLM processes transcript
↓
Synthesizer → Audio stream → Caller
↓
Call ends (hangup or timeout)
↓
Post-call processing (transcript, cost, extraction)
↓
Execution record: status = completed
```
***
## Step-by-step
### 1. Call request accepted
Your app calls `POST /call` with `agent_id`, `recipient_phone_number`, and optional call metadata. Bolna validates the request and returns:
```json theme={"system"}
{
"execution_id": "b7140255-af33-4608-8e97-04dd944b8e48",
"status": "queued"
}
```
The execution record is created in the `queued` state. No telephony has happened yet.
### 2. Telephony dialing
Bolna's call scheduler picks up the queued execution and dials out via the configured telephony provider (Plivo, Twilio, Exotel, or your SIP trunk). The execution moves to `initiated`, then `ringing` as the call progresses through the network.
### 3. Call answered → pipeline starts
When the recipient answers, the status moves to `in-progress`. The real-time pipeline activates:
1. **Audio capture** — the telephony provider streams caller audio to Bolna
2. **Transcription** — the transcriber (e.g. Deepgram) converts audio to text in real-time
3. **LLM inference** — the transcript is sent to the LLM with the agent's system prompt; the LLM streams a response
4. **Synthesis** — the synthesizer converts the LLM response to speech audio
5. **Audio playback** — Bolna streams the synthesized audio back to the caller
This loop repeats for every conversational turn.
### 4. Tools (if configured)
If the agent's prompt triggers a tool call (function call, knowledge base lookup, call transfer), the LLM emits a tool-call intent. Bolna:
* Pauses synthesis
* Executes the tool (calls your API endpoint, queries the knowledge base, etc.)
* Feeds the tool result back to the LLM
* Resumes the conversation
Tool calls add 50–500ms of latency depending on the tool's response time.
### 5. Call ends
The call ends when:
* The caller hangs up
* The agent's hangup prompt fires (e.g. "Have a great day, goodbye!")
* `call_terminate` timeout is reached (configured in `task_config`)
* `hangup_after_silence` fires (no speech for N seconds)
* The agent calls the hangup tool explicitly
The telephony provider signals the disconnect. The execution moves to `call-disconnected`.
### 6. Post-call processing
`call-disconnected` is NOT the final state. After the line drops, Bolna runs:
* Transcript assembly (merges partial chunks into the full conversation text)
* Cost calculation (platform fee + network + transcriber + LLM + synthesizer)
* Post-call extraction (if an extraction task is configured — runs the LLM over the transcript to pull structured data)
* Recording URL generation
When all processing completes, the execution moves to **`completed`** and all fields are populated.
**Always wait for `completed`**, not `call-disconnected`, before reading `conversation_duration`, `total_cost`, `recording_url`, or `extracted_data`. These are `null` or `0` at `call-disconnected`.
### 7. Webhook delivery
If `webhook_url` is set on the agent, Bolna POSTs the execution payload to your server at each status change. The final `completed` POST includes all populated fields.
Source IP: `13.203.39.153` — whitelist this on your server.
***
## Execution status reference
| Status | Phase |
| ------------------- | -------------------------------- |
| `queued` | Accepted, waiting to dial |
| `initiated` | Dialing |
| `ringing` | Recipient's phone ringing |
| `in-progress` | Call answered, pipeline active |
| `call-disconnected` | Line dropped, post-processing |
| `completed` | All fields finalized ✓ |
| `no-answer` | Not picked up |
| `busy` | Line busy |
| `failed` | Telephony error |
| `canceled` | Manually canceled before answer |
| `stopped` | Stopped mid-execution |
| `error` | Internal error during processing |
| `balance-low` | Insufficient wallet balance |
See [Errors & Status Codes](/docs/api-reference/errors) for the full enum with terminal/intermediate labels.
***
## Related
* [Make a Call API](/docs/api-reference/calls/make)
* [Get Execution API](/docs/api-reference/executions/get_execution)
* [Webhooks](/docs/guides/post-call/polling-call-status-webhooks)
* [Hangup & Termination](/docs/guides/outbound/hangup-calls)
# Understanding Call Latency Metrics in Bolna Voice AI
Source: https://www.bolna.ai/docs/concepts/call-latencies
Analyze call latency across transcription, LLM, and synthesis in Bolna Voice AI. Identify bottlenecks and optimize response times.
## Introduction
Bolna provides detailed latency metrics for every Voice AI execution, helping you monitor and optimize agent response speed. These metrics break down timing across the entire voice pipeline, from speech recognition to LLM processing to audio synthesis.
Access latency data via the [Get Execution API](/docs/api-reference/executions/get_execution) in the `latency_data` object.
***
## Latency Data Overview
### Top-Level Metrics
```json theme={"system"}
{
"latency_data": {
"stream_id": 129.56,
"time_to_first_audio": 130.84,
"region": "in",
"transcriber": { ... },
"llm": { ... },
"synthesizer": { ... }
}
}
```
| Field | Type | Description |
| --------------------- | -------- | --------------------------------------------------------------------------- |
| `stream_id` | `float` | Time (ms) to establish the audio stream connection |
| `time_to_first_audio` | `float` | Time (ms) from end of caller's utterance to start of agent's audio response |
| `region` | `string` | Geographic region code (e.g., `in` for India, `us` for United States) |
`time_to_first_audio` is the most important metric for perceived responsiveness. It represents how long the caller waits before hearing the agent speak.
***
## Pipeline Component Metrics
Converts spoken audio into text. Tracks how quickly speech is being transcribed.
```json theme={"system"}
{
"transcriber": {
"time_to_connect": 226,
"turns": [
{
"turn": 1,
"turn_latency": [
{
"sequence_id": 1,
"audio_to_text_latency": 20.12,
"text": "hello who is there"
},
{
"sequence_id": 2,
"audio_to_text_latency": 19.96,
"text": "hello who is this"
}
]
}
]
}
}
```
| Field | Type | Description |
| ----------------------- | --------- | ------------------------------------------------------ |
| `time_to_connect` | `integer` | Time (ms) to establish connection with the transcriber |
| `turn` | `integer` | Sequential conversation turn number (starting at 1) |
| `sequence_id` | `integer` | Incremental transcription update ID within a turn |
| `audio_to_text_latency` | `float` | Time (ms) from audio input to transcribed text |
| `text` | `string` | Transcribed text for this sequence |
Multiple sequences per turn represent **incremental refinements**. The transcriber provides partial results that improve over time. The final sequence is the most accurate.
Generates the agent's response based on transcribed input.
```json theme={"system"}
{
"llm": {
"time_to_connect": null,
"turns": [
{
"time_to_first_token": 1633.04,
"time_to_last_token": 1691.53,
"turn": 1
},
{
"time_to_first_token": 737.80,
"time_to_last_token": 777.49,
"turn": 2
}
]
}
}
```
| Field | Type | Description |
| --------------------- | ----------------- | ---------------------------------------------------------------------- |
| `time_to_connect` | `integer \| null` | Time (ms) to connect to the LLM provider (`null` if not applicable) |
| `turn` | `integer` | Sequential turn number |
| `time_to_first_token` | `float` | Time (ms) to receive the **first token**, critical for perceived speed |
| `time_to_last_token` | `float` | Time (ms) to receive the **last token**, total generation time |
**Time to First Token (TTFT)** is the key metric here. With streaming, the synthesizer starts converting text to speech as soon as the first tokens arrive, reducing overall latency.
Converts LLM text responses into spoken audio.
```json theme={"system"}
{
"synthesizer": {
"time_to_connect": 271,
"turns": [
{
"time_to_first_token": 599,
"time_to_last_token": 800,
"turn": 1
},
{
"time_to_first_token": 317,
"time_to_last_token": 518,
"turn": 2
}
]
}
}
```
| Field | Type | Description |
| --------------------- | --------- | ----------------------------------------------- |
| `time_to_connect` | `integer` | Time (ms) to connect to the TTS service |
| `turn` | `integer` | Sequential turn number |
| `time_to_first_token` | `integer` | Time (ms) to generate the **first audio chunk** |
| `time_to_last_token` | `integer` | Time (ms) to complete **all audio generation** |
Modern TTS systems stream audio. Playback begins before the entire response is synthesized, keeping the conversation flowing naturally.
***
## Identifying Bottlenecks
Use these thresholds to pinpoint performance issues across the pipeline:
**Possible causes:**
* Network issues with the transcription service
* Need for a different transcription provider
* Poor audio quality or background noise
**Fix:** Try a different transcriber provider in your [Audio Tab](/docs/agent-setup/audio-tab) configuration, or improve audio input quality.
**Possible causes:**
* LLM model is too large or complex
* Prompts need optimization (too long or unstructured)
* High load on the LLM service
**Fix:** Consider a faster LLM model, optimize your prompt length, or try a different provider in your [LLM Tab](/docs/agent-setup/llm-tab).
**Possible causes:**
* Network issues with the TTS service
* Voice model is computationally expensive
* Provider experiencing high load
**Fix:** Try a different voice or TTS provider in your [Audio Tab](/docs/agent-setup/audio-tab) configuration.
***
## Related Pages
Retrieve execution details with latency data
Track the full lifecycle of your calls
Understand call termination reasons
# Choosing Providers
Source: https://www.bolna.ai/docs/concepts/choosing-providers
How to pick the right transcriber, LLM, and voice synthesizer for your Bolna agent based on language, latency, and quality requirements.
Every Bolna agent uses three provider categories: a **transcriber** (speech-to-text), an **LLM** (language model), and a **synthesizer** (text-to-speech). This page helps you choose the right combination for your use case.
Provider model lineups change frequently. The specific model names here are current examples — always check the relevant [LLM provider page](/docs/providers) or the provider's own docs for the latest recommended model.
***
## Quick Decision Guide
| Primary concern | Transcriber | LLM | Synthesizer |
| ------------------------------------- | --------------- | ------------------------------ | --------------------- |
| English, lowest latency | Deepgram Nova-3 | `gpt-5.4-mini` | ElevenLabs Turbo v2.5 |
| Indian languages (Hindi, Tamil, etc.) | Sarvam | `gpt-5.4-mini` or Sarvam | Sarvam |
| European multilingual | Azure Speech | `gpt-5.4` | Azure TTS |
| Enterprise / data residency | Azure Speech | Azure OpenAI | Azure TTS |
| Cost-sensitive high volume | Deepgram Nova-2 | `deepseek-v4-flash` | AWS Polly |
| Complex reasoning or sensitive domain | Deepgram Nova-3 | `gpt-5.4` or `claude-sonnet-5` | ElevenLabs |
***
## Transcribers (speech-to-text)
Language support is the primary selection factor — most transcribers are optimized for specific language families.
| Provider | Best for | Notes |
| ------------------- | -------------------------- | ----------------------------------------------------- |
| **Deepgram Nova-3** | English | Fastest; best accuracy for English |
| **Deepgram Nova-2** | Many languages | Broader language coverage |
| **ElevenLabs** | English | High accuracy; slightly higher latency |
| **Azure Speech** | Enterprise, many languages | Strong multilingual; good for EU |
| **AssemblyAI** | English | High accuracy; async features |
| **Sarvam** | Indian languages | Best for Hindi, Tamil, Bengali, Telugu, Marathi, etc. |
| **Gladia** | European languages | Good multilingual coverage |
| **Soniox** | English | Low latency option |
Key settings: `endpointing` (silence detection), `language` (always set explicitly — auto-detection adds latency), `encoding` / `sampling_rate` (must match your telephony provider).
***
## LLMs (language models)
Quality tier and latency are the primary selection factors. See each provider's page for current model names.
| Tier | When to use | Examples |
| ------------------------- | ------------------------------------------------------------- | ------------------------------------------------------- |
| **Fast / cost-efficient** | Most agents — lead qualification, reminders, scheduling, FAQs | `gpt-5.4-mini`, `gemini-2.5-flash`, `deepseek-v4-flash` |
| **High quality** | Complex reasoning, financial/medical, sensitive conversations | `gpt-5.4`, `gpt-5.5`, `claude-sonnet-5` |
| **Enterprise** | Data residency requirements | Azure OpenAI |
| **Custom / self-hosted** | On-premise or proprietary models | [Custom LLM](/docs/customizations/using-custom-llm) |
**LLM provider pages:**
GPT-5.4-mini, GPT-5.4, GPT-5.5
Claude Sonnet 5, Haiku 4.5, Opus 4.8
Gemini 2.5 Flash, Gemini 3.x
GPT-5.x via Azure infrastructure
DeepSeek V4 Flash, V4 Pro
Unified gateway — all providers
***
## Synthesizers (text-to-speech)
Latency and language are the primary selection factors. Always enable `stream: true`.
| Provider | Best for | Notes |
| ----------------- | ------------------------------ | ------------------------------------------------------------------------ |
| **ElevenLabs** | Natural English voices | Bolna default; Turbo models are fastest |
| **Cartesia** | Lowest latency English | Very fast time-to-first-audio |
| **Azure TTS** | Multilingual, enterprise | Strong across many languages |
| **AWS Polly** | Cost-sensitive workloads | Lower cost; neural voices available |
| **Deepgram Aura** | English | Fast and accurate |
| **Rime** | Natural conversational English | Good prosody for dialogue |
| **Sarvam** | Indian languages | Native voices for Hindi, Tamil, Telugu, and more |
| **Smallest AI** | Ultra-low latency | Optimized for real-time |
| **Maya** | Indian languages | 11 languages, 2 voices, mid-call language switching without reconnecting |
Key settings: `stream: true` (always enable), `buffer_size` (100–250 chars typical), `audio_format` (must match your telephony provider).
***
## Telephony providers
| Provider | Best for | Notes |
| --------------------- | --------------------------------- | --------------------------------------------- |
| **Plivo** | India + global | Default for most Bolna deployments |
| **Exotel** | India | Strong local support; DLT compliance built in |
| **Twilio** | US / global | Widest geographic reach |
| **Vobiz** | India | Competitive rates |
| **Custom SIP (BYOT)** | On-premise / bring your own trunk | See [SIP Trunking](/docs/sip-trunking/byot-setup) |
***
## Related
* [Providers overview](/docs/providers)
* [Supported Telephony Providers](/docs/supported-telephony-providers)
* [Latency tuning](/docs/concepts/latency)
* [Custom LLM setup](/docs/customizations/using-custom-llm)
* [Multilingual Voice Agents](/docs/customizations/multilingual-languages-support)
# Glossary
Source: https://www.bolna.ai/docs/concepts/glossary
Definitions for the key terms used throughout the Bolna documentation.
## A
**Agent**
A complete Voice AI configuration that can make and receive phone calls. An agent bundles together a prompt, a voice pipeline (transcriber + LLM + synthesizer), telephony settings, and optional tools.
**ASR (Automatic Speech Recognition)**
See *Transcriber*.
**Agent ID**
A UUID that uniquely identifies an agent in Bolna. Required when making calls or managing the agent via API. Example: `5bc97541-e320-4d95-a3a5-242cfe45621d`.
***
## B
**Batch**
A campaign that places calls to a list of recipients uploaded as a CSV file. Batches are created, scheduled, and tracked via the `/batches` API endpoints.
**Batch ID**
A string identifier for a batch. Example: `3c90c3cc0d444b5088888dd25736052a`.
**Buffer size**
The number of text characters the synthesizer accumulates before sending the first audio chunk. Smaller buffers start audio sooner; larger buffers produce smoother speech.
***
## C
**Call-disconnected**
An intermediate execution status — NOT the final state. Fires when the phone line drops, but post-call processing (transcript assembly, cost calculation, extraction) has not yet completed. Always wait for `completed`.
**Completed**
The terminal execution status indicating all post-call processing is done. At this point `conversation_duration`, `total_cost`, `recording_url`, and `extracted_data` are populated.
**Concurrency**
The number of simultaneous active calls your account can run. Visible in `GET /user/me` as `concurrency.max`. Contact support to increase.
**Context details**
Per-call metadata attached at call time, including `recipient_data` (the CSV row columns for batch calls) and any custom fields.
***
## D
**DTMF (Dual-Tone Multi-Frequency)**
Touch-tone signals generated when a caller presses phone keys (0–9, \*, #). Used in IVR agents for menu navigation.
***
## E
**Endpointing**
The process of detecting when a caller has finished speaking. Configured in milliseconds on the transcriber. Too low causes interruptions; too high adds dead air.
**Execution**
A single call event — one phone call placed or received. Identified by an `execution_id`. Contains the full call record: status, transcript, cost, recording URL, extracted data.
**Execution ID**
A UUID identifying a single call execution. Used to poll status or retrieve results. Example: `b7140255-af33-4608-8e97-04dd944b8e48`.
**Extracted data**
Structured data automatically pulled from the conversation transcript by post-call extraction (if configured). Returns a JSON object keyed by category and field name.
***
## G
**Graph agent**
An agent architecture where the conversation is structured as a directed graph of nodes, each with its own prompt and routing rules. Contrast with *conversation agent*.
**Guardrail**
A calling restriction that prevents calls from being placed under certain conditions — time of day, do-not-call lists, daily limits.
***
## H
**Hangup prompt**
A phrase or condition configured on an agent that triggers the agent to end the call when detected in conversation. Example: when the agent says "Goodbye" or "Have a great day."
***
## I
**Inbound call**
A call received by a Bolna agent on a phone number linked to the agent. The caller initiates.
**IVR (Interactive Voice Response)**
An agent type that routes callers based on key presses rather than AI conversation. See [IVR Inbound Calls](/docs/guides/inbound/ivr-inbound-calls).
***
## K
**Knowledge base**
A collection of documents (PDFs, URLs, text) that an agent can search during conversations using RAG (Retrieval-Augmented Generation). Configured in the LLM tab.
***
## L
**Latency**
The delay between when a caller finishes speaking and when the agent starts responding. Measured as Time to First Audio (TTFA) in milliseconds. See [Latency](/docs/concepts/latency).
**LLM (Large Language Model)**
The AI model that processes the conversation transcript and generates the agent's responses. Examples: GPT-4.1, Claude, Gemini.
***
## O
**Outbound call**
A call placed by Bolna to a recipient. Initiated via `POST /call` or as part of a batch.
***
## P
**Pipeline**
The ordered chain of processing components for a task: `[["transcriber", "llm", "synthesizer"]]`. Must be an array of arrays.
**Prompt**
The system instruction given to the LLM that defines the agent's persona, task, and behavior. Written in natural language.
***
## R
**RAG (Retrieval-Augmented Generation)**
A technique where the LLM is given relevant excerpts from a knowledge base before generating a response, allowing it to answer questions from your documents.
**Recording URL**
A URL to the audio recording of the call. Available in `telephony_data.recording_url` after the execution reaches `completed`.
***
## S
**Scheduled\_at**
The ISO 8601 timestamp at which a batch should start calling. Must use a numeric UTC offset (e.g. `+00:00`) — the `Z` suffix is rejected. Must be at least 2 minutes in the future; Bolna rounds up to the next 10-minute mark.
**Synthesizer**
The text-to-speech provider that converts the LLM's response into spoken audio. Examples: ElevenLabs, Cartesia, Azure TTS.
***
## T
**Task**
The unit of work inside an agent. A conversation task handles the real-time conversation; an extraction task runs post-call to pull structured data from the transcript.
**Telephony provider**
The phone network provider that handles call connections, phone number assignment, and audio transport. Examples: Plivo, Twilio, Exotel.
**Time to First Audio (TTFA)**
The latency metric reported per call in `latency_data.time_to_first_audio` (milliseconds). Measures from end of caller's utterance to start of agent's audio response.
**Toolchain**
The configuration block that defines the pipeline and execution mode for an agent task. Contains `execution` (e.g. `"sequential"`) and `pipelines` (array of arrays).
**Transcriber**
The speech-to-text provider that converts caller audio into text in real-time. Examples: Deepgram, Azure Speech, Sarvam.
**Transcript**
The full text of the conversation, with speaker labels (`assistant:` / `user:`). Available in the execution record after `completed`.
***
## W
**Wallet**
The credit balance used to pay for calls. Each call deducts from the wallet based on duration, provider costs, and platform fee. A `balance-low` execution status means the wallet was empty when the call was attempted.
**Webhook**
An HTTP POST that Bolna sends to your server at each execution status change. Delivers the same payload as `GET /executions/{id}`. Source IP: `13.203.39.153`.
***
## Related
* [Platform Concepts](/docs/platform-concepts) — visual overview of how Bolna works
* [Call Flow](/docs/concepts/call-flow) — step-by-step lifecycle of a call
* [Errors & Status Codes](/docs/api-reference/errors) — full status enum tables
# Latency in Real-Time Voice AI
Source: https://www.bolna.ai/docs/concepts/latency
How Bolna measures and minimizes end-to-end latency in voice conversations, and what you can tune to improve response times.
Latency in a voice AI system is the time between when a caller finishes speaking and when they hear the agent start responding. Bolna targets **sub-600ms end-to-end** for a natural conversation feel.
***
## Where latency comes from
Every response goes through three processing stages, each adding latency:
```
Caller stops speaking
↓
Endpointing (50–300ms) ← How long before we decide they're done?
↓
Transcription (50–150ms) ← Speech-to-text processing time
↓
LLM first token (100–400ms) ← Time to first token from the model
↓
Synthesis first chunk (80–200ms) ← TTS time to first audio
↓
Caller hears first word
```
**Time to First Audio (TTFA)** is the total of these stages — the metric Bolna reports in `latency_data.time_to_first_audio` on each execution.
***
## Endpointing
Endpointing is the detection of when the caller has finished speaking. Setting it too low causes the agent to interrupt mid-sentence. Setting it too high adds noticeable dead air.
Bolna uses **voice activity detection (VAD)** with configurable `endpointing` delay (in milliseconds). The default is 250ms.
```json theme={"system"}
"transcriber": {
"provider": "deepgram",
"endpointing": 250
}
```
Increase to 400–500ms for callers who pause mid-sentence (non-native speakers, elderly). Decrease toward 100ms for fast-paced sales scripts.
***
## Transcription latency
Streaming transcribers (Deepgram, Azure, ElevenLabs) return partial transcripts in real-time, with the final transcript arriving 50–150ms after endpointing. The LLM inference begins as soon as the final transcript arrives.
Transcriber choice has a modest effect on latency. Deepgram Nova-3 is generally the fastest option.
***
## LLM latency
The LLM accounts for the largest share of latency. The key metric is **time to first token (TTFT)** — how long before the model starts streaming its response.
| Provider | Typical TTFT |
| ---------------------------------- | ------------ |
| OpenAI gpt-4.1-mini | \~150ms |
| OpenAI gpt-4.1 | \~200ms |
| Anthropic claude-sonnet-4-20250514 | \~250ms |
| Gemini gemini-2.5-flash | \~150ms |
Shorter prompts, lower `max_tokens`, and `temperature` close to 0 all reduce TTFT. Avoid sending large knowledge-base results or long tool outputs back to the LLM unnecessarily.
***
## Synthesis latency
Bolna starts streaming synthesizer audio as soon as the LLM emits the first sentence. You don't wait for the full LLM response.
`buffer_size` controls how many characters to accumulate before sending the first audio chunk. Smaller buffers start audio sooner but can produce choppy speech if the synthesizer is slow to respond.
```json theme={"system"}
"synthesizer": {
"provider": "elevenlabs",
"stream": true,
"buffer_size": 100
}
```
A buffer of 100–150 characters is typical. ElevenLabs Turbo and Cartesia are the lowest-latency synthesis options.
***
## Network and telephony
The call's geographic path also adds latency. A caller in India connecting to a US-hosted telephony provider adds \~100–200ms round-trip. Use a telephony provider with regional presence near your callers:
* India: Plivo, Exotel, Vobiz
* US/global: Twilio, Plivo
For the lowest latency within India, enable Indian server configuration — see [Indian Server Configuration](/docs/enterprise/indian-server-configuration).
***
## Reading latency data
Each completed execution includes:
```json theme={"system"}
"latency_data": {
"time_to_first_audio": 189.69
}
```
`time_to_first_audio` is in milliseconds from the end of the caller's utterance to the start of the agent's audio response.
Monitor this across calls to detect regressions when you change providers, prompts, or model versions.
***
## Summary of tunable parameters
| Parameter | Where | Effect |
| ------------------------- | --------------------------- | ----------------------------------------------------------------------- |
| `endpointing` | transcriber config | Reduce for faster response; increase to avoid mid-sentence interruption |
| `buffer_size` | synthesizer config | Reduce for faster first audio; increase for smoother speech |
| `stream: true` | synthesizer config | Enable for streaming; never disable in production |
| LLM model choice | `llm_config.model` | Smaller models (gpt-4.1-mini, gemini-2.5-flash-lite) have lower TTFT |
| `max_tokens` | `llm_config` | Lower cap reduces tail latency on long responses |
| Telephony provider region | `tools_config.input/output` | Match provider region to callers |
See [Call Latencies](/docs/concepts/call-latencies) for per-provider benchmarks.
# Security & Data Handling
Source: https://www.bolna.ai/docs/concepts/security
How Bolna handles your data, where it is stored, and what controls are available for enterprise and compliance requirements.
## Data in transit
All API requests and responses use **TLS 1.2+**. Audio streams between Bolna and telephony providers are encrypted in transit. Webhook payloads are delivered over HTTPS.
***
## Data at rest
| Data type | What is stored | Retention |
| ------------------- | --------------------------------------------- | ------------------------------------------------------------------- |
| Call recordings | Audio file of the conversation | Available in execution record; contact support for retention policy |
| Transcripts | Full conversation text | Stored in execution record |
| Extracted data | Structured fields from post-call extraction | Stored in execution record |
| Agent configuration | Prompts, tool configs, provider keys | Encrypted at rest |
| API keys | Hashed — Bolna cannot recover a plaintext key | N/A |
***
## Data residency
By default, Bolna processes calls on infrastructure in the US (AWS us-east-1). Indian data residency is available for deployments where data must remain in India.
When Indian data residency is enabled:
* Call processing runs on servers in `ap-south-1` (Mumbai)
* Recordings and transcripts are stored in India
* LLM inference is routed to India-region endpoints (where available)
See [Indian Server Configuration](/docs/enterprise/indian-server-configuration) for setup.
For enterprise customers requiring other regions or on-premise deployment, see [Enterprise Plans](/docs/enterprise/plan) and [On-Premise Deployments](/docs/enterprise/on-premise-deployments).
***
## Webhook security
Bolna sends webhooks from a fixed source IP: **`13.203.39.153`**
To verify webhooks are genuinely from Bolna:
1. Whitelist `13.203.39.153` on your server or firewall
2. Reject webhook requests from any other IP on your webhook endpoint
There is no HMAC signature on webhook payloads in the current version. Source IP verification is the primary trust mechanism.
***
## API key security
* API keys are displayed once at creation — copy and store them securely immediately
* If a key is compromised, revoke it from the [Bolna dashboard](https://platform.bolna.ai) and issue a new one
* Never expose your API key in client-side code or public repositories
* Use environment variables (`BOLNA_API_KEY`) in application code
***
## Provider credential storage
When you configure third-party providers (OpenAI, ElevenLabs, Twilio, etc.) in Bolna, your provider API keys are stored encrypted in Bolna's infrastructure. They are used at call time to authenticate requests on your behalf.
Bolna does not log or expose provider credentials in API responses.
***
## Sub-accounts and access control
Enterprise plans support **sub-accounts** — isolated Bolna accounts under your organization's umbrella. Each sub-account has its own agents, phone numbers, wallet balance, and API keys.
Use sub-accounts to:
* Isolate different customers or business units
* Apply per-sub-account spending limits
* Restrict which agents and numbers a team can access
See [Sub-Accounts](/docs/enterprise/sub-accounts) and [Organization Management](/docs/enterprise/organization).
***
## Compliance
Bolna supports compliance application for regulated industries. Applications are reviewed on a per-account basis.
See [Compliance Introduction](/docs/compliance-application/introduction) to understand the application process.
Bolna undergoes independent security assessments, including Vulnerability Assessment and Penetration Testing (VAPT). Our latest independent VAPT assessment received an A+ rating. If you'd like a copy of the report, request it at [support@bolna.dev](mailto:support@bolna.dev) and we'll share it with you.
For HIPAA, SOC 2, GDPR, or other specific certifications, contact [support@bolna.ai](mailto:support@bolna.ai).
***
## Responsible AI
Bolna agents are subject to the [Calling Guardrails](/docs/guides/outbound/calling-guardrails) system, which lets you configure:
* Time-of-day restrictions for when calls can be placed
* Do-not-call list integration
* Maximum call duration limits
These controls help ensure Bolna is used responsibly and in compliance with telemarketing regulations.
# Auto-Detect and Switch Languages in Bolna Voice AI
Source: https://www.bolna.ai/docs/customizations/auto-switch-multilingual-messages
Learn how Bolna Voice AI automatically detects the caller's language and switches system messages like hangup, user online check, and tool call messages to match.
Bolna Voice AI automatically detects the language your callers speak and switches system messages to match. No manual intervention needed. The agent analyzes the conversation and delivers the right message in the right language.
"Are you still there?" plays in the caller's detected language
Farewell message delivered in the detected language
"Please wait" messages during API calls adapt to the language
***
## How Detection Works
The agent starts in the primary language configured in the [Audio Tab](/docs/agent-setup/audio-tab).
After **3 conversation turns**, Bolna analyzes the caller's transcripts to identify the dominant language being spoken.
Once detected, all configured system messages switch to that language for the rest of the call.
Detection waits for 3 turns to gather enough context for accurate identification. This keeps it fast while avoiding false matches early in the call.
***
## Supported Message Types
### User Online Check Message
When the agent checks if a caller is still on the line after a period of silence, it sends a configurable message. Add variants in multiple languages and Bolna picks the right one automatically.
```json theme={"system"}
{
"check_user_online_message": {
"en": "Hey, are you still there?",
"hi": "क्या आप अभी भी वहाँ हैं?",
"ta": "வணக்கம், நீங்கள் இன்னும் இணைப்பில் இருக்கிறீர்களா?",
"bn": "নমস্কার, আপনি কি এখনও লাইনে আছেন?"
}
}
```
***
### Call Hangup Message
When the agent ends a call, it delivers a closing message. Configure multilingual variants so callers hear a natural farewell in their language.
```json theme={"system"}
{
"call_hangup_message": {
"en": "Thank you for calling. Goodbye!",
"hi": "कॉल करने के लिए धन्यवाद। अलविदा!",
"bn": "কলটি এখন কেটে যাবে। ধন্যবাদ এবং নমস্কার!"
}
}
```
***
### Function Tool Call Messages
When the agent executes a tool or API call, it plays a brief "please wait" message. This message can also be configured per language.
```json theme={"system"}
{
"pre_call_message": {
"en": "Just give me a moment, I'll be back with you.",
"hi": "कृपया थोड़ा समय दीजिए, मैं पता करके बताता हूँ।"
}
}
```
***
## Fallback Behavior
When selecting a message, Bolna follows a three-step fallback:
| Priority | What happens |
| ------------------------ | ------------------------------------------------------------------------- |
| **1. Detected language** | Uses the message in the caller's detected language |
| **2. English** | Falls back to the `en` variant if the detected language is not configured |
| **3. First available** | Uses the first language in the configuration if neither is found |
Always configure an `en` (English) variant as a safe fallback for every message type.
***
## Supported Languages
Auto-detection supports all languages available in Bolna, identified by their ISO 639-1 codes.
| Code | Language | Code | Language | Code | Language |
| ---- | -------- | ---- | -------- | ---- | --------- |
| `en` | English | `hi` | Hindi | `bn` | Bengali |
| `ta` | Tamil | `te` | Telugu | `mr` | Marathi |
| `gu` | Gujarati | `kn` | Kannada | `ml` | Malayalam |
| `pa` | Punjabi | `ur` | Urdu | `as` | Assamese |
For the full list of supported languages, see the [Multilingual Support](/docs/customizations/multilingual-languages-support) guide.
***
## Best Practices
Add message variants for every language your agent supports. Gaps lead to unexpected fallbacks.
Write messages that feel natural in each language. Avoid direct translations.
Always use the language's native script. "धन्यवाद" not "Dhanyavaad".
Verify messages sound natural by testing with native speakers of each language.
***
## Next Steps
Full guide to setting up multilingual agents
Best practices for writing prompts in native scripts
Configure pre-call messages for API tools
Configure user online detection and timeouts
# Capturing precise transcripts in Bolna Voice AI
Source: https://www.bolna.ai/docs/customizations/capturing-precise-transcripts
Bolna Voice AI enables to capture actual transcripts when the conversations involve interruptions to improve call accuracy and experience.
## Overview
Bolna automatically reconstructs conversation transcripts to accurately reflect what was actually spoken during a call.
During natural conversations, callers often interrupt the AI agent before it has finished speaking. Rather than storing the entire response generated by the language model, Bolna intelligently retains only the portion that was actually delivered before the interruption.
This ensures transcripts represent the real conversation, making them more reliable for analytics, summaries, debugging, and downstream workflows.
This behavior is enabled by default for all Bolna voice agents and requires no configuration.
## How It Works
Bolna AI’s interruption handling system functions through a three-step process:
* **Detection of Interruptions**: The system continuously monitors speech input to detect when the user starts speaking while the Voice agent is still speaking.
* **Contextual Computation**: Whenever an interruption is detected, Bolna AI determines whether the user’s input should overrides the Voice agent's response.
* **Final Transcript Adjustment**: Bolna then reconstructs the conversation transcript to exclude everything after the interruption, ensuring that only the final & meaningful parts of the dialogue are retained, processed and used for further processing.
## Example
| Without precise transcript generation | Using precise transcript generation |
| ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **Assistant:** "Hello, Thank you for calling Wayne Enterprises. How can we help you today?" | **Assistant:** "Hello, Thank you for calling Wayne Enterprises. How can we help you today?" |
| **User:** "hello" | **User:** "hello" |
| **Assistant:** "Hello! How can I assist you today?" | **Assistant:** "Hello! How can I ~~assist you today?~~" |
| **User:** "yeah where are you calling from" | **User:** "yeah where are you calling from" |
| **Assistant:** "I'm here to support you regarding your recent order from Wayne Enterprises. How can I assist you?" | **Assistant:** "I'm here to support you regarding your recent order ~~from Wayne Enterprises. How can I assist you?~~" |
| **User:** "yeah i'm facing an issue with the item i purchased" | **User:** "yeah i'm facing an issue with the item i purchased" |
| ... | ... |
In the above example, the strikethrough text is only for representation purposes. In practice, you'll see only the transcripts till the interruptions if the `precise transcript generation` is `enabled`.
## Conclusion
Bolna AI’s interruption handling feature ensures that conversation transcripts reflect actual user intent rather than an unfiltered log of AI responses. By dynamically computing the actual transcript, this feature enhances the efficiency of voice AI applications, making conversations more human-like and structured.
# Dynamically identify incoming callers
Source: https://www.bolna.ai/docs/customizations/identify-incoming-callers
Use Bolna Voice AI agents to identify callers in real time via API, CSV, or Google Sheets and personalize calls with automatic user data injection.
## What is Caller Identification?
Link your inbound phone numbers to custom data sources. When a call comes in, your Bolna Voice AI agent automatically identifies the caller, matches their number, and pulls in relevant details like name, address, preferences, past history, or any data you provide.
This data is seamlessly injected into the agent's prompt, making every interaction personalized and contextual.
***
## Data Source Options
**Best for:** Teams with existing databases or CRM systems.
Provide an API endpoint that accepts the caller's phone number. Bolna automatically sends the following parameters:
| Parameter | Description |
| ---------------- | ------------------------------- |
| `contact_number` | Incoming caller's phone number |
| `agent_id` | Agent handling the call |
| `execution_id` | Unique identifier for this call |
**Example request:**
```
GET https://api.your-domain.com/api/customers?contact_number=+19876543210&agent_id=06f64cb2-...&execution_id=c4be1d0b-...
```
The returned JSON data is automatically merged into the AI prompt before the call begins.
* The endpoint must be a **GET** endpoint
* Supported authentication: **Bearer Token**
**Best for:** Smaller teams who prefer simple, no-code data management.
Upload a CSV file with `contact_number` column (phone numbers with country code) and associated user info. Bolna automatically looks up the incoming number and injects matching row data into the prompt.
```csv theme={"system"}
contact_number,first_name,last_name
+11231237890,Bruce,Wayne
+91012345678,Bruce,Lee
+00021000000,Satoshi,Nakamoto
+44999999007,James,Bond
```
**Best for:** Real-time sync with spreadsheet simplicity.
Link a **publicly accessible** Google Sheet with user data. Bolna auto-syncs and looks up the incoming number to pull the latest data. No re-uploads needed.
| contact\_number | first\_name | last\_name |
| --------------- | ----------- | ---------- |
| +11231237890 | Bruce | Wayne |
| +91012345678 | Bruce | Lee |
| +00021000000 | Satoshi | Nakamoto |
| +44999999007 | James | Bond |
Your Google Sheet can be updated at any time. Bolna agents automatically pick up the latest data in real time.
***
## Related Features
Configure inbound calling for your agents
Pass dynamic data to personalize conversations
Route inbound calls with IVR menus
# Multilingual Config Reference
Source: https://www.bolna.ai/docs/customizations/multilingual-config-reference
The multilingual_config object reference for building Bolna multilingual voice agents over the API. Per-language transcriber, synthesizer, prompts, handoff messages, and language switching.
When you build an agent through the [dashboard](/docs/customizations/multilingual-languages-support), Bolna generates the multilingual configuration for you. If you create or update agents over the API instead, you provide that configuration directly through the `multilingual_config` object.
This page documents the object: where it lives, every field, its validation rules, and how Bolna expands it for the call.
***
## Where it lives
`multilingual_config` sits inside `tools_config` on the first task of the agent payload you send to `POST /v2/agent`:
```json theme={"system"}
{
"agent_config": {
"tasks": [
{
"tools_config": {
"transcriber": { "provider": "deepgram", "model": "nova-3", "language": "en" },
"synthesizer": { "provider": "elevenlabs", "provider_config": { "voice_id": "..." } },
"multilingual_config": {
"enabled": true,
"active_language": "en",
"languages": { }
}
}
}
]
}
}
```
The top-level `transcriber` and `synthesizer` act as the **base**. Each language in `multilingual_config.languages` starts from that base and applies its own overrides on top. The agent opens the call in `active_language`.
***
## Top-level fields
| Field | Type | Required | Default | Description |
| ------------------------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled` | boolean | yes | `false` | Must be `true` for multilingual to take effect. When `false` (or omitted), the object is dropped and the agent runs single-language. |
| `active_language` | string | no | `"en"` | Language code the agent starts the call in. Must be a key in `languages`. |
| `languages` | object | yes | — | Map of language code to a per-language config. Minimum **2** languages. |
| `switch_tool_description` | string | no | — | Overrides the description of the `switch_language` tool the LLM uses to change languages mid-call. |
Two validation rules are enforced on agent create and update:
1. `languages` must contain at least **2** entries.
2. `active_language` must be one of the keys in `languages`.
Failing either returns `Invalid multilingual config` and the agent is not saved.
***
## Per-language entry
Each value in `languages` is keyed by an [ISO 639-1 code](#supported-languages) and has this shape:
```json theme={"system"}
{
"hi": {
"transcriber": {
"language": "hi"
},
"synthesizer": {
"provider": "sarvam",
"provider_config": {
"voice_id": "anushka",
"model": "bulbul:v2"
}
},
"system_prompt": "आप एक सहायक एजेंट हैं। हिंदी में संक्षेप में उत्तर दें।",
"handoff_message": "ठीक है, मैं हिंदी में बात करता हूँ।",
"agent_name": "राज"
}
}
```
| Field | Type | Required | Description |
| ----------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transcriber` | object | no | Speech-to-text override for this language. If omitted, the base transcriber is used with the language code applied. Must include `language`; extra provider fields are allowed (for example `model`, `language_hints`). |
| `synthesizer` | object | yes | Text-to-speech config for this language. Requires `provider` and `provider_config`. Optional `buffer_size`. Extra fields are allowed. |
| `system_prompt` | string | no | Prompt activated while the agent speaks this language. Write it in the language's native script. |
| `handoff_message` | string | no | Message played when the agent switches to this language. |
| `agent_name` | string | no | Agent name used while speaking this language. |
### How overrides layer onto the base
* **Transcriber**: the per-language `transcriber` is merged onto the base transcriber, then the `language` field is resolved to the provider's expected format (for example Sarvam `hi` becomes `hi-IN`). If you omit `transcriber`, the base transcriber is reused with the language code set to the entry's key.
* **Synthesizer**: if the per-language `provider` matches the base, only the differing keys (including a shallow merge of `provider_config`) are applied. If the `provider` differs, the per-language synthesizer replaces the base entirely. For `sarvam`, `smallest`, `cartesia`, `openai`, `pixa`, and `polly`, the language is resolved into `provider_config.language` automatically.
This lets each language use a different STT and TTS provider. A common setup uses Deepgram for English transcription and Sarvam for Hindi, with ElevenLabs voice for English and Sarvam voice for Hindi.
***
## Language switching
Once `multilingual_config` is enabled, Bolna injects a `switch_language` tool so the LLM can change language mid-call, and runs language detection in parallel so the agent can follow the caller automatically.
* **Prompt-driven**: describe when to switch in your prompt (for example "switch to Hindi if the user speaks Hindi"). The LLM calls `switch_language` and the transcriber, synthesizer, and active system prompt all switch together.
* **Auto-detection**: after a few conversation turns Bolna identifies the dominant language and switches system messages to match. See [Auto-Switch Languages](/docs/customizations/auto-switch-multilingual-messages).
* **`switch_tool_description`**: customize how the switch tool is described to the LLM when you need tighter control over switching behavior.
***
## Full example
A two-language agent (English primary, Hindi secondary) with a different STT and TTS provider per language:
```json theme={"system"}
{
"agent_config": {
"tasks": [
{
"tools_config": {
"transcriber": {
"provider": "deepgram",
"model": "nova-3",
"language": "en"
},
"synthesizer": {
"provider": "elevenlabs",
"provider_config": {
"voice_id": "21m00Tcm4TlvDq8ikWAM",
"model": "eleven_turbo_v2_5"
}
},
"multilingual_config": {
"enabled": true,
"active_language": "en",
"switch_tool_description": "Switch the conversation language when the caller changes language.",
"languages": {
"en": {
"synthesizer": {
"provider": "elevenlabs",
"provider_config": {
"voice_id": "21m00Tcm4TlvDq8ikWAM",
"model": "eleven_turbo_v2_5"
}
},
"system_prompt": "You are a helpful assistant. Keep replies short.",
"agent_name": "Alex"
},
"hi": {
"transcriber": {
"language": "hi"
},
"synthesizer": {
"provider": "sarvam",
"provider_config": {
"voice_id": "anushka",
"model": "bulbul:v2"
}
},
"system_prompt": "आप एक सहायक एजेंट हैं। हिंदी में संक्षेप में उत्तर दें।",
"handoff_message": "ठीक है, मैं हिंदी में बात करता हूँ।",
"agent_name": "राज"
}
}
}
}
}
]
}
}
```
***
## Supported languages
| Language | Code | Language | Code | Language | Code |
| ---------- | ---- | -------- | ---- | -------- | ---- |
| English | `en` | Hindi | `hi` | Bengali | `bn` |
| Assamese | `as` | French | `fr` | Gujarati | `gu` |
| Indonesian | `id` | Kannada | `kn` | Malay | `ms` |
| Malayalam | `ml` | Marathi | `mr` | Odia | `od` |
| Punjabi | `pa` | Spanish | `es` | Tamil | `ta` |
| Telugu | `te` | Urdu | `ur` | Dutch | `nl` |
Provider support varies by language. Pick an STT and TTS provider per language that covers it. For Indian languages, Sarvam covers the widest set.
***
## Next Steps
Set up the same agent from the dashboard
Auto-detect and switch system messages by language
Write per-language prompts in native scripts
Full agent creation API reference
# Set Up Multilingual Voice AI Agents
Source: https://www.bolna.ai/docs/customizations/multilingual-languages-support
Deploy Bolna Voice AI agents in multiple languages. Configure per-language prompts, language switching, handoff messages, and multilingual knowledge bases.
Bolna supports multiple languages, letting you deploy voice agents globally. Language support is integrated across all components: transcription, LLM processing, and voice synthesis.
***
## How Multilingual Agents Work
A multilingual agent can understand and respond in multiple languages within a single call. Here is how the pieces fit together:
Add languages in the [Audio Tab](/docs/agent-setup/audio-tab) or [Agent Tab](/docs/agent-setup/agent-tab). They stay synced across both.
Each language gets its own prompt tab. Write a dedicated prompt for every language your agent supports.
A shared instruction field tells the agent when to switch languages mid-call.
***
## Setting Up Languages
In the [Audio Tab](/docs/agent-setup/audio-tab) or [Agent Tab](/docs/agent-setup/agent-tab), click **+ Add Language**. Languages sync between both tabs automatically.
Click the **crown icon** next to any language to make it primary. The primary language is what the agent starts every conversation in.
In the [Agent Tab](/docs/agent-setup/agent-tab), select each language tab and write its prompt. The agent activates the matching prompt when speaking in that language.
In the [Advanced Settings](/docs/agent-setup/agent-tab#per-language-advanced-settings) for each language, set a **Handoff Message** that plays when the agent transitions away from that language.
***
## Language Switching
The **Language Switching Instructions** field in the [Agent Tab](/docs/agent-setup/agent-tab) is a single shared field that applies to all languages. It tells the agent when and how to switch languages during a call.
| What to include | Example |
| ---------------------- | ----------------------------------------------------- |
| **Trigger conditions** | "Switch to Hindi if the user speaks in Hindi" |
| **Fallback behavior** | "Fall back to English if the language is unsupported" |
| **Default rule** | "Respond in the language the user is currently using" |
Write these once. They apply across all languages automatically.
### Auto-Switching System Messages
Beyond prompt-level switching, Bolna can also **auto-detect** the caller's language and switch system messages to match. This works for:
"Are you still there?" adapts to the caller's language
Farewell message plays in the detected language
"Please wait" messages during API calls match the language
Detection activates after 3 conversation turns to ensure accuracy. See the full [Auto-Switch Languages](/docs/customizations/auto-switch-multilingual-messages) guide for setup details.
***
## Per-Language Configuration
Each language you add gets its own independent configuration:
| What | Where | Scope |
| ----------------------------------- | ---------------------------- | ----------------- |
| **Prompt** | Agent Tab, language tabs | Per language |
| **Agent Name** | Agent Tab, Advanced Settings | Per language |
| **Handoff Message** | Agent Tab, Advanced Settings | Per language |
| **Language Switching Instructions** | Agent Tab | Shared across all |
| **Text-to-Speech** | Audio Tab | Per language |
| **Speech-to-Text** | Audio Tab | Per language |
Each language can use a different STT and TTS provider. For example, use **Deepgram** for English transcription and **Sarvam** for Hindi, or **ElevenLabs** for English voice and **Sarvam** for Hindi voice. Select a language tab in the [Audio Tab](/docs/agent-setup/audio-tab) to configure its providers independently.
Settings are independent per language. The Agent Name, Handoff Message, STT provider, and TTS provider for Hindi do not affect English.
***
## Supported Languages
| Language | Code |
| ---------- | ---- |
| English | `en` |
| Hindi | `hi` |
| Bengali | `bn` |
| Assamese | `as` |
| French | `fr` |
| Gujarati | `gu` |
| Indonesian | `id` |
| Kannada | `kn` |
| Malay | `ms` |
| Malayalam | `ml` |
| Marathi | `mr` |
| Odia | `od` |
| Punjabi | `pa` |
| Spanish | `es` |
| Tamil | `ta` |
| Telugu | `te` |
| Urdu | `ur` |
| Dutch | `nl` |
***
## Writing Effective Multilingual Prompts
Write prompts in the language's native script, not phonetic English. "नमस्ते" not "Namaste".
Use proper accents for European languages. "Cómo estás?" not "Como estas?"
**Hindi**
* Incorrect: "Namaste! Aap kaise ho?"
* Correct: "नमस्ते! आप कैसे हैं?"
**Spanish**
* Incorrect: "Hola! Como estas?"
* Correct: "¡Hola! ¿Cómo estás?"
**French**
* Incorrect: "Bonjour! Comment ca va?"
* Correct: "Bonjour ! Comment ça va ?"
Read the full [guide for writing prompts in non-English languages](/docs/guides/writing-prompts-in-non-english-languages) for detailed best practices.
***
## Multilingual Knowledge Bases
If your agent uses knowledge bases with non-English documents, enable **multilingual** support when creating the knowledge base. This supports 100+ languages, allowing your agent to retrieve information regardless of document or query language.
Learn more in the [Knowledge Base documentation](/docs/getting-started/knowledge-base#multilingual-knowledge-bases).
***
## Next Steps
Configure per-language prompts and handoff messages
Set up languages, voices, and transcription
Auto-detect and switch system messages by language
Best practices for writing multilingual prompts
# Using Custom LLMs with Bolna Voice AI
Source: https://www.bolna.ai/docs/customizations/using-custom-llm
Integrate custom large language models (LLMs) into Bolna Voice AI to enhance agent capabilities and tailor responses to your unique requirements
We expect your custom LLM to be an OpenAI compatible server.
* [https://platform.openai.com/docs/api-reference/chat/create](https://platform.openai.com/docs/api-reference/chat/create)
* [https://platform.openai.com/docs/api-reference/chat/streaming](https://platform.openai.com/docs/api-reference/chat/streaming)
## Adding your Custom LLM using dashboard
1. Click on LLM select dropdown as shown in the image
2. From the dropdown click on `Add your own LLM`.
3. A dialog box will be displayed. Fill in the following details:
* `LLM URL`: the endpoint of your custom LLM
* `LLM Name`: a name for your custom LLM
click on `Add Custom LLM` to connect this LLM to Bolna
4. **Refresh the page**
5. In the LLM settings tab, choose `Custom` in the first dropdown to select LLM Providers
6. In the LLM settings tab, you'l now see your custom LLM model name appearing. Select this and save the agent.
**Using the above steps will make sure the agent uses your Custom LLM URL**.
## Demo video
Here's a working video highlighting the flow:
# Developer Resources
Source: https://www.bolna.ai/docs/developer-resources/overview
Everything you need to build on Bolna — SDKs, the REST API, the CLI, the MCP server, and the open-source core — in one place.
Bolna is built to be integrated, scripted, and extended. This page is a map of every way to work with Bolna as a developer — pick the entry point that matches how you want to build.
Drop live voice conversations into your own app. Starts with the **Web Call SDK** for browser-based WebRTC calls.
Create agents, place calls, run batches, and pull executions over HTTP from any language.
Manage agents, calls, phone numbers, and batches from your terminal — no dashboard required.
Connect Claude, Cursor, Windsurf, or any MCP client directly to your Bolna account.
Bolna Skills teach Claude Code, Cursor, and Codex to build and debug agents from plain-English prompts.
The core Bolna framework, MIT-licensed and self-hostable — inspect it, extend it, or run it on your own infrastructure.
***
## Developer community
Tutorials, demos, and walkthroughs for building and deploying voice agents.
Product updates, comparisons, and deep dives on voice AI.
Ask questions and talk to the Bolna team and other builders directly.
# Concurrency Management for Organizations
Source: https://www.bolna.ai/docs/enterprise/concurrency-management
Understand how Bolna allocates outbound call concurrency across an organization and its sub-accounts using guaranteed minimums and maximum caps.
## Overview
An organization has a pool of outbound call concurrency to share across its **main account** and any **sub-accounts**. Bolna divides that pool using two settings on each account:
Concurrency **reserved** for an account — it can always run at least this many calls, even when the rest of the organization is busy.
The **ceiling** an account can reach. Leave it unset to make the account **elastic** — free to burst into the organization's unused capacity.
Together these let you guarantee critical workloads a floor of capacity while still letting quieter accounts borrow spare capacity when it's available.
Concurrency management applies to organizations with sub-accounts, an Enterprise feature. Reach out at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) to get set up.
## The organization envelope
Your organization's envelope is provisioned by Bolna:
* **Organization maximum** — the hard ceiling on total simultaneous outbound calls across the main account and every sub-account combined. The organization never exceeds this.
* **Organization guaranteed minimum** — the capacity Bolna guarantees your organization as a whole, even when the wider platform is under load.
You then distribute that envelope across your accounts. Each account gets its own `min_concurrency` (its guaranteed floor) and an optional `max_concurrency` (its cap).
## Per-account settings
| Setting | Meaning | Notes |
| ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `min_concurrency` | Guaranteed floor for the account | `0` means no guarantee — the account only runs calls when spare capacity is available |
| `max_concurrency` | Hard cap for the account | Omit (or `null`) for **elastic** — the account can burst up to the organization maximum. `0` **pauses** the account |
The main account and each sub-account each carry their own pair of values.
## How calls are allocated
Each scheduling cycle, Bolna decides how many new calls to start per account:
Every account is brought up to its guaranteed minimum before any spare capacity is handed out. Calls already in progress are never dropped to make room.
Whatever is left in the organization pool is shared among the accounts that still have calls waiting, in proportion to their guarantees — so an account with a larger floor also gets a larger share of the surplus.
A capped account bursts up to its `max_concurrency`; an elastic account (no max) can keep climbing until the organization pool is full.
Calls that don't fit this cycle stay queued and dial automatically as in-flight calls finish. Inbound calls are never queued.
## Telephony providers and your concurrency
Queued calls are tracked **per telephony provider**, so congestion on one provider stays contained to that provider:
* **An account's capacity is split evenly across its providers.** Dialing is not first-come-first-served across an account's whole queue: its share of the pool is divided equally between the providers it has calls waiting on, and any share a provider can't use passes to the others. Within a single provider, calls dial in the order they were queued.
* **One busy provider doesn't stall the others.** If a provider is temporarily out of capacity, your accounts keep dialing their queued calls on every other provider at their usual share of the pool.
* **Your own provider credentials don't share capacity.** Calls placed on an account's [own provider account](/docs/providers) are limited by that account's guarantee and cap alone — never by how busy the provider is for other Bolna customers.
For example, an account allowed 700 concurrent calls with 15,000 calls queued on one provider and 15,000 on another runs 350 on each, both dialing continuously, rather than draining the first queue before starting the second.
[SIP trunking (BYOT)](/docs/sip-trunking/introduction) is the exception to the point above: those calls run on Bolna's SIP infrastructure, so they share platform capacity even though the trunk is yours.
When a telephony provider is saturated platform-wide, Bolna temporarily rations each organization toward its **guaranteed minimum** on **that provider only**: floors are still honored and every other provider keeps bursting, until the saturated provider frees up.
## Configuration rules
When you set or change limits, Bolna validates the whole account set so guarantees and caps stay consistent with the organization envelope:
* The sum of all account **minimums** must not exceed the organization's guaranteed minimum.
* The sum of all **capped** account maximums must not exceed the organization maximum. Elastic accounts (no max) are not counted toward this sum.
* For any account, `min_concurrency` must not exceed `max_concurrency`.
An edit that breaks a rule is rejected with a `400` explaining which sum was exceeded, for example:
```json theme={"system"}
{
"message": "Sum of account minimums (60) exceeds the org minimum (50) by 10; lower an account minimum first."
}
```
## Worked example
An organization with a maximum of **100** concurrent calls, distributed across three accounts:
| Account | `min_concurrency` | `max_concurrency` | Behavior |
| ------------- | ----------------- | ----------------- | --------------------------------------------------------- |
| Main | 20 | *(elastic)* | Always has 20; can burst toward 100 when capacity is free |
| Sales (sub) | 30 | 50 | Always has 30; bursts up to 50 |
| Support (sub) | 10 | 30 | Always has 10; bursts up to 30 |
* **Only Sales is busy:** Sales runs up to its cap of 50; the remaining capacity stays available for the other accounts.
* **All three busy, demand over 100:** each account first gets its guarantee (20 + 30 + 10 = 60), then the remaining 40 is shared in proportion to those guarantees, up to each account's cap. Anything that still doesn't fit queues and dials as calls finish.
* **One provider saturated:** the organization is rationed toward its guaranteed minimum on that provider — the guarantees above are preserved — while calls on the organization's other providers keep bursting normally.
## Who can manage it
Only **organization admins** can set or change account concurrency, from the dashboard or the API. Sub-account members cannot.
## Setting concurrency
Set `min_concurrency` and `max_concurrency` when creating a sub-account.
Change an existing sub-account's guarantee or cap.
For the broader account tiers (trial, paid, enterprise), see [Concurrency tiers](/docs/outbound-calling-concurrency).
# Bolna AI Data residency
Source: https://www.bolna.ai/docs/enterprise/data-residency
Bolna AI India data residency for enterprises: store & process voice AI data in India with compliance, privacy & ultra-low latency.
## Overview
Bolna AI now supports data residency in India (IN) for customers who require their data to be stored and processed within Indian jurisdiction.
By default, all Bolna AI services operate in United States (US)‑hosted infrastructure, but customers on enterprise plans can choose to have their data processed exclusively in India.
This feature helps organizations meet local compliance, privacy, and sovereignty requirements while continuing to benefit from Bolna’s real‑time AI capabilities.
Data residency is an Enterprise feature. Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for more information.
## What’s Included
When you select India (IN) as your data residency location:
* **Storage**: All customer audio, transcripts, logs, and configurations are stored on secure infrastructure physically located in India.
* **Processing**: All inference, transcription, and response generation happens within Indian borders.
## When to Use India Data Residency
India‑based data residency is recommended if you:
* Are subject to Indian data localization laws or work in regulated industries like banking, government, healthcare, or telecom.
* Want to ensure all processing and storage remain inside Indian borders for privacy or competitive reasons.
* Need to meet contractual obligations with Indian clients regarding data handling.
# Routing Calls Through Indian Servers
Source: https://www.bolna.ai/docs/enterprise/indian-server-configuration
Configure your voice agent to process calls on Indian servers for data residency compliance and lower latency.
## Overview
If your business requires data residency in India or you want to achieve the lowest possible latency for calls to Indian phone numbers, you can configure your agent to route calls through Bolna's Indian servers.
This guide explains the configuration requirements to ensure your calls are processed entirely on Indian infrastructure.
## Requirements
To route calls through Indian servers, your agent configuration must meet **all** of the following requirements:
### 1. Telephony Provider
Use **Plivo** as your telephony provider.
Twilio is not supported for Indian server routing. If you use Twilio, calls will be processed on US servers.
### 2. Transcriber (Speech-to-Text)
Use one of these transcription providers:
* Deepgram
* Azure
* Sarvam
* ElevenLabs
* Smallest
**If using Deepgram**, additional requirements apply:
| Requirement | Supported Values |
| ------------ | ----------------------------------------------------------------------------------- |
| **Model** | `nova-2`, `nova-3`, and their variants (e.g., `nova-2-phonecall`, `nova-3-general`) |
| **Language** | `hi` (Hindi), `multi-hi` (Multilingual Hindi), `en-IN` (Indian English) |
### 3. Synthesizer (Text-to-Speech)
Use one of these voice synthesis providers:
* ElevenLabs
* Sarvam
* Azure TTS
* Cartesia
Some ElevenLabs voices may not be available in the India region. If you encounter issues, try selecting a different voice.
### 4. LLM (Language Model)
Use one of these LLM providers:
* Azure OpenAI
### 5. Provider API Keys
Use Bolna's default provider integrations. Do not connect your own API keys for the transcriber, synthesizer, or LLM providers.
If you connect your own API keys for any provider (transcriber, synthesizer, or LLM), calls will automatically route through US servers regardless of other configuration settings.
## Quick Checklist
Before deploying your agent for Indian server routing, verify:
| Component | Requirement | Status |
| ----------------- | ------------------------------------------------ | -------- |
| Telephony | Plivo | Required |
| Transcriber | Deepgram, Azure, Sarvam, ElevenLabs, or Smallest | Required |
| Deepgram Language | `hi`, `multi-hi`, or `en-IN` (if using Deepgram) | Required |
| Synthesizer | ElevenLabs, Sarvam, Azure TTS, or Cartesia | Required |
| LLM | Azure OpenAI | Required |
| Custom API Keys | None connected | Required |
## Troubleshooting
If your calls are not routing through Indian servers, check the following:
1. **Telephony Provider**: Ensure you're using Plivo, not Twilio
2. **Deepgram Language**: If using Deepgram, verify the language is set to `hi`, `multi-hi`, or `en-IN`
3. **Custom API Keys**: Check that you haven't connected your own API keys for any provider in the Providers section
4. **Provider Selection**: Verify all providers (transcriber, synthesizer, LLM) are from the supported lists above
## Related Resources
* [Supported Telephony Providers](/docs/supported-telephony-providers)
* [Plivo Setup Guide](/docs/plivo)
* [Understanding Latency Metrics](/docs/concepts/call-latencies)
# Bolna AI On-Prem for Enterprise
Source: https://www.bolna.ai/docs/enterprise/on-premise-deployments
Discover Bolna Enterprise solutions for large-scale businesses, offering scalable Voice AI agents, advanced integrations, and custom seamless solutions.
**Bolna AI On-Prem** empowers your organization to deploy our best-in-class voice AI infrastructure. It is fully containerized and runs entirely within your cloud or data center. Designed for high-security, high-performance workloads, it's ideal for industries with stringent data requirements.
Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for more information about Bolna On-Premise deployments.
## Deployment Anywhere, Full Control
* Deploy **dockerized containers** or use **Kubernetes** across any cloud or on-prem environment.
* Supports deployment on **your own servers** fully leveraging your existing infrastructure.
* Choose your preferred region and provider (AWS, GCP, Azure, bare metal, private cloud).
## Data Privacy & Compliance
* **Complete data sovereignty**: All audio, requests, logs and transcripts remain within your environment. Nothing is sent to Bolna's servers. This ensurs compliance with healthcare, financial, and legal regulations.
* Regular performance and usage metrics are securely sent to Bolna cloud solely for billing and system optimizations.
* Full audit logs for monitoring all outbound activity, giving your security team complete visibility.
## Performance, Scalability & Reliability
* Achieve **ultra-low latency** by co-locating inference with your existing application stack.
* Scale horizontally and separate API and websocket containers, and auto-scale based on demand.
## Enterprise-Grade Operations
* Fully compatible with Bolna APIs, without any changes to your integration. You can simply point to your self-hosted endpoint.
# Bolna AI On-Prem guide for Enterprises
Source: https://www.bolna.ai/docs/enterprise/on-premise-instructions
Learn how to self-host Bolna Voice AI on your own servers using Docker or Kubernetes for secure, private, and scalable enterprise deployments.
Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for the Docker images and pricing info.
## 1. Introduction
### Why on-premise?
Deploying Voice AI infrastructure on your own server (on-premises or self-managed cloud infrastructure) instead of relying entirely on third-party SaaS solutions has several strategic, technical, and operational advantages, especially for companies focused on privacy, control, and performance.
### Security
With an on-premises deployment, all data remains within your corporate network, ensuring enhanced security as it is not transmitted over the Internet. This setup helps in complying with strict data privacy and protection regulations.
### Components
### Prerequisites
**Docker**: Install Docker on your system to manage the containerized application.
```bash theme={"system"}
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install the latest version of Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Verify Docker is running
sudo docker run hello-world
# Install Docker Compose plugin
sudo apt install -y docker-compose-plugin
# Verify Docker Compose version
docker compose version
```
**Hardware Specifications**: Storage and compute requirements
* **Instance type**: c6a.xlarge
* **Object storage**: AWS S3
* **Relational Database**: PostgreSQL 16.3, RAM: 8GB+
* **Caching layer**: Redis 7.10, 4GB RAM (Instance type: cache.t4g.medium)
* **Message Queueing Channel**: RabbitMQ 13.13.7, RAM: 8GB (Instance type: mq.m5.large)
## 2. Deployment Environments
This documentation will cover specific instructions and considerations for deploying the services within an AWS environment, ensuring optimal configuration and performance.
## 3. Self-Service Licensing & Credentials
Self-hosting key can be either generated from our dashboard or contact [enterprise@bolna.ai](mailto:enterprise@bolna.ai)
## 4. Deploy All Services
### Login to Bolna's ghcr
```bash theme={"system"}
echo | docker login ghcr.io -u --password-stdin
```
### Pull images
```bash theme={"system"}
docker pull ghcr.io/bolna-ai/api_server:v1
docker pull ghcr.io/bolna-ai/ws_server:v1
docker pull ghcr.io/bolna-ai/telephone_server:v1
docker pull ghcr.io/bolna-ai/q_manager:v1
docker pull ghcr.io/bolna-ai/q_worker:v1
docker pull ghcr.io/bolna-ai/arq_worker:v1
```
### Docker Compose File:
Create a docker-compose.yml File
```bash theme={"system"}
version: '3.8'
services:
api_server:
image: ghcr.io/bolna-ai/api_server:v1
container_name: api_server
ports:
- "5001:5001"
env_file:
- .env
restart: always
telephone_server:
image: ghcr.io/bolna-ai/telephone_server:v1
container_name: telephone_server
ports:
- "8001:8001"
env_file:
- .env
restart: always
q_worker:
image: ghcr.io/bolna-ai/q_worker:v1
container_name: q_worker
ports:
- "5002:5002"
env_file:
- .env
restart: always
q_manager:
image: ghcr.io/bolna-ai/q_manager:v1
container_name: q_manager
ports:
- "5003:5003"
env_file:
- .env
restart: always
ws_server:
image: ghcr.io/bolna-ai/ws_server:v1
container_name: ws_server
ports:
- "5005:5005"
env_file:
- .env
restart: always
arq_worker:
image: ghcr.io/bolna-ai/arq_worker:v1
container_name: arq_worker
env_file:
- .env
restart: always
command: ["arq", "arq_worker.WorkerSettings"]
```
### Start docker compose:
```bash theme={"system"}
docker compose up -d
```
# Managing Your Organization & Team
Source: https://www.bolna.ai/docs/enterprise/organization
Learn how to manage your Bolna organization, invite team members, and configure roles and permissions for secure and efficient voice AI operations.
## Overview
Your Bolna Organization is the central hub for all your voice AI resources. It acts as a top-level container for your team members, voice agents, billing information, API keys, and overall settings. Proper organization management is key to scaling your operations securely and efficiently.
Within an organization, you can manage access for different team members, monitor usage across all your agents, and configure security policies that apply to your entire team.
This is an Enterprise feature.
Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for more information.
## Managing Team Members
You can invite new members to your organization and assign and edit roles based on their responsibilities. This ensures that team members only have access to the resources they need to perform their jobs.
* **Invite Members**: Organization Admins can invite new users via email from the 'Members' tab in the organization settings.
* **Assign Roles**: Each member is assigned a role that dictates their level of access and permissions within the organization.
* **Edit Roles**: Organization Admins can edit the access level of existing users by selecting the organization role they want to assign to their members.
## Roles and Permissions
Bolna uses a simple two-role system to manage access control within your organization.
* **Admin**: Has full, unrestricted access to the organization. Admins can manage billing, invite or edit member roles, create and delete agents, and manage all API keys. They have complete control over all settings.
* **Member**: Has limited access designed for operational tasks. Members can place calls on existing agents. They can create and manage their own API keys but cannot access API keys belonging to the admin or other members. Members are restricted from performing most delete operations (like deleting agents).
## Editing Existing User Roles
* In order to update existing user roles, click on the Edit Icon for the user you want to edit the organization role of.
* This opens up a dialog box where you can update the role that you want to edit.
## Usage & Billing
The **Billing** tab provides a complete overview of your subscription, plan details, and usage metrics like total call minutes and number of active agents. You can view invoicing history and manage your payment methods here.
The organization's balance is shared across all users. All usage from both Admin and Member accounts is deducted from this single, centralized balance.
## API Keys
Both Admins and Members can generate API keys for programmatic access. However, access is scoped based on role:
* **Admin Keys**: Have full permissions and can perform any action via the API.
* **Member Keys**: Are restricted to the same permissions as the Member role. They can be used to call agents but cannot perform most of the delete or edit actions. Members can delete and create their own API Keys while not having access to the admins or other member's keys.
# Bolna AI Enterprise Plan
Source: https://www.bolna.ai/docs/enterprise/plan
Discover Bolna Enterprise solutions for large-scale businesses, offering scalable Voice AI agents, advanced integrations, and custom seamless solutions.
As you build your application on Bolna to solve your use-case, we partner with you throughout the journey - from early concept to enterprise-grade deployment.
## What is included in the Enterprise Plan?
Bolna's Enterprise Plan is built for organizations with high-volume, mission-critical voice needs. It includes:
### Elevated concurrency limits
Scale beyond the default 10 concurrent calls to handle hundreds or thousands of simultaneous conversations based on your needs. Learn more about [outbound calling concurrency](/docs/pricing/outbound-calling-concurrency).
### Priority in processing your calls and requests
Enterprise customers skip queues during peak usage, ensuring consistent performance even during high-demand periods.
### Premium Slack support and regular check-ins
Access guaranteed support and a dedicated engineer who understands your use case and can provide proactive assistance.
### Customized volume-based discounts
Competitive pricing that improves as your call volume grows, making enterprise-scale deployments cost-effective. See our [call pricing](/docs/pricing/call-pricing) for standard rates.
## Who should consider the Enterprise Plan?
The Enterprise Plan is ideal for:
* Companies making 10,000+ calls per month
* Organizations requiring guaranteed uptime and SLAs
* Businesses needing dedicated technical support
* Teams building mission-critical voice AI applications
* Companies requiring custom integrations or features
* Organizations with specific data residency requirements ([learn more](/docs/enterprise/data-residency))
## How to get started with Enterprise
Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call at [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for more information and a customized quote based on your requirements.
# Sub-Accounts for Enterprise Organizations
Source: https://www.bolna.ai/docs/enterprise/sub-accounts
Bolna AI enterprise sub-accounts let you manage multiple customers & teams with full data isolation, unified billing & centralized control.
## Overview
Bolna's Sub-Account feature is designed for enterprise organizations that need to manage multiple customers, business units, or operational environments under a single main account. This powerful organizational tool provides complete data isolation, centralized management, and scalable operations for complex voice AI deployments.
Sub-accounts enable you to create logical boundaries within your account, ensuring that different customers, departments, or projects operate independently while maintaining unified oversight and control.
Sub-accounts is an Enterprise feature.
Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for more information.
## Key Sub-account Advantages
### Complete Data Isolation
* **Customer separation**: Maintain strict boundaries between different customer data and configurations
* **Audit trails**: Comprehensive logging and monitoring for each sub-account independently
### Centralized Management & Control
* **Unified dashboard**: Manage all sub-accounts from a single enterprise control panel
* **Consolidated billing**: Streamlined invoicing and cost allocation across all sub-accounts
* **Resource allocation**: Distribute and monitor usage quotas across sub-accounts
## Primary Use Cases
### Service Providers & Agencies
Transform your voice AI service delivery with enterprise-grade multi-tenancy:
* **Customer isolation**: Each client gets their own environment with dedicated resources
* **Flexible billing**: Accurate cost tracking and billing for each client account
### Large Enterprise Organizations
Organize your voice AI infrastructure across complex organizational structures:
* **Department separation**: Sales, support, marketing, and operations teams get isolated environments
* **Regional management**: Separate voice AI deployments by geographic regions or markets
* **Product line organization**: Different products or services get dedicated sub-accounts
* **Subsidiary management**: Manage voice AI for multiple company subsidiaries independently
### Development & Testing Teams
Maintain clean separation between different environments and projects:
* **Environment isolation**: Separate development, staging, and production deployments
* **Team collaboration**: Multiple teams work on isolated projects without interference
* **Feature testing**: Test new voice AI capabilities without affecting production systems
* **A/B testing**: Run parallel experiments with completely isolated data sets
### Compliance-Heavy Industries
Meet strict regulatory and compliance requirements:
* **Healthcare**: Separate patient data and HIPAA-compliant voice AI deployments
* **Financial services**: Isolated environments for different financial products or regions
* **Government**: Secure, compliant voice AI for different agencies or departments
* **Legal**: Client-specific environments with strict confidentiality requirements
## Managing Sub Accounts
### Creation
Sub-accounts are managed within the [Organization](/docs/enterprise/organization). Only **organization admins** can create, update, or delete sub-accounts and set their concurrency.
### API Keys & Access
* Sub-accounts themselves cannot generate or manage API keys.
* When a sub-account is created, an associated API key is automatically provisioned.
### Usage & Billing
* Usage can be accessed for [each sub account's usage](/docs/api-reference/sub-accounts/usage) or by [all the sub accounts](/docs/api-reference/sub-accounts/all_usage) across the entire organization.
* Navigate to [Sub-Account Usage](https://platform.bolna.ai/dashboard/subaccounts?tab=usage) to see detailed breakdowns.
* Billing is consolidated at the **organization level**, but with granular visibility into sub-account consumption for accurate cost tracking.
### Roles & Permissions
* Only **organization admins** can create, update, or delete sub-accounts and manage their concurrency.
* Sub-accounts are **not users** — they act as logical containers for agents, call logs, and usage separation.
* Access to sub-account data is scoped by API keys.
### Concurrency
* Each sub-account has a guaranteed concurrency floor (`min_concurrency`) and an optional hard cap (`max_concurrency`); leaving the cap unset makes the sub-account elastic so it can burst into the organization's unused capacity.
* See [Concurrency management](/docs/enterprise/concurrency-management) for how guarantees, caps, and shared capacity work across the organization.
### Resource Isolation
* Sub-accounts provide isolation at the **agents and call logs** level.
* Shared resources such as **phone numbers and providers** remain available at the organization level, allowing reuse across multiple sub-accounts.
* This ensures logical boundaries while still enabling efficient resource management.
### Lifecycle Management
* Sub-accounts can be created and updated via the dashboard or API.
* Create, update, and delete are restricted to **organization admins**.
### Audit & Monitoring
* Sub-accounts maintain independent usage logs, analytics, and call histories.
* These can be viewed centrally by **Admins** using the sub-account’s associated API key or the dashboard.
* This provides enterprise-wide observability while preserving operational separation between environments.
For detailed technical implementation, see our [Sub-Account API Reference](/docs/api-reference/sub-accounts/overview).
Enterprise sub-accounts are designed for organizations with complex operational needs.
Our enterprise team will work with you to design the optimal sub-account architecture for your specific requirements.
# Frequently Asked Questions
Source: https://www.bolna.ai/docs/frequently-asked-questions
Find answers to common questions about Bolna Voice AI — setup, pricing, APIs, phone numbers, multilingual agents, sub-accounts, and on-premise deployment.
All agents created on Bolna undergo internal compliance and safety checks.
If you see a message such as **“Agent is restricted due to disallowed content. Please review and update it.”**, it means your agent’s configuration or prompt may have triggered a violation of Bolna’s content safety policies.
Disallowed content includes (but is not limited to):
* Political campaigns
* Illegal activities or solicitation
* Scam or fraud-related behavior
* Profanity or hate speech
* NSFW, adult, or sexually explicit content
* Harmful or misleading information
To resolve this, please review and modify your agent’s prompt, instructions, or behavior to ensure it adheres to a valid use-case.
Once updated, you can re-save the agent to re-trigger validation.
Bolna supports a wide range of customizable voice agents. From free-flowing conversational assistants to structured IVR-style bots.
You can build agents for use cases like [lead qualification](/docs/agents-library), customer support, interviews, [appointment bookings](/docs/tool-calling/book-calendar-slots), [call transfers](/docs/tool-calling/transfer-calls), and more.
Get started with our [Agent template library](/docs/agents-library) or explore the [Playground agent setup guide](/docs/agent-setup/agent-tab).
Bolna offers transparent usage-based pricing:
* **Call pricing**: \$0.02/min platform fee (plus provider charges).
Please refer to the [cost & pricing documentation](/docs/pricing/call-pricing) for detailed information. For high-volume usage, explore our [Enterprise Plan](/docs/enterprise/plan) with customized volume-based discounts.
Your flat rate only covers a specific set of **preferred ASR, LLM, and TTS models**. If your agent uses a model outside that list, that component is billed separately at variable, usage-based rates instead of being included in the flat rate.
Check the **Add Funds** panel (click the **+** next to your wallet balance in [Agent Studio](https://platform.bolna.ai)) for the current preferred model list, or see the [Preferred models documentation](/docs/pricing/preferred-models) for the full breakdown.
By default, Bolna allows up to **10 concurrent calls** for paid users. Learn more about [outbound calling concurrency](/docs/pricing/outbound-calling-concurrency) or request higher limits via the [Enterprise Plan](/docs/enterprise/plan) for large-scale deployments and [batch calling](/docs/guides/outbound/batch-calling) capabilities.
**Yes**. You can either:
* **Buy phone numbers directly** from the [Bolna Dashboard](/docs/guides/inbound/buying-phone-numbers).
* **Use your own telephony account** (e.g., [Twilio](/docs/twilio-connect-provider) or [Plivo](/docs/plivo-connect-provider)) to connect and use your own manageed dedicated phone numbers.
No - Phone numbers purchased on Bolna can only be used with Bolna Voice AI agents.
Absolutely. Bolna integrates seamlessly with third-party telephony providers like [Twilio](/docs/twilio-connect-provider) and [Plivo](/docs/plivo-connect-provider), allowing you to use your own account and phone numbers.
Yes. Bolna supports multiple languages and voices. You can create agents in various languages (e.g., English, Hindi) using built-in multilingual support across [speech-to-text](/docs/providers/transcriber/deepgram), [LLM](/docs/providers/llm-model/openai), and [text-to-speech](/docs/providers/voice/elevenlabs) components.
Find the [list of all supported languages](/docs/customizations/multilingual-languages-support) and learn how to [write prompts for multilingual agents](/docs/guides/writing-prompts-in-non-english-languages).
Yes, definitely. Bolna AI is an API-first platform providing a comprehensive API suite to:
* Create, update, list, and delete voice agents via [Agent APIs](/docs/api-reference/agent/v2/overview).
* Trigger calls via [Call APIs](/docs/api-reference/calls/overview).
* Manage executions and logs via [Executions APIs](/docs/api-reference/executions/overview).
* Do bulk calls using batches via [Batches APIs](/docs/api-reference/batches/overview).
* Manage phone numbers via [Phone numbers APIs](/docs/api-reference/phone-numbers/overview).
* Create, list and manage sub‑accounts via [Sub-Account APIs](/docs/api-reference/sub-accounts/overview).
Yes. The platform supports shared access where you can add your team (developers, operators, analysts, etc.) to collaborate within the Bolna dashboard. APIs also allow scoped access through sub‑accounts.
Yes. Bolna supports multiple sub-accounts, designed for enterprise-level teams to isolate projects, billing, and permissions—fully manageable via the API.
Yes - Bolna AI supports on-premise deployments.
You can run the complete Bolna platform on your own infrastructure (e.g., private cloud or on-premise servers) instead of the hosted Bolna service.
On-premise is available only for enterprise customers. Please reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai) or schedule a call [https://www.bolna.ai/meet](https://www.bolna.ai/meet) for more information.
Not yet. SIP connectivity is **not currently supported** on Bolna Voice AI.
However, native SIP integration is on our roadmap to enable direct enterprise-grade connectivity with PBX systems and VoIP infrastructure.
You can currently use [Twilio](/docs/twilio-connect-provider), [Plivo](/docs/plivo-connect-provider) or [Exotel](/docs/exotel-connect-provider) integrations for all telephony and call-routing needs.
# Getting Help
Source: https://www.bolna.ai/docs/getting-help
Community resources, support channels, and what to include when reporting an issue with Bolna.
Stuck on something, or think you've found a bug? Here's where to look and who to contact, depending on what you need.
## Community & Resources
Ask questions and get real-time help from the Bolna team and other builders.
Search these docs from the bar at the top of any page, or browse the sidebar by topic.
Quick answers to the questions we hear most often — pricing, concurrency, phone numbers, and more.
Ready-made prompts and configs for common use cases — lead qualification, support, scheduling, and more.
Tutorials, demos, and walkthroughs for building and deploying voice agents.
Check real-time platform status, ongoing incidents, and maintenance notices before filing a report.
Before reaching out, check the [Status Page](https://status.bolna.ai) — if there's an ongoing incident, it's likely already being tracked there.
## Direct Support Channels
| Channel | Contact | Use for |
| ---------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **General Support** | [support@bolna.ai](mailto:support@bolna.ai) | Technical issues, account/billing questions, feature requests |
| **Enterprise & Sales** | [enterprise@bolna.ai](mailto:enterprise@bolna.ai) | Enterprise plan, sub-accounts, on-premise deployments, data residency, custom pricing — or [schedule a call](https://www.bolna.ai/meet) |
| **Regulated Numbers & Compliance** | [compliance@bolna.ai](mailto:compliance@bolna.ai) | LOA requests and DLT/TRAI compliance for regulated Indian phone numbers |
| **Security & Certifications** | [support@bolna.ai](mailto:support@bolna.ai) / [support@bolna.dev](mailto:support@bolna.dev) | HIPAA, SOC 2, GDPR certification requests, and VAPT report requests — see [Security](/docs/concepts/security) |
## What to Include When Reporting an Issue
The faster we can reproduce a problem, the faster we can fix it. Include the following details depending on the issue type.
* Agent ID and agent type (single-prompt or [graph agent](/docs/graph-agent/introduction))
* What you expected the agent to do vs. what it actually did
* Steps to reproduce, including any inputs or user\_data variables passed
* The relevant `execution_id` and conversation transcript, if the issue happened on a live or test call
* The `execution_id` (call ID), phone number, and timestamp of the call
* Direction (inbound/outbound) and telephony provider used
* A description of the issue — latency, dropped audio, wrong transcription, premature hangup, etc.
* Raw logs for the call, pulled via [Get Execution Raw Logs](/docs/api-reference/executions/get_execution_raw_logs) or the [debug-bolna-calls](/docs/agent-setup/call-history) view in the dashboard
* Browser and version
* Steps to reproduce
* Screenshots or the exact error message shown
* The account email associated with your Bolna workspace
* The `batch_id` and affected recipient row(s) from your CSV
* Expected vs. actual outcome for those recipients
* Whether the issue affects the whole batch or specific recipients — see [Batch Calling](/docs/guides/outbound/batch-calling)
## Enterprise Support
Enterprise customers get a dedicated Slack channel with premium support, priority response times, and a dedicated engineer who knows your use case. See the [Enterprise Plan](/docs/enterprise/plan) or reach out at [enterprise@bolna.ai](mailto:enterprise@bolna.ai).
# Build Knowledge Base with PDFs & URLs
Source: https://www.bolna.ai/docs/getting-started/knowledge-base
Upload PDFs and add URLs to create knowledge bases for your Bolna Voice AI agents. Enable context-aware responses with RAG-powered retrieval.
## What is Knowledge Base?
Knowledge Base allows you to upload documents and add URLs that your AI agent can reference during conversations. Using RAG (Retrieval-Augmented Generation), your agent retrieves relevant information and provides accurate, context-aware responses.
***
## How to Access Knowledge Base
Navigate to [platform.bolna.ai](https://platform.bolna.ai/)
Click **Knowledge Base** in the left sidebar.
Click the blue **Add Knowledge Base** button to get started.
***
## Adding a Knowledge Base
Upload PDF documents for your agent to reference.
Open the modal from the main Knowledge Base page.
The **Upload PDF** tab is selected by default.
Drag and drop your PDF file, or click **"click to browse"** to select.
Choose **English (Default)** or **Multilingual (Hindi, Tamil, etc.)** from the **Language Support** dropdown.
Click **Upload PDF** to start processing.
Only `.pdf` files are supported for document upload.
Add website URLs for your agent to reference.
Open the modal from the main Knowledge Base page.
Click the **Add URL** tab.
Paste the full URL (e.g., `https://example.com`).
Choose **English (Default)** or **Multilingual (Hindi, Tamil, etc.)** from the **Language Support** dropdown.
Click **Add URL** to start processing.
Add your company website, FAQ pages, or product documentation URLs for comprehensive agent knowledge.
***
## Multilingual Knowledge Bases
By default, knowledge bases are optimized for English content. If your documents are in **non-English languages** (Hindi, Spanish, French, etc.) or you need **cross-lingual retrieval** (e.g., query in English, retrieve from Hindi documents), enable **Multilingual** language support when creating a knowledge base.
| Mode | Best for |
| -------------------------- | ---------------------------------------------------------------------- |
| **Default** (no selection) | English-only documents and queries |
| **Multilingual** | Non-English documents, mixed-language queries, cross-lingual retrieval |
Choose the language support mode **before** uploading. Existing knowledge bases cannot be switched between default and multilingual — you'll need to create a new one.
If your agent handles calls in multiple languages using [multilingual voice support](/docs/customizations/multilingual-languages-support), pair it with a multilingual knowledge base for consistent cross-lingual performance.
***
## Managing Your Knowledge Bases
Your uploaded knowledge bases are displayed in a table with full management capabilities.
| Column | Description |
| ----------- | ------------------------------------------------------ |
| **RAG ID** | Unique identifier for the knowledge base |
| **Source** | Original file name or URL |
| **Type** | Content type (Pdf, Url) |
| **Created** | When the knowledge base was added |
| **Status** | Processing status (`processed`, `processing`, `error`) |
| **Delete** | Remove the knowledge base |
Wait for the status to show **"processed"** before connecting to your agent. If status shows **"error"**, try re-uploading the file.
***
## Connecting to Your Agent
**Don't forget this step!** Knowledge bases must be connected to your agent in the LLM Tab to take effect.
Go to your agent's **[LLM Tab](/docs/agent-setup/llm-tab)**.
Locate **Add knowledge base (Multi-select)**.
Check one or more knowledge bases from the dropdown.
Click **Save agent** to apply changes.
You can connect multiple knowledge bases to a single agent for comprehensive responses across different topics.
***
## Use Cases
Answer questions about your products and services
Provide accurate answers from your FAQ pages
Reference company policies during calls
Help agents access training and onboarding content
***
## Next Steps
Connect knowledge base to your agent
Configure prompts to use knowledge
Set safety rules and structured responses
Prompting best practices
# Agent Setup
Source: https://www.bolna.ai/docs/graph-agent/agent-setup
Configure the welcome message, LLM, voice, and conversation behaviour for your graph agent.
With no node or transition selected, the inspector shows the **Agent setup** tab. This is where you configure everything that applies to the agent as a whole, rather than to a specific node.
***
## Agent Basics
The first collapsible section contains top-level agent settings.
| Field | Description |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Agent name** | The display name for this agent in the Bolna dashboard. |
| **Start node** | The entry-point node for every new call. Equivalent to clicking **Make start node** on a node in the canvas. |
| **Welcome message** | The first thing the agent says when a call connects, before any node is active. Supports `{variable}` tokens — see [Variables](/docs/graph-agent/variables). |
| **Global prompt** | System-level prompt applied to every LLM call in this agent. Use it for persona, language rules, guardrails, and pronunciation rules. This is the `agent_information` field in the JSON schema. |
***
## Welcome message
The first thing the agent says when a call connects, before any node is active.
```
Hi there! Thanks for calling Acme support. How can I help you today?
```
You can use `{variable}` tokens in the welcome message. Any tokens here are discovered by the [Variables panel](/docs/graph-agent/variables) so you can set test values.
***
## LLM settings
Controls the response LLM used across all nodes that don't override it individually.
| Field | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Provider** | The LLM provider (e.g. OpenAI, Anthropic, Google). |
| **Model** | Specific model name. Choose from the dropdown of supported models for the selected provider. |
| **Temperature** | Controls response randomness. Lower values (0.0–0.5) produce consistent, predictable output. Higher values (0.8–1.5) produce more varied responses. GPT-5 models accept only `1`. |
| **Max tokens** | Cap on the number of tokens in each response. On GPT-5 models this budget is shared with reasoning tokens. |
| **Reasoning effort** | For models that support it. The control offers only the values the selected model accepts, so the options change when you switch models. Higher effort increases latency and cost; stay at the lowest one or two settings for voice. |
Individual nodes can override these settings in their **LLM overrides** section. The agent-level settings serve as the default for any node that doesn't override them.
***
## STT settings (speech-to-text)
Configures the transcriber that converts the caller's voice to text.
| Field | Description |
| ------------------- | ---------------------------------------------------------------------------------------- |
| **Transcriber** | Select from supported STT providers. |
| **Advanced config** | JSON editor for provider-specific settings (e.g. language hints, keywords, punctuation). |
***
## TTS settings (text-to-speech)
Configures the voice synthesis that converts the agent's text responses to audio.
| Field | Description |
| ------------------- | ------------------------------------------------------------------------------------- |
| **Language** | The primary language for voice synthesis. |
| **Advanced config** | JSON editor for synthesizer-specific settings (voice ID, speaking rate, pitch, etc.). |
***
## Conversation settings
Controls call-level behaviour: timeouts, silence handling, backchanneling, and special modes.
### Timing
| Setting | Description | Default |
| ------------------------- | --------------------------------------------------------------------------- | ------- |
| **Welcome message delay** | Seconds to wait after the call connects before playing the welcome message. | 0 |
| **Hang up after silence** | Seconds of total silence before the agent ends the call. | — |
| **Call terminate** | Hard timeout in seconds for the entire call. | — |
### Interruption
| Setting | Description |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Number of words for interruption** | Minimum words the user must speak before the agent considers it an interruption and stops speaking. Lower values make the agent more interruptible. |
### Backchanneling
Backchanneling plays short filler phrases ("Mm-hmm", "I see") while the agent is processing, so the caller doesn't experience dead silence.
| Setting | Description |
| --------------- | ---------------------------------------------------------- |
| **Enabled** | Toggle backchanneling on or off. |
| **Start delay** | Seconds to wait before the first backchannel phrase plays. |
| **Message gap** | Minimum seconds between backchannel phrases. |
### Online check
Periodically checks whether the user is still on the line.
| Setting | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Enabled** | Toggle online check on or off. |
| **Trigger after** | Seconds of silence before checking if the user is still there. |
| **Check message** | The phrase the agent says to check (e.g. "Are you still there?"). Supports multilingual object (`{"en": "...", "hi": "..."}`). |
### Voicemail detection
| Setting | Description |
| ---------------------- | --------------------------------------------------------------------- |
| **Enabled** | Toggle voicemail detection on or off. |
| **Detection duration** | Seconds to wait while determining whether the call went to voicemail. |
### Discard pre-welcome utterance
When enabled, any speech detected before the welcome message finishes playing is discarded. Useful for outbound calls where the recipient often says "Hello?" before the agent starts speaking.
***
## Extra agent config
An advanced JSON editor for any agent configuration keys not covered by the fields above. Changes here are merged into `agent_config` when the agent is saved. Use this for platform-specific settings not yet exposed in the UI.
Only keys the platform knows about are written on save. Unknown keys are dropped. Check the [API reference](/docs/api-reference/agent/create) for a full list of accepted fields.
# Debugging Graph Agents
Source: https://www.bolna.ai/docs/graph-agent/debugging
Read the routing logs, understand what the routing LLM saw, and fix the most common misbehaviour patterns.
The fastest way to diagnose a misbehaving graph agent is to read the routing logs. On every customer turn the framework logs the routing decision, the confidence, and the reason. This page walks through the log format and the patterns you'll see most often.
***
## What you'll see in the logs
Every customer turn produces one routing log line. Two formats, depending on whether the routing LLM ran or a deterministic rule fired first.
**LLM-routed turn:**
```
Routing decision (LLM): transition_to_offer_pitch | confidence: 0.95 |
reasoning: Customer confirmed identity by saying 'yeah'. (latency: 210.4ms)
```
**Deterministic turn (expression or unconditional edge):**
```
Routing decision (deterministic): -> after_hours |
deterministic:expression:Outside working hours (latency: 0.6ms)
```
| Field | What it tells you |
| --------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `LLM` vs `deterministic` | Whether the routing LLM made the call, or an expression / unconditional rule fired first. |
| `transition_to_` or `-> ` | The target node the routing picked. |
| `confidence` (LLM only) | How certain the LLM was. Close to `1.0` means a clear match. Below `0.6` suggests ambiguous edges. |
| `reasoning` | Why this transition was chosen. The single most useful field for debugging wrong transitions. |
| `latency` | How long routing took. Deterministic edges are sub-millisecond; LLM routing is typically 150 to 300ms. |
When the routing LLM picks `stay_on_current_node`, the agent **still produces a response** on the current node. It does not stay silent.
***
## Common scenarios
### Agent keeps re-asking instead of moving forward
The routing LLM is returning `stay_on_current_node`. Read the `reasoning` value in the routing log: it almost always explains what it thought was missing.
Common causes:
* The edge condition is too strict, or uses vocabulary the LLM wouldn't associate with what the customer said.
* The customer's input genuinely doesn't match any condition. Add a broader fallback edge.
* The edge has `parameters` and the customer hasn't provided one of the required values yet.
### Agent routes to the wrong node
Two edge conditions are overlapping. The routing LLM is matching the wrong one. Check the `reasoning` value in the routing log to see which condition it picked and why, then rewrite the conditions to be more specific and mutually exclusive.
### Confidence is consistently low
Edge conditions are ambiguous or too similar to each other. Rewrite them, or add expression edges for the deterministic cases (working hours, retry counts, language) so the LLM has fewer overlapping options.
### Agent skips a node unexpectedly
An expression edge fired before the LLM got a chance. Check whether any expression edges on the previous node have overly broad conditions. For example `_node_turns gte 1` would always fire on the second turn regardless of what the customer said.
### Time-based expression never fires
`recipient_data.timezone` was not set on the call. Without it, `current_hour`, `current_weekday`, etc. are never populated and every time-based comparison silently returns `False`. Always set `timezone` when creating a call that uses time-based routing.
### Agent forgets earlier context on long calls
The response LLM only sees the most recent 50 messages of conversation history. For most calls this is fine, but on very long flows the agent can lose earlier turns. Persist important state into `context_data` (extracted via edge `parameters` or pushed via event properties) instead of relying on the LLM seeing it in the transcript.
### Static node plays the wrong text or wrong voice
The cache was built from an earlier version of the config. Re-save the agent so the cache regenerates from the current `static_message` and TTS voice settings.
### Event fires but the agent stays silent
Most likely causes, in rough order:
1. The call had already ended when the event arrived. Check that you got `202 Accepted`, not `404`.
2. The event name doesn't match any edge on the **current** node. Event edges only fire on the active node. Check the most recent `Routing decision` log line to see where the call actually was when the event landed.
3. The user was speaking when the event resolved. The node still transitioned, but proactive generation was deliberately skipped. The next user turn will route on the new node naturally.
4. There's no event edge for that name anywhere on the node. Add one or rename the event to match an existing edge.
# Edges & Routing
Source: https://www.bolna.ai/docs/graph-agent/edges-and-routing
Edge types, expression operators, built-in variables, and how routing decisions are made on every turn.
Every node has a list of `edges`. After each customer message, the framework picks the next node by checking deterministic edges first (instant, free), then handing off to the routing LLM if nothing deterministic matches.
***
## Edge fields
| Field | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `to_node_id` | Target node id. Required. |
| `condition` | Human-readable description of when to transition. Used as the routing LLM's tool description. |
| `condition_type` | One of `"llm"` (default if unset), `"expression"`, `"unconditional"`, `"event"`. |
| `expression` | Required when `condition_type == "expression"`. See [Expression edges](#expression-edges). |
| `event_name` | Required when `condition_type == "event"`. The external event name to listen for. See [Event injection](/docs/graph-agent/event-injection). |
| `function_name` | Override the auto-generated routing tool name (default: `transition_to_`). |
| `function_description` | Override the auto-generated routing tool description. |
| `parameters` | Map of `{name: type}` to extract from the user's input during the transition. See [Inline data extraction](#inline-data-extraction). |
| `priority` | Lower fires first. Defaults: expression / unconditional / event = `0`, llm = `100`. |
***
## Edge types
| `condition_type` | How it works | When to use |
| ------------------ | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| Not set or `"llm"` | Routing LLM evaluates `condition` against the customer's reply. | When the decision requires understanding intent. |
| `"expression"` | Rule-based check on context variables. Fires instantly if matched. | Time of day, retry counts, language detection, any data-driven decision. |
| `"unconditional"` | Always takes this edge. No check. | When there is only one possible next step. |
| `"event"` | Fires only when a matching external event arrives via REST. Ignored during speech routing. | When an external system (payment, form, link click) drives the conversation. See [Event injection](/docs/graph-agent/event-injection). |
Expression and unconditional edges are checked together (in `priority` order, ascending) **before** any LLM call is made.
To put routing in its own node instead of on a conversational node's edges — a silent classifier or a pre-conversation dispatcher — use a [router node](/docs/graph-agent/router-nodes).
***
## Expression edges
```json theme={"system"}
{
"to_node_id": "after_hours",
"condition": "Outside working hours",
"condition_type": "expression",
"expression": {
"logic": "or",
"conditions": [
{ "variable": "recipient_data.current_hour", "operator": "lt", "value": 10 },
{ "variable": "recipient_data.current_hour", "operator": "gte", "value": 18 }
]
}
}
```
Use `"logic": "and"` when all conditions must be true. Use `"logic": "or"` when any one is enough.
### Operators
`eq`, `neq`
`gt`, `gte`, `lt`, `lte`
`contains`
`in`, `not_in`
`exists`, `not_exists`
### Priority
Lower priority fires first. Defaults if not set: deterministic edges (expression, unconditional, event) get priority `0`; LLM edges get priority `100`. Within the deterministic bucket, the **first** matching edge wins. For mutually-exclusive rules (e.g. working-hours vs after-hours), set distinct priorities to make ordering explicit.
***
## Built-in variables
These variables are populated automatically and can be referenced in any expression.
| Variable | Type | Notes |
| -------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `recipient_data.current_hour` | int (0-23) | Hour in the call's timezone. |
| `recipient_data.current_minute` | int (0-59) | |
| `recipient_data.current_weekday` | string | Lowercase, e.g. `"wednesday"`. |
| `recipient_data.current_day` | int (1-31) | |
| `recipient_data.current_month` | int (1-12) | |
| `recipient_data.current_year` | int | |
| `recipient_data.current_date` | string | Display string for prompts only, not for comparisons. |
| `recipient_data.current_time` | string | Display string for prompts only. |
| `recipient_data.timezone` | string | e.g. `"Asia/Kolkata"`. |
| `recipient_data.user_number` | string | E.164 phone number. |
| `detected_language` | string | Top-level, not under `recipient_data`. e.g. `"hindi"`, `"en"`. |
| `_node_turns` | int | User messages on the **current** node. Resets on every transition. |
| `_total_turns` | int | User messages in the entire call. |
| `_silence_repeats` | int | Times the current node has replayed because the user stayed silent past `repeat_after_silence_seconds`. Resets on transition. See [Static nodes](/docs/graph-agent/static-nodes). |
Time variables (`current_hour`, `current_weekday`, etc.) are populated **only when `recipient_data.timezone` is set on the call**. Without a timezone, time-based expressions silently never match. Always set `timezone` when creating a call that uses time-based routing.
***
## Typed variables
Values used in expressions often arrive as strings (event properties, extracted `parameters`, dynamic `context_data`). So `"18"` would not match `18`, and `"false"` would not be treated as a boolean. Declare the variable's type and both sides of the comparison are converted before matching.
Add a `variable_types` map at the top level of the graph config. Each key is the variable path, written **exactly** as it appears in the condition (including dot-notation):
```json theme={"system"}
{
"variable_types": {
"recipient_data.age": "number",
"recipient_data.hold_status": "boolean",
"plan_tier": "string"
}
}
```
| Type | Matches |
| --------- | ----------------------------------------------------------------- |
| `number` | Any number or numeric string, e.g. `18` or `"18"`. |
| `boolean` | `true` / `1` / `yes` and `false` / `0` / `no` (case-insensitive). |
| `string` | Compared as text. |
```json theme={"system"}
{
"to_node_id": "premium_flow",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "recipient_data.age", "operator": "gte", "value": 18 },
{ "variable": "recipient_data.hold_status", "operator": "eq", "value": true }
]
}
}
```
Declare a type whenever a value can arrive as a string. If you leave a variable out, the framework guesses based on the values, which is fine for plain numbers but unreliable for booleans.
***
## Common patterns
**Working hours (10 AM to 6 PM)**
```json theme={"system"}
{
"to_node_id": "transfer_call",
"condition": "Working hours",
"condition_type": "expression",
"priority": 0,
"expression": {
"logic": "and",
"conditions": [
{ "variable": "recipient_data.current_hour", "operator": "gte", "value": 10 },
{ "variable": "recipient_data.current_hour", "operator": "lt", "value": 18 }
]
}
}
```
**Auto-escalate after too many retries**
```json theme={"system"}
{
"to_node_id": "transfer_call",
"condition": "Too many retries on this node",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "_node_turns", "operator": "gte", "value": 2 }
]
}
}
```
***
## Inline data extraction
Edges can capture typed values from the user's reply during routing. The routing LLM treats them as required parameters; on a successful transition the values are merged into `context_data` and become available everywhere.
```json theme={"system"}
{
"to_node_id": "confirm_order",
"condition": "Customer provided their order id",
"parameters": {
"order_id": "string"
}
}
```
After the transition, `context_data["order_id"]` is set and you can:
* Reference it in node prompts via `{order_id}`.
* Use it in downstream expression edges: `{ "variable": "order_id", "operator": "exists" }`.
* Pass it to API tools as `%(order_id)s`.
Prefer `parameters` over a separate "extract" node. One LLM call routes **and** captures data.
***
## Routing instructions
The `routing_instructions` field is prepended to every routing request. Keep it short and directive:
```
You are the Routing System for this conversation. Analyze the user's input
and the available edges. Select the edge whose condition best matches.
If no edge matches, stay on the current node.
```
You can include `{variable}` placeholders. They are substituted from `context_data` (and the flattened `recipient_data`) at runtime. Missing keys render as `NULL`.
# Real-Time Event Injection
Source: https://www.bolna.ai/docs/graph-agent/event-injection
Drive graph agent transitions and proactive agent speech from external events via REST, without waiting for the user to speak.
Speech is one input to a graph agent. Events are the other. When a customer opens a payment link, completes a form, or finishes a transaction on your website, you want the agent to react immediately rather than wait for the user to say something.
Event injection adds a REST endpoint, `POST /v1/call/{run_id}/events`, that lets your backend push named events into a live call. A matching event edge transitions the conversation and triggers proactive agent speech, all in under a second.
***
## Configuring an event edge
Add edges with `condition_type: "event"` and an `event_name`. They are ignored during normal speech routing, so they coexist freely with LLM and expression edges on the same node.
```json theme={"system"}
{
"id": "awaiting_payment",
"prompt": "User is completing payment via {method}. Reassure them.",
"edges": [
{
"to_node_id": "confirmation",
"condition_type": "event",
"event_name": "payment_completed"
},
{
"to_node_id": "payment_failed",
"condition_type": "event",
"event_name": "payment_failed"
}
]
}
```
A node can mix all three edge types: event edges (fire on external signal), expression edges (fire on context variables), and LLM edges (fire on user speech). Whichever input arrives first drives the transition.
### Edge field reference
| Field | Type | Required | What it does |
| ---------------- | --------- | -------- | ------------------------------------------------------------------------------------- |
| `condition_type` | `"event"` | Yes | Marks this edge as event-triggered. Skipped during speech routing. |
| `event_name` | string | Yes | The event name to match (e.g. `"link_opened"`, `"payment_completed"`). |
| `to_node_id` | string | Yes | Target node for the transition. |
| `priority` | number | No | If multiple event edges match the same name, lower priority fires first. Default `0`. |
***
## Firing an event
```bash theme={"system"}
curl -X POST https://api.bolna.ai/v1/call/{run_id}/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "link_opened",
"properties": { "step": "verify" }
}'
```
```
202 Accepted
{ "status": "accepted", "event": "link_opened", "run_id": "..." }
404 Not Found
{ "detail": "No active call found for this run_id" }
```
* `run_id` is returned by `POST /call` for outbound calls or arrives in your webhook for inbound calls.
* Fire-and-forget. The endpoint returns 202 as soon as the event is published.
* `properties` are merged into the agent's `context_data`, so they become available as `{variable}` substitution in node prompts and as `variable` references in expression edges.
***
## What happens when an event arrives
| Scenario | Behaviour |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event matches an edge on the current node | Properties merged into `context_data`, transition fires, agent speaks proactively. |
| Event doesn't match any edge | Properties still merged into `context_data`. No speech, but the next LLM call sees the new context. |
| Agent is currently speaking | Buffered at a safe point, processed after the current utterance finishes. |
| User is speaking when the event resolves | Node transitions, but proactive generation is **skipped**. The user's in-progress utterance routes on the new node. Prevents the agent from interrupting itself. |
| LLM is generating a response | Buffered until generation completes. |
| Two events arrive rapidly | Processed sequentially in arrival order. |
| Event transitions to a static node | Cached audio plays in \~50ms. Zero LLM cost. |
| Event arrives on a node with no event edges for that name | No transition. Properties still merge into `context_data` silently. |
***
## How proactive speech stays natural
When an event drives a transition, the agent must speak without the user saying anything. Two design choices make this feel natural rather than scripted:
1. Event `properties` are merged into `context_data`, so the new node's `prompt` can reference them via `{variable}` substitution.
2. The conversation history is **not** polluted with fake user messages. The agent simply produces a new assistant turn on the new node.
The result: a transcript that reads as consecutive assistant messages, exactly as a human agent would speak after seeing a screen update.
***
## Latency
| Target node type | Latency | Cost |
| ---------------- | --------------------- | ---------------- |
| LLM node | \~800ms (LLM + TTS) | LLM tokens + TTS |
| Static node | \~50ms (cached audio) | Zero |
If a confirmation message never changes, point your event edge at a [static node](/docs/graph-agent/static-nodes) for the fastest possible response.
***
## Worked example: payment confirmation
The agent waits while the user completes a payment on the bank's website. Your backend fires `payment_completed` when the gateway confirms.
### Graph config (3 nodes)
```json theme={"system"}
[
{
"id": "awaiting_payment",
"prompt": "Payment initiated. Reassure the user while it processes. Amount: {payment_currency} {payment_amount}.",
"repeat_after_silence_seconds": 20,
"edges": [
{
"to_node_id": "confirmation",
"condition_type": "event",
"event_name": "payment_completed"
},
{
"to_node_id": "payment_failed",
"condition_type": "event",
"event_name": "payment_failed"
}
]
},
{
"id": "confirmation",
"node_type": "static",
"static_message": "Payment confirmed! Thank you. Have a great day.",
"edges": []
},
{
"id": "payment_failed",
"prompt": "Payment failed: {error_reason}. Apologise briefly and offer to retry.",
"edges": []
}
]
```
### Backend code
```python theme={"system"}
import requests
def fire_event(run_id, event, properties=None):
requests.post(
f"https://api.bolna.ai/v1/call/{run_id}/events",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"event": event, "properties": properties or {}},
)
# Payment gateway webhook handler
fire_event(run_id, "payment_completed", {"ref": "TXN-98765"})
```
The `confirmation` node is static, so the user hears the confirmation in \~50ms with no LLM call. The `payment_failed` node uses `{error_reason}` from the event's `properties` to give the user a specific message.
Add more event edges (`details_verified`, `payment_initiated`, etc.) to walk the user through a longer flow. The pattern stays the same: one edge per event name, one HTTP call per step.
***
## Notes on timing
* Events never interrupt active speech. They are queued until the agent is at a safe point (no audio playing, no response in flight) and processed then.
* If the user is mid-utterance when the event lands, the node transitions but the agent does not speak proactively. The user's utterance routes on the new node, so the agent's first words still feel responsive.
* The `run_id` is all you need. The same endpoint works regardless of where the call is running.
# Full Example
Source: https://www.bolna.ai/docs/graph-agent/full-example
Complete annotated graph agent config showing every feature: nodes, edges, expression routing, static nodes, event injection, and call transfer.
This is the complete shape of a graph agent. It demonstrates every feature documented in the rest of this section. Replace `PLACEHOLDER` values with real config before deploying.
The flow:
* `welcome`: greets the customer. Transfers during working hours, ends the call after-hours, or jumps straight to `payment_confirmed` if a payment event arrives.
* `collect_order`: collects an order id with silence handling and a per-node knowledge base.
* `payment_confirmed`: static confirmation message played from cache.
* `transfer_call`: routes the call to a human agent via the transfer tool.
* `closing`: static goodbye.
```json theme={"system"}
{
"agent_config": {
"agent_name": "Demo Graph Agent",
"agent_type": "other",
"agent_welcome_message": "Hello, my name is Neha.",
"tasks": [
{
"task_type": "conversation",
"toolchain": {
"execution": "parallel",
"pipelines": [["transcriber", "llm", "synthesizer"]]
},
"task_config": {
"optimize_latency": true,
"call_terminate": 600,
"hangup_after_LLMCall": true
},
"tools_config": {
"input": { "format": "wav", "provider": "plivo" },
"output": { "format": "wav", "provider": "plivo" },
"api_tools": {
"tools": [
{
"key": "transfer_call",
"name": "transfer_call_main",
"parameters": {
"type": "object",
"required": ["call_sid"],
"properties": {
"call_sid": { "type": "string", "description": "unique call id" }
}
},
"description": "Transfer call to human agent.",
"pre_call_message": "Please hold while I transfer your call..."
}
],
"tools_params": {
"transfer_call_main": {
"url": null,
"param": {
"call_sid": "%(call_sid)s",
"call_transfer_number": "+91XXXXXXXXXX"
},
"method": "POST",
"headers": {},
"scope": "node",
"nodes": ["transfer_call"]
}
}
},
"llm_agent": {
"agent_type": "graph_agent",
"agent_flow_type": "streaming",
"llm_config": {
"model": "gpt-4.1-mini",
"max_tokens": 200,
"temperature": 0.2,
"provider": "openai",
"routing_model": "gpt-4.1-mini",
"routing_max_tokens": 250,
"routing_instructions": "PLACEHOLDER: routing instructions",
"agent_information": "PLACEHOLDER: global agent prompt (persona, language, guardrails)",
"current_node_id": "welcome",
"variable_types": {
"recipient_data.current_hour": "number"
},
"nodes": [
{
"id": "welcome",
"prompt": "Greet the customer and identify their intent.",
"edges": [
{
"to_node_id": "collect_order",
"condition": "Customer wants order status",
"parameters": { "order_id": "string" }
},
{
"to_node_id": "transfer_call",
"condition": "Customer asks for a human",
"condition_type": "expression",
"expression": {
"logic": "and",
"conditions": [
{ "variable": "recipient_data.current_hour", "operator": "gte", "value": 10 },
{ "variable": "recipient_data.current_hour", "operator": "lt", "value": 18 }
]
}
},
{
"to_node_id": "closing",
"condition": "Outside working hours",
"condition_type": "expression",
"priority": 1,
"expression": {
"logic": "or",
"conditions": [
{ "variable": "recipient_data.current_hour", "operator": "lt", "value": 10 },
{ "variable": "recipient_data.current_hour", "operator": "gte", "value": 18 }
]
}
},
{
"to_node_id": "payment_confirmed",
"condition_type": "event",
"event_name": "payment_completed"
}
]
},
{
"id": "collect_order",
"prompt": "Confirm the order id and look up its status using @fetch_order_status.",
"repeat_after_silence_seconds": 10,
"rag_config": {
"vector_store": {
"provider_config": { "vector_id": "PLACEHOLDER_collection_id" }
},
"similarity_top_k": 8
},
"edges": [
{ "to_node_id": "closing", "condition": "Status delivered to customer" },
{
"to_node_id": "transfer_call",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "_silence_repeats", "operator": "gte", "value": 3 }
]
}
}
]
},
{
"id": "payment_confirmed",
"node_type": "static",
"static_message": "Your payment is confirmed. Thank you!",
"edges": [
{ "to_node_id": "closing", "condition_type": "unconditional" }
]
},
{
"id": "transfer_call",
"prompt": "Transfer the call to a human agent.",
"function_call": "transfer_call_main",
"edges": []
},
{
"id": "closing",
"node_type": "static",
"static_message": "Thank you for calling. Have a wonderful day. Goodbye!",
"edges": []
}
]
}
},
"transcriber": {
"model": "nova-3",
"language": "multi-hi",
"provider": "deepgram",
"stream": true,
"encoding": "linear16",
"sampling_rate": 16000,
"endpointing": 700
},
"synthesizer": {
"provider": "elevenlabs",
"stream": true,
"caching": true,
"buffer_size": 220,
"audio_format": "wav",
"provider_config": {
"model": "eleven_turbo_v2_5",
"voice": "PLACEHOLDER: voice name",
"voice_id": "PLACEHOLDER: voice ID",
"temperature": 0.2,
"similarity_boost": 0.6,
"speed": 0.9
}
}
}
}
]
}
}
```
For automatic post-call extraction (disposition, sentiment, funnel stage), add an `extraction` task alongside the conversation task. See [Using extractions](/docs/guides/prompting/using-extractions).
## What this example shows
| Feature | Where |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Mixed edge types on one node | `welcome` has LLM, expression, and event edges. |
| Inline data extraction via `parameters` | `welcome -> collect_order` captures `order_id`. |
| Working-hours routing | `welcome -> transfer_call` (expression). |
| After-hours fallback | `welcome -> closing` (expression, priority 1). |
| Event-driven proactive speech | `welcome -> payment_confirmed` on `payment_completed`. |
| Typed expression variables | `variable_types` types `recipient_data.current_hour` as a number. |
| Per-node RAG | `collect_order` has `rag_config`. |
| Silence handling and escalation | `collect_order` has `repeat_after_silence_seconds: 10` and an expression edge on `_silence_repeats`. |
| Static node | `payment_confirmed`, `closing`. |
| Call transfer | `transfer_call` with `function_call`. |
| Node-scoped tool | `transfer_call_main` is scoped to the `transfer_call` node via `scope` and `nodes`. |
# Import & Export
Source: https://www.bolna.ai/docs/graph-agent/import-export
Export your graph agent as JSON for backup or sharing, and import JSON to replace the current graph.
The editor can export any agent to a JSON file and import a JSON file to replace an agent's current graph. Use this to back up agents, share them with teammates, migrate agents between environments, or create templates.
***
## Exporting an agent
1. Click **Export** in the toolbar.
2. The export dialog opens with the agent JSON in a read-only text area.
3. Click **Copy JSON** to copy the JSON to your clipboard, or **Download .json** to save it as a `.json` file.
The downloaded file is named after the agent (e.g. `my-graph-agent.json`).
Export before making large structural changes. If you need to roll back, you can re-import the exported file. For automatic snapshots, use [Version history](/docs/graph-agent/version-history) instead.
***
## Importing an agent
Importing replaces the **entire current graph** with the imported JSON. The current graph is discarded. Export or save a version before importing if you want to keep the current state.
1. Click **Import** in the toolbar.
2. The import dialog opens with two options:
**Paste JSON:**
Click the **Paste JSON** tab, paste your agent JSON into the text area, and click **Import**.
**Upload a file:**
Click the **Upload file** tab, drag a `.json` file onto the dropzone or click to browse, and click **Import**.
3. The editor validates the JSON format. If it's valid, the canvas reloads with the imported graph. If not, an error message describes the problem.
***
## What's included in the export
The exported JSON is the complete agent payload — the same structure you'd send to the [Agents API](/docs/api-reference/agent/create). It includes:
* Agent name and configuration
* All nodes and their prompts, settings, and overrides
* All transitions with conditions and expressions
* Conversation settings (hangup, backchanneling, etc.)
* LLM, STT, and TTS configuration
* API tools configuration
* Input and output schemas
Variable values set in the Variables panel are **not** included in the export. They are local to your browser session.
***
## Use cases
**Backup before a risky change**
Export → make changes → if something breaks, import the backup.
**Share with a teammate**
Export → send the JSON file → teammate imports into their agent.
**Move between environments**
Export from staging → import into production (update environment-specific URLs in API tools first).
**Create a template library**
Build a well-designed graph for a use case, export it, store it in your team's shared drive. Anyone who needs a similar agent imports the template and customises it.
# Graph Agents
Source: https://www.bolna.ai/docs/graph-agent/introduction
Build structured, multi-step voice AI conversations using a node-based graph instead of one large prompt.
A graph agent breaks a phone conversation into discrete **nodes**, each with its own purpose, instructions, and transition rules. Instead of one giant prompt that has to handle everything, you define exactly what the agent does at each step and exactly when it moves to the next one.
Conversations follow explicit paths. Every transition is a rule you defined.
When something breaks, you know which node failed and why.
Change one node without touching the rest of the flow.
Deterministic edges and static nodes skip the LLM entirely.
## When to use a graph agent
Pick a graph agent when the call has discrete stages with different objectives (greet, qualify, collect, confirm, close), or when you need deterministic transitions (time of day, retry count, external events). For a single-objective agent that just answers questions, a regular `simple_llm_agent` is enough.
***
## Core concepts
### Nodes
A node is one step in the conversation. Each node has one clear job.
| Field | Type | Description |
| ------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `id` | string | Unique identifier. Referenced by edges and `current_node_id`. |
| `prompt` | string | Instruction given to the response LLM when the conversation is in this node. |
| `edges` | array | Possible transitions out of this node. |
| `examples` | object | Sample responses per language (`"en"`, `"hi"`). Guides tone and phrasing. |
| `node_type` | string | `"llm"` (default), `"static"`, or `"router"`. See [Static Nodes](/docs/graph-agent/static-nodes) and [Router Nodes](/docs/graph-agent/router-nodes). |
| `static_message` | string | Required when `node_type == "static"`. Pre-cached audio plays at runtime. |
| `description` | string | Optional. On a `"router"` node, used as the routing objective (a router has no `prompt`). |
| `repeat_after_silence_seconds` | number | Auto-replay the node after N seconds of user silence. Works on LLM and static nodes. |
| `function_call` | string | Forces the response LLM's `tool_choice` to this tool when the node is entered (e.g. transfer nodes). |
| `rag_config` | object | Optional per-node knowledge base. See [Tools & RAG](/docs/graph-agent/tools-and-rag). |
### Edges
Edges define how the conversation moves from one node to the next.
```json theme={"system"}
{
"to_node_id": "order_status",
"condition": "Customer provides a valid order number"
}
```
If no edge matches, the agent stays on the current node and re-asks naturally. There are four edge types: LLM (default), expression, unconditional, and event. Full reference on [Edges & Routing](/docs/graph-agent/edges-and-routing).
### Routing
After every customer message, a routing LLM evaluates the available LLM-typed edges on the current node and picks the best match.
Expression and unconditional edges are evaluated **before** the routing LLM runs. If a deterministic rule matches, the transition fires instantly with zero latency and zero cost. The routing LLM is only invoked when no deterministic rule matches.
***
## Where graph agent config lives
All graph-agent fields live inside `llm_agent`, nested under `tools_config` in your conversation task:
```
agent_config
└── tasks[]
└── tools_config
└── llm_agent ← graph agent config goes here
├── agent_type: "graph_agent"
├── agent_information
├── routing_instructions
├── current_node_id
└── nodes[]
```
### Top-level fields
| Field | Description |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent_type` | Must be `"graph_agent"` to enable the node-based flow. |
| `agent_information` | Global system prompt. Persona, language rules, guardrails. Applied to every node. |
| `routing_instructions` | Prompt given to the routing LLM. Prepended to every routing request. Supports `{variable}` substitution from `context_data`. |
| `current_node_id` | Starting node when a new call begins. |
| `nodes` | Array of all node objects. |
| `rag_config` | Optional global knowledge base. Nodes without their own `rag_config` fall back to this. See [Tools & RAG](/docs/graph-agent/tools-and-rag). |
| `variable_types` | Optional map of `{variable: type}` that types values used in expression edges (`"string"`, `"number"`, `"boolean"`). See [Edges & Routing](/docs/graph-agent/edges-and-routing#typed-variables). |
| `model` | Response LLM. Defaults to `gpt-4.1-mini`. |
| `routing_provider` | Provider for the routing LLM. Defaults to `groq` when a Groq key is configured, otherwise `openai`. |
| `routing_model` | Routing LLM. Defaults to `gpt-4.1-mini` on OpenAI and Azure, `llama-3.3-70b-versatile` on Groq. |
| `routing_max_tokens` | Cap on routing response tokens. Defaults: 250 (non-GPT-5), 150 (GPT-5). |
| `routing_reasoning_effort` | GPT-5 routing models only. Accepted values differ per model — see the [per-model table](/docs/providers/llm-model/openai#reasoning-effort). Omit it to get the lowest-latency effort the routing model supports. |
The response LLM takes the same `llm_config` fields as a simple agent, so a graph agent on a GPT-5 model must also send `"temperature": 1` and follow the same `reasoning_effort` rules. See [OpenAI](/docs/providers/llm-model/openai).
`minimal` is not a universal value. It is accepted only on `gpt-5`, `gpt-5-mini` and `gpt-5-nano`; on `gpt-5.1` and later the equivalent is `none`, and sending `minimal` is rejected.
### `agent_information` is the identity layer
This prompt is applied to every node. Use it for persona, response rules (max sentence count, language switching), pronunciation rules, and hard guardrails.
`agent_information` is sent with every LLM call. Keep it focused. Save specifics for individual node prompts.
***
## Writing effective node prompts
A well-written `prompt` includes the node's purpose, the exact question to ask, validation rules, a fallback, and any voice formatting rules.
**Weak:**
```
Get the order number from the customer.
```
**Strong:**
```
Collect the customer's 10-digit order number.
ASK: 'Can you please share your 10-digit order number?'
VALIDATION:
- Accept only numeric input, exactly 10 digits.
- Expand spoken phrases: 'double four' becomes 'four four'.
- If the customer gives fewer or more digits, ask once more politely.
- After 2 failed attempts, offer to transfer to a live agent.
FORMAT: Confirm the number in groups of 3-3-4 with a short pause between groups.
Spell each digit as a word. Never use numerals in speech.
```
**One node, one job.** A node that collects an order number should only collect the order number. Don't also ask for the customer's name or call reason in the same node.
***
## Next steps
Edge types, expression operators, built-in variables, inline data extraction.
Pre-cached audio messages with auto-replay on user silence.
Silent dispatch nodes that route to the right node in one turn without speaking.
Drive transitions and proactive speech from external events via REST.
Call transfer, custom API tools, per-node knowledge bases.
Routing logs, common scenarios, and how to fix them.
Complete annotated JSON skeleton showing every feature end-to-end.
# Managing Nodes
Source: https://www.bolna.ai/docs/graph-agent/managing-nodes
Create, configure, duplicate, and delete nodes in the graph agent editor.
A node is one step in your conversation. The editor gives each node a card on the canvas with a role badge, a preview of its prompt, and the number of transitions leaving it.
***
## Node types
Every node has a **node type** that controls how it responds.
| Type | What it does |
| ---------- | ------------------------------------------------------------------------------------------------------------------------ |
| **LLM** | Sends the node's prompt and conversation history to the response LLM. The LLM generates a reply. |
| **Static** | Plays a pre-cached audio clip — no LLM call, no TTS call, \~50ms latency. See [Static nodes](/docs/graph-agent/static-nodes). |
***
## Node roles
The editor assigns each node a role based on its position and configuration. Roles are shown as a badge on the node card.
| Badge | Colour | When assigned |
| ---------------- | ------ | ------------------------------------------------------------ |
| **Start** | Purple | This node is the entry point — the first node on a new call. |
| **Closing** | Red | This node has no outgoing transitions. The call ends here. |
| **Function** | Green | LLM node with a forced `function_call` set. |
| **Static Audio** | Amber | `node_type` is `"static"`. |
| **LLM** | Blue | Standard LLM node with no special configuration. |
A node can only have one role. Precedence: Start > Closing > Function > Static > LLM.
***
## Creating a node
**Method 1 — double-click the canvas**
Double-click any empty area of the canvas. A dialog opens asking for the node type (**LLM Node** or **Static Audio Node**). Confirm to place the node at your click position.
**Method 2 — drag from a transition handle**
Click an existing node to reveal its output handle (the small circle on its bottom edge). Drag from the handle to an empty area. A new node is created and a transition from the source node is added automatically.
**Method 3 — insert on an existing transition**
Click a transition arrow to select it. In the edge inspector, click **Insert Node** and choose a node type. The new node is inserted between the source and target, with two transitions replacing the original one.
***
## Editing a node
Click any node card to select it. The **Node Inspector** opens on the right.
### Node ID
The node's unique identifier. Referenced by transitions and the start-node setting. Click the ID field to rename it.
Renaming a node updates all transitions that point to it automatically. If two nodes would end up with the same ID, a numeric suffix is added (e.g. `node_1`).
### Set as start node
Click **Make start node** to make this node the entry point for new calls. The button shows **Current start node** when this node is already the start. Only one node can be the start node at a time. The current start node shows the purple **Start** badge.
### Node type toggle
Switch between **LLM** and **Static** at the top of the node inspector. Switching to Static reveals the **Spoken message** field and hides the LLM-only fields.
### Prompt (LLM nodes)
The instruction given to the response LLM when the conversation is in this node. Write exactly what the agent should do and say at this step.
```
Collect the customer's 10-digit order number.
ASK: 'Can you please share your 10-digit order number?'
VALIDATION:
- Accept only numeric input, exactly 10 digits.
- If the customer gives fewer or more digits, ask once more.
- After 2 failed attempts, offer to transfer to a human agent.
```
### Spoken message (Static nodes)
The exact text to speak. Audio is pre-generated from this text using the agent's configured TTS voice when the agent is saved. Changing this field requires a re-save to regenerate the cache.
### Examples
Optional per-language example responses. Guides tone and phrasing without restricting the LLM. Add entries for each language code your agent supports (e.g. `en`, `hi`).
### Function call (LLM nodes)
Forces the response LLM's `tool_choice` to the selected tool when the node is entered. Use this on transfer nodes so the LLM always calls the transfer function without waiting for the user to ask.
### Knowledge base (LLM nodes)
Attach one or more knowledge bases to this node. On every turn while the conversation is on this node, the user's message is used to retrieve relevant chunks from the selected knowledge base and inject them into the LLM's context. See [Tools & RAG](/docs/graph-agent/tools-and-rag).
### LLM overrides (LLM nodes)
Override the agent-level LLM settings for just this node.
| Field | What it overrides |
| ---------------- | ----------------------------------------------------------------------------------- |
| Reasoning effort | For supported models. The control offers only the values the selected model accepts |
| Model & provider | LLM provider and specific model name |
| Temperature | Response creativity (0.0–2.0). GPT-5 models accept only `1` |
| Max tokens | Cap on response length. On GPT-5 models this budget is shared with reasoning tokens |
### Auto-replay on silence
When enabled, the node replays automatically after a configurable number of seconds of user silence. The `_silence_repeats` counter increments on each replay and can be used in expression transitions to escalate (transfer, hang up). See [Static nodes](/docs/graph-agent/static-nodes) for a full example with the expression pattern.
***
## Duplicating a node
Open the node inspector and click **Duplicate** at the top of the inspector. A copy of the node is placed on the canvas with all the same settings. The copy gets a new unique ID (original ID + `_copy` suffix or a numeric suffix).
***
## Deleting a node
Open the node inspector and click **Delete** at the top of the inspector. Deleting a node also removes all transitions that point **to** that node. Transitions that **leave** the node (its outgoing edges) are removed too.
Node deletion cannot be undone via Cmd+Z. Confirm before deleting.
***
## Transitions list
The **Transitions** section in the node inspector lists every outgoing transition from that node. It appears below the Prompt and Examples fields. Each row shows the target node and the transition type. Click a row to select the transition and open the edge inspector.
To add a new transition from the node inspector, click **Transition** at the top of the inspector.
# Managing Transitions
Source: https://www.bolna.ai/docs/graph-agent/managing-transitions
Create, configure, and delete transitions between nodes using the intent, rule, and always trigger types.
A transition (edge) connects two nodes and tells the agent when to move from one to the other. The editor supports three trigger types: **Intent** (LLM-evaluated), **Rule** (deterministic expression), and **Always** (unconditional).
***
## Creating a transition
**Method 1 — drag from a node handle**
Click a node to reveal its output handle (the circle on its bottom edge). Drag from the handle onto another node. The **Create transition** form opens.
**Method 2 — from the node inspector**
Open the node inspector for a source node. Click **Transition** at the top of the inspector. The **Create transition** form opens.
### Create transition form
| Field | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------- |
| **Transition to** | The node to transition to. Select from a dropdown of all nodes. |
| **Trigger** | **Intent**, **Rule**, or **Always**. |
| **When the user says something like…** | Visible for **Intent** only. Free-text description of when to take this transition. |
***
## Trigger types
### Intent (LLM-evaluated)
The routing LLM reads the condition text and decides whether the customer's last message matches it.
```
Customer provides a valid order number
```
The condition text becomes the tool description passed to the routing LLM. Write it as a factual statement about what should have happened, not as an instruction.
Make conditions specific and mutually exclusive. "Customer is interested" is ambiguous; "Customer confirms they want to proceed with purchase" is not.
### Rule (expression)
A rule-based check on context variables. Fires instantly before the routing LLM runs — zero latency, zero LLM cost.
The expression builder in the edge inspector has:
* **Logic**: `AND` (all conditions must be true) or `OR` (any one is enough)
* **Conditions**: one or more rows, each with a **variable**, **operator**, and **value**
| Operator | Use case |
| --------------------------- | ------------------------------------ |
| `eq` / `neq` | Exact match or not-match |
| `gt` / `gte` / `lt` / `lte` | Numeric comparisons |
| `contains` | String contains substring |
| `in` / `not_in` | Value is (or is not) in a list |
| `exists` / `not_exists` | Variable has a value (or is missing) |
**Built-in variables** available in every expression (populated automatically per call):
| Variable | Type | Notes |
| -------------------------------- | ---------- | ------------------------------------------------------- |
| `recipient_data.current_hour` | int (0–23) | Hour in the call's timezone |
| `recipient_data.current_minute` | int (0–59) | |
| `recipient_data.current_weekday` | string | Lowercase, e.g. `"wednesday"` |
| `recipient_data.current_day` | int (1–31) | |
| `recipient_data.current_month` | int (1–12) | |
| `recipient_data.current_year` | int | |
| `recipient_data.current_date` | string | Full date string, e.g. `"2026-06-23"` |
| `recipient_data.current_time` | string | Time string in the call's timezone |
| `recipient_data.timezone` | string | e.g. `"Asia/Kolkata"` |
| `recipient_data.user_number` | string | E.164 phone number |
| `detected_language` | string | e.g. `"hindi"`, `"en"` |
| `_node_turns` | int | User messages on the current node; resets on transition |
| `_total_turns` | int | User messages in the entire call |
You can also reference any variable captured via transition parameters (see [Inline data extraction](/docs/graph-agent/edges-and-routing#inline-data-extraction)) or passed in `recipient_data` when the call was created.
**Example — route to transfer after 2 failed attempts on a node:**
Set `_node_turns` `gte` `2`.
**Example — route to after-hours node outside 10 AM–6 PM:**
Logic: `OR`
* `recipient_data.current_hour` `lt` `10`
* `recipient_data.current_hour` `gte` `18`
### Always (unconditional)
Takes this transition on every routing evaluation, regardless of what the user said. Use when a node has exactly one possible next step.
An **Always** transition fires before the routing LLM runs. If a node has both an Intent transition and an Always transition, the Always transition fires first and the Intent transition never evaluates. To prevent this, give the Always transition a higher priority number (e.g. `101`) so the Intent transitions are evaluated first.
### Event
A fourth trigger type — **Event** — fires only when a matching external event arrives via the Bolna REST API, not during speech routing. It is used for payment webhooks, form submissions, and other external signals. See [Event injection](/docs/graph-agent/event-injection) for the full reference.
***
## Edge inspector
Click any transition arrow on the canvas to open the edge inspector.
### Fields
| Field | Description |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **From** | Read-only. The source node for this transition. |
| **To** | Select dropdown. Change which node this transition leads to. |
| **Condition type** | Select between **LLM (default)**, **Expression**, or **Unconditional**. |
| **Condition** | (LLM only) The routing LLM's tool description. |
| **Expression builder** | (Expression only) Logic selector (AND/OR) + condition rows. |
| **Label (optional)** | Short label displayed on the arrow in the canvas. |
| **Priority** | Lower number fires first. Default: 0 for Expression/Unconditional, 100 for LLM. |
| **Routing tool name override** | Optional: override the auto-generated routing tool name (default: `transition_to_`). Found under **Advanced (optional)**. |
| **Routing tool description override** | Optional: override the auto-generated routing tool description shown to the routing LLM. Found under **Advanced (optional)**. |
### Priority
When a node has multiple deterministic transitions (Rule or Always), they are evaluated in ascending priority order. The first one that matches fires. Use distinct priorities to make evaluation order explicit — e.g. priority `0` for the retry escalation check, priority `1` for the after-hours check.
### Parameters (inline data extraction)
Intent transitions can capture typed values from the user's reply during routing. Add a parameter name and type (e.g. `order_id: string`). After the transition fires, the value is available as `{order_id}` in node prompts and as a variable in expression rules. To add parameters, expand the **Advanced (optional)** accordion in the edge inspector and use the **Extract parameters** section — see [Inline data extraction](/docs/graph-agent/edges-and-routing#inline-data-extraction).
***
## Deleting a transition
**From the canvas:** Click the transition arrow to select it, then click the **Delete** button in the edge inspector.
**From the node inspector:** In the **Transitions** list at the bottom of the node inspector, click the trash icon on the row for the transition you want to remove.
***
## Transition display on the canvas
The canvas draws a bezier curve for each transition with a label in the middle. When two nodes have multiple transitions between them (parallel edges), the curves are offset horizontally so they don't overlap. Each curve shows the condition text (or "Always" for unconditional edges) as a label.
# Router Nodes
Source: https://www.bolna.ai/docs/graph-agent/router-nodes
Silent dispatch nodes that route the caller to the right node in one turn, without speaking.
Some nodes in a flow only exist to decide where to go next: send VIP callers to a different greeting, classify a request into billing / support / sales, or branch on time of day before the conversation starts. A router node does exactly that and nothing else. It never speaks. On entry it evaluates its edges and transitions again, within the same turn, until it lands on a node that does speak.
This keeps routing logic in its own place in the graph instead of hiding it inside a conversational node's edges, and it lets you build a silent classifier or a pre-conversation dispatcher.
Router nodes are configured through the agent JSON / API today. Visual editor support is coming.
## How a router node picks an edge
On entry, a router evaluates its edges in three phases and takes the first that resolves:
| Order | Edge type | Cost |
| ----- | ------------------------------------------ | ------------------------------------------------ |
| 1 | **Expression** edges, in `priority` order | Instant, no LLM call |
| 2 | **Intent** edges, via one routing-LLM call | One routing call (same as normal intent routing) |
| 3 | The **unconditional** catch-all | Instant fallback |
Two things to keep in mind:
* **The catch-all is always a fallback.** Unlike a normal node, an unconditional edge on a router never pre-empts a matching expression edge, regardless of its `priority`. It is taken only when nothing else matches (including when the intent call finds no match).
* **At most one routing-LLM call per turn.** Every hop still checks its expression edges first; only the intent (LLM) call is capped. So if a router chains into another router that would also need an intent call, the second one takes its catch-all instead. A purely deterministic chain (expression + unconditional only) resolves in \~0ms with no LLM call at all.
A router always advances to a speaking node in the same turn, so a caller never hears dead air waiting on it.
`priority` orders edges **within a phase** (expression edges among themselves, intent edges among themselves). It cannot make an intent edge outrank an expression edge — expression edges are always checked first. If you want an intent decision to win a case, don't also give the router an expression edge that matches that case.
## Configuring a router node
A router node is one entry in your agent's `nodes` array — the same array that holds every other node, under `llm_agent.llm_config`. See [Full example](/docs/graph-agent/full-example) for a complete agent payload, and [Edges & routing](/docs/graph-agent/edges-and-routing) for the expression syntax, operators, and built-in variables (like `_total_turns`) used below.
Set `node_type` to `"router"`, leave the prompt empty, and give it edges plus an unconditional catch-all:
```json theme={"system"}
{
"id": "entry_dispatch",
"node_type": "router",
"description": "Send VIP callers to the VIP greeting, everyone else to the standard greeting.",
"edges": [
{
"to_node_id": "vip_greeting",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "recipient_data.customer_tier", "operator": "eq", "value": "vip" }
]
}
},
{ "to_node_id": "greeting", "condition_type": "unconditional" }
]
}
```
### Field reference
| Field | Type | Required | What it does |
| ------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| `node_type` | `"router"` | Yes | Marks the node as a silent dispatcher. |
| `edges` | array | Yes | Expression, intent, and unconditional edges. Must include an unconditional catch-all. Event edges are not allowed. |
| `description` | string | No | The classification objective shown to the routing LLM when the router has intent edges (a router has no `prompt`). |
A router node must **not** set `prompt` or `static_message` — it never speaks. On expression and unconditional edges, the `condition` string is just a human-readable label; only `expression` (for expression edges) and `condition` text on intent edges affect routing.
## Intent routing on a router
An **intent edge** is an edge with a `condition` and no `condition_type` (the default edge type — see [Edges & routing](/docs/graph-agent/edges-and-routing)). A router can use intent edges to classify what the caller wants and dispatch silently. Because a router has no prompt, the routing LLM is guided by three things:
* Each intent edge's `condition` (and optional `function_description`) — the primary signal.
* The router's `description` — its overall objective.
* The agent-level `routing_instructions`, if set.
Do not put conversational instructions on a router. It never speaks and can only pick a transition, so prompt-like text there does nothing.
## Example: silent NLU dispatcher
Classify the caller's request and route to the right department. The escalation guard runs first (instant, no LLM), then the intent call, then the catch-all when the request is unclear.
```json theme={"system"}
{
"id": "topic_router",
"node_type": "router",
"description": "Route the caller to billing, technical support, or sales.",
"edges": [
{
"to_node_id": "human_handoff",
"condition": "Conversation too long, escalate",
"condition_type": "expression",
"priority": 0,
"expression": {
"conditions": [
{ "variable": "_total_turns", "operator": "gte", "value": 12 }
]
}
},
{
"to_node_id": "billing",
"condition": "The user asks about payments, invoices, or charges.",
"parameters": { "billing_issue": "string" }
},
{
"to_node_id": "tech_support",
"condition": "The user reports a technical problem with their service."
},
{
"to_node_id": "sales",
"condition": "The user wants a new connection or a plan upgrade."
},
{ "to_node_id": "clarify", "condition_type": "unconditional" }
]
}
```
What happens on a turn:
* If `_total_turns >= 12`, the expression matches first and routes to `human_handoff` with no LLM call.
* Otherwise one routing call classifies the reply into `billing`, `tech_support`, or `sales`. Intent edges can still extract `parameters` into context, exactly like normal intent routing.
* If the request is unclear, the catch-all routes to `clarify`, which asks the caller to say what they need.
## Example: pre-conversation dispatch
A router can be the start node. On the first turn it resolves before any conversational node runs, so the caller begins on the right node. Pre-conversation routing is deterministic (there is no reply to classify yet), so use expression and unconditional edges here.
```json theme={"system"}
{
"current_node_id": "entry_dispatch",
"nodes": [
{
"id": "entry_dispatch",
"node_type": "router",
"edges": [
{
"to_node_id": "hindi_greeting",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "recipient_data.language", "operator": "eq", "value": "hi" }
]
}
},
{ "to_node_id": "greeting", "condition_type": "unconditional" }
]
},
{ "id": "hindi_greeting", "prompt": "Greet the caller warmly in Hindi and ask how you can help.", "edges": [] },
{ "id": "greeting", "prompt": "Greet the caller warmly and ask how you can help.", "edges": [] }
]
}
```
Both target nodes are included so this validates and runs as-is — a router's edges must point to nodes that exist.
A router keys on call-time data. Pass it as `user_data` when you [start the call](/docs/api-reference/calls/make) — e.g. `{ "user_data": { "customer_tier": "vip", "language": "hi" } }` — and reference it in expressions as `recipient_data.customer_tier`, `recipient_data.language`, and so on. A value set in the agent's `context_data` acts only as a default; on a real call the call-time `user_data` is what's used.
## Validation
A router node config is checked when the agent is saved. It is rejected if:
* It sets a `prompt` or `static_message` (a router never speaks).
* It has no unconditional catch-all edge (a router must always be able to advance).
* Any edge is an event edge (a call never rests on a router, so events would never fire).
* An edge points to a node ID that doesn't exist.
* Routers form a cycle among themselves with no way out to a speaking node.
## When to use a router node
* **Silent NLU dispatcher** — classify a request once and route to the right sub-flow, without a node that speaks.
* **Pre-conversation dispatch** — pick the starting node from caller data before the first turn.
* **Nested deterministic branching** — keep complex rule-based routing in one place instead of copying edges across conversational nodes.
If a routing decision needs the node to also say something, use a normal LLM node with intent edges instead — routing already happens before that node speaks.
# Static Nodes & Silence Repeat
Source: https://www.bolna.ai/docs/graph-agent/static-nodes
Pre-cached audio messages that play in 50ms with zero LLM cost, plus auto-replay on user silence with deterministic escalation.
Many nodes in a flow always say the same thing: greetings, hold messages, confirmations, goodbyes. A static node pre-renders the audio for that message when the agent is saved and plays it back from cache at runtime. No LLM call. No TTS call. No latency.
`repeat_after_silence_seconds` is a related setting that auto-replays a node after N seconds of user silence and exposes a `_silence_repeats` counter so expression edges can escalate after a few silent rounds (offer help, transfer, hang up).
## Latency and cost
| Node type | Latency | Cost per turn |
| ----------- | --------------------------- | --------------------------- |
| LLM node | \~800ms (LLM + TTS + audio) | LLM tokens + TTS characters |
| Static node | \~50ms (cached audio) | Zero |
***
## Configuring a static node
Set `node_type` to `"static"` and provide `static_message`:
```json theme={"system"}
{
"id": "greeting",
"node_type": "static",
"static_message": "Hello! Thank you for calling Acme. How can I help you today?",
"edges": [
{ "to_node_id": "main_menu", "condition": "User responds with a request" }
]
}
```
That's it. The audio is pre-generated using the agent's configured TTS voice when the agent is saved, then served from cache on every call.
### Field reference
| Field | Type | Required | What it does |
| ------------------------------ | -------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `node_type` | `"llm"` or `"static"` | No (defaults to `"llm"`) | Controls whether the node calls the LLM or plays cached audio. |
| `static_message` | string or per-language map | Yes when `node_type == "static"` | The exact text to speak. Accepts a single string, or a `{ "language_code": "text" }` map for multilingual agents (see [Multilingual static messages](#multilingual-static-messages)). Audio is pre-generated from this when the agent is saved. |
| `repeat_after_silence_seconds` | number | No | If set, replays the node's response after this many seconds of user silence. Works on **both** static and LLM nodes. In the editor, this is the **Auto-replay on silence** toggle in the node inspector. |
All three fields are optional with safe defaults. Existing graph agents that don't use any of them behave exactly as before.
***
## Multilingual static messages
For a multilingual agent, `static_message` can be a per-language map instead of a single string. At runtime the node speaks the variant that matches the caller's active language, and the platform pre-generates a separate cached clip for each language using that language's voice.
```json theme={"system"}
{
"id": "clinic_hours",
"node_type": "static",
"static_message": {
"en": "Our clinic is open Monday to Saturday, 9 AM to 8 PM.",
"hi": "हमारा क्लिनिक सोमवार से शनिवार, सुबह 9 से रात 8 बजे तक खुला रहता है।",
"ta": "எங்கள் மருத்துவமனை திங்கள் முதல் சனி வரை காலை 9 மணி முதல் இரவு 8 மணி வரை திறந்திருக்கும்."
},
"edges": [
{ "to_node_id": "main_menu", "condition_type": "unconditional" }
]
}
```
Use the same two-letter language codes as your agent's [multilingual configuration](/docs/customizations/multilingual-config-reference). When the caller's language switches mid-call ([auto-switch](/docs/customizations/auto-switch-multilingual-messages)), the next static node automatically plays the matching-language clip. This is the same `{ "language_code": "text" }` format used by system messages like `call_hangup_message` and `check_user_online_message`.
A plain-string `static_message` keeps working unchanged, so add a map only when you want per-language audio.
### How the multilingual audio is built
When you save the agent, the platform pre-generates one cached clip per language variant, each rendered with that language's configured voice. At call time the clip for the active language streams from cache with the same instant playback and zero cost as a single-language static node. If a language has no dedicated voice in your multilingual settings, its clip falls back to the agent's primary voice.
***
## Silence repeat
When `repeat_after_silence_seconds` is set and the user goes quiet:
1. The silence timer fires after the configured seconds.
2. `_silence_repeats` increments by 1.
3. Expression edges are evaluated. If one matches `_silence_repeats`, the agent transitions.
4. Otherwise the node replays. A static node plays the same cached audio (zero cost). An LLM node regenerates with `[silence]` in the conversation history and rephrases naturally.
5. `_silence_repeats` resets to `0` on any transition out of the node.
***
## Example: greeting with silence fallback
Play a greeting. If the user is silent, repeat up to 3 times, then hang up.
```json theme={"system"}
{
"id": "greeting",
"node_type": "static",
"static_message": "Hello! Thank you for calling. How can I help you today?",
"repeat_after_silence_seconds": 8,
"edges": [
{ "to_node_id": "main_menu", "condition": "User responds with a request" },
{
"to_node_id": "goodbye",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "_silence_repeats", "operator": "gte", "value": 3 }
]
}
}
]
}
```
What happens:
* Cached audio plays instantly.
* User silent for 8s, audio replays (`_silence_repeats = 1`).
* Still silent, replays (`_silence_repeats = 2`).
* Still silent, replays (`_silence_repeats = 3`), expression matches, transitions to `goodbye`.
***
## Example: LLM node with silence nudge
The same pattern works on LLM nodes. The LLM sees `[silence]` in conversation history and rephrases without any extra prompt engineering on your part.
```json theme={"system"}
{
"id": "collect_email",
"prompt": "Ask the user for their email address politely.",
"repeat_after_silence_seconds": 10,
"edges": [
{
"to_node_id": "confirm",
"condition": "User shared an email",
"parameters": { "email": "string" }
},
{
"to_node_id": "goodbye",
"condition_type": "expression",
"expression": {
"conditions": [
{ "variable": "_silence_repeats", "operator": "gte", "value": 3 }
]
}
}
]
}
```
The LLM might say "Could you share your email?" first, then "Sorry, I didn't catch that, could you tell me your email?" on the next silence, then transition to goodbye after the third.
***
## When the cache is built
Audio for every static node is generated when you save the agent, using the agent's configured TTS voice. At call time the cached audio is streamed directly, no LLM or TTS call.
If you change `static_message` later, re-save the agent so the cache regenerates with the new text.
# Testing Your Agent
Source: https://www.bolna.ai/docs/graph-agent/testing
Test your graph agent from inside the editor using chat simulation or a live call.
The editor has a built-in **Test agent** panel that lets you verify your agent's behaviour without leaving the builder. The panel shows two options: **Get call from agent** (real outbound call) and **Chat with agent** (text simulation, no phone needed).
***
## Opening the test panel
With nothing selected on the canvas, the inspector shows three tabs: **Agent setup**, **Tools**, and **Test agent**. Click **Test agent**.
***
## Chat mode
Chat mode simulates a conversation with your agent as a text exchange. This is the fastest way to verify routing logic, node transitions, and prompt behaviour.
**How to use:**
1. With nothing selected on the canvas, click the **Test agent** tab in the inspector.
2. Click **Chat with agent**.
3. Type a message and press Enter to send it.
4. The agent's response appears in the chat panel, along with which node is active.
Set variable values in the [Variables panel](/docs/graph-agent/variables) before starting a chat test. The test uses your variable values to substitute `{tokens}` in prompts and the welcome message.
Chat mode tests the text-level logic — prompts, routing, and transitions. It does not test TTS voice quality, STT transcription accuracy, or audio latency.
***
## Call mode
Call mode initiates a real outbound call using the agent's full configuration — TTS, STT, telephony, and all.
**How to use:**
1. With nothing selected on the canvas, click the **Test agent** tab in the inspector.
2. Click **Get call from agent**, enter the phone number in E.164 format (e.g. `+919876543210`), and confirm.
3. Answer the phone. The agent runs exactly as it would in production.
Call mode makes a real phone call and consumes telephony and LLM credits. Save the agent before starting a call test so the call uses your latest changes.
***
## What to check
Use the test panel to verify:
* The welcome message sounds right with your variable values filled in.
* Routing transitions fire correctly — the agent moves to the expected node when you say what each condition describes.
* Rule (expression) transitions based on turn counts, time of day, or other built-in variables fire at the right moment.
* Static nodes play the correct message.
* Function tools are invoked on the right node.
* Silence handling (Auto-replay on silence) behaves as expected.
# Tools & Knowledge Base
Source: https://www.bolna.ai/docs/graph-agent/tools-and-rag
Wire up call transfer, custom API tools, node-scoped tools, ending the call, and global or per-node knowledge bases inside a graph agent.
Graph agents support two kinds of tools (call transfer and custom HTTP) and an optional knowledge base (RAG). Tools are defined globally in `api_tools` and referenced by name in node prompts. A knowledge base can be set once for the whole agent, or per node when different steps need different sources.
***
## Call transfer
Define the transfer tool once in `api_tools.tools` and `api_tools.tools_params`:
```json theme={"system"}
{
"key": "transfer_call",
"name": "transfer_call_main",
"description": "Use when the customer requests a human agent.",
"pre_call_message": "Transferring you now, please hold..."
}
```
```json theme={"system"}
{
"tools_params": {
"transfer_call_main": {
"url": null,
"param": {
"call_sid": "%(call_sid)s",
"call_transfer_number": "+91XXXXXXXXXX"
},
"method": "POST"
}
}
}
```
On the transfer node, set `function_call` to force the response LLM to pick this tool when the node is entered:
```json theme={"system"}
{
"id": "transfer",
"prompt": "Transfer the call to a human agent.",
"function_call": "transfer_call_main",
"edges": []
}
```
`function_call` sets the response LLM's `tool_choice` to the named tool. The LLM still emits the call; the framework doesn't auto-invoke it.
***
## Custom API tools
Define a tool the LLM can call mid-conversation, e.g. to look up an order:
```json theme={"system"}
{
"key": "custom_task",
"name": "fetch_order_status",
"description": "Fetch order status using the customer's order ID.",
"parameters": {
"type": "object",
"properties": {
"order_id": { "type": "string", "description": "Customer order ID" }
}
},
"pre_call_message": "Just a moment, let me check that..."
}
```
```json theme={"system"}
{
"tools_params": {
"fetch_order_status": {
"url": "https://your-api.example.com/order/status",
"param": { "order_id": "%(order_id)s" },
"method": "POST",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
}
```
Reference the tool from a node prompt with the `@` prefix:
```
Call @fetch_order_status with the [order_id] collected earlier.
```
Only define tools you actually use. Every tool is visible to the LLM as a callable function, and unused tools increase the chance of accidental invocations.
***
## Limiting a tool to specific nodes
By default every tool is visible to the LLM on every node. To expose a tool only where it makes sense, add `scope: "node"` and a `nodes` list to its entry in `tools_params`:
```json theme={"system"}
{
"tools_params": {
"fetch_order_status": {
"url": "https://your-api.example.com/order/status",
"param": { "order_id": "%(order_id)s" },
"method": "POST",
"scope": "node",
"nodes": ["collect_order", "confirm_order"]
}
}
}
```
Now the LLM can only call `fetch_order_status` while the conversation is on `collect_order` or `confirm_order`. On every other node the tool is hidden, so it can't be triggered by accident. Tools with no `scope` (or `scope: "global"`) stay available everywhere.
Scope each tool to the nodes that need it. Fewer visible tools per node means fewer wrong tool calls and a cheaper, more focused LLM call.
***
## Ending the call
Graph agents can hang up using the built-in `end_call` tool. To let a node end the call, set `function_call: "end_call"` on that node and set `hangup_after_LLMCall: false` in the task config:
```json theme={"system"}
{
"id": "closing",
"prompt": "Thank the customer and end the call.",
"function_call": "end_call",
"edges": []
}
```
With `hangup_after_LLMCall: false`, the call only ends from the nodes that opt in with `function_call: "end_call"`. This gives you exact control over where a call is allowed to hang up. Leave `hangup_after_LLMCall: true` (the default) if you instead want the agent to decide when to end the call on its own.
***
## Knowledge base
Attach a knowledge base so the agent can answer from your documents. On each turn the latest user message retrieves the most relevant chunks, which are added to the prompt before the response is generated.
### Global knowledge base
Set `rag_config` at the top level of the graph config and every node uses it:
```json theme={"system"}
{
"agent_type": "graph_agent",
"agent_information": "...",
"current_node_id": "welcome",
"rag_config": {
"vector_store": {
"provider_config": { "vector_id": "policies_v1" }
},
"similarity_top_k": 10
},
"nodes": [ ... ]
}
```
### Per-node knowledge base
Set `rag_config` on a node to use a different source on that node. A node's own `rag_config` takes precedence; nodes without one fall back to the global `rag_config`.
```json theme={"system"}
{
"id": "policy_questions",
"prompt": "Answer the customer's policy question using the knowledge base.",
"rag_config": {
"vector_store": {
"provider_config": { "vector_id": "policies_v1" }
},
"similarity_top_k": 10
},
"edges": [
{ "to_node_id": "closing", "condition": "Customer is satisfied" }
]
}
```
### Multiple collections
Pass `vector_ids` instead of `vector_id` to search several collections at once:
```json theme={"system"}
"rag_config": {
"vector_store": {
"provider_config": { "vector_ids": ["policies_v1", "faqs_v2"] }
},
"similarity_top_k": 10
}
```
| Field | Description |
| ----------------------------------------- | ------------------------------------------------------- |
| `vector_store.provider_config.vector_id` | A single knowledge base collection id. |
| `vector_store.provider_config.vector_ids` | A list of collection ids to search together. |
| `similarity_top_k` | How many chunks to retrieve per turn. Defaults to `10`. |
If retrieval fails, the node still responds, just without retrieved context. The error is logged but never raised to the caller.
Use a global `rag_config` when the whole agent answers from one knowledge base. Add a per-node `rag_config` only where a step needs a different source. Every retrieval adds latency, so a node that needs no knowledge base shouldn't pay for one.
# Using the Graph Agent Editor
Source: https://www.bolna.ai/docs/graph-agent/using-the-editor
A tour of the visual editor: canvas, inspector, toolbar, and keyboard shortcuts.
The graph agent editor is the visual builder for creating and editing graph agents in the Bolna dashboard. It has three main areas: a **canvas** in the centre, an **inspector panel** on the right, and a **toolbar** at the top.
***
## Opening the editor
Navigate to **Agents** in the dashboard, then either:
* Click **New agent** and choose **Graph agent** to create a blank agent.
* Click an existing graph agent to open it for editing.
***
## Editor layout
### Canvas
The canvas is the central workspace where your graph lives. Each node appears as a card; each transition appears as a directed arrow between nodes.
| Action | How |
| ----------------------------- | --------------------------------------------------------------------------------------- |
| Pan | Click and drag on any empty area |
| Zoom | Scroll wheel, or pinch on trackpad |
| Select a node | Click the node card |
| Select a transition | Click the arrow |
| Deselect | Click on any empty area |
| Create a new node | Double-click on any empty area |
| Insert a node on a transition | Click a transition arrow to select it, then click **Insert Node** in the edge inspector |
The canvas remembers node positions between sessions for each agent.
### Inspector panel
The inspector opens on the right side of the canvas. Its contents change based on what is selected:
| Selection | Inspector shows |
| ---------------------- | ------------------------------------------------------------- |
| Nothing selected | Tabs: **Agent setup**, **Tools**, **Test agent** |
| A node | Node inspector — all node fields |
| A transition (arrow) | Edge inspector — condition, type, label, priority, parameters |
| Pending new transition | Create transition form |
Click the **✕** button at the top of the inspector to close it. To reopen the inspector, click the **Inspector** button (panel-right icon) in the top-right corner of the canvas.
### Toolbar
The toolbar runs along the top of the canvas and contains all editor-level actions.
| Button | What it does |
| ------------------- | -------------------------------------------------------------------------------------------------------- |
| **Add node** | Create a new node at the centre of the canvas. |
| **Import** | Open a JSON file or paste JSON to replace the current graph. |
| **Export** | Download the current agent as JSON, or copy to clipboard. |
| **Auto layout** | Automatically arrange all nodes using a hierarchy layout algorithm. |
| **Undo** | Undo the last change (Cmd/Ctrl+Z). |
| **Redo** | Redo an undone change (Shift+Cmd/Ctrl+Z or Ctrl+Y). |
| **Search nodes** | Filter nodes by name, prompt text, or tool name. Matching nodes are highlighted on the canvas. |
| **Variables** | Open the variables panel to set values for `{variable}` tokens. See [Variables](/docs/graph-agent/variables). |
| **Zoom out** | Zoom the canvas out. |
| **Zoom in** | Zoom the canvas in. |
| **Fit view** | Fit all nodes into the visible canvas area. |
| **Version history** | Open the version history sheet to view and restore past saves. |
| **Validate** | Run validation and open the issues dialog. Shows a badge with the error count if issues exist. |
| **Save** | Saves the agent. The save icon changes colour when there are unsaved changes. |
***
## Keyboard shortcuts
| Shortcut | Action |
| ---------------------- | -------------- |
| `Cmd/Ctrl + Z` | Undo |
| `Shift + Cmd/Ctrl + Z` | Redo |
| `Ctrl + Y` | Redo (Windows) |
Undo snapshots are coalesced — rapid successive edits (e.g. typing in a prompt field) are grouped into a single undo step, captured after \~800ms of inactivity.
***
## Next steps
Create, edit, duplicate, and delete nodes in the canvas.
Wire nodes together with intent, rule, and always-transition edges.
Configure welcome message, LLM, voice, and conversation settings.
Find and fix errors before saving.
# Validation
Source: https://www.bolna.ai/docs/graph-agent/validation
Run the validation checker to find errors before saving and warnings before deploying.
The editor validates your graph agent automatically before every save and on demand. Validation finds two categories of issues: **errors** that block saving and **warnings** that you can acknowledge and proceed.
***
## Running validation
Click **Validate** in the toolbar to open the validation dialog. The toolbar button shows a badge with the error count if any errors exist.
Validation also runs automatically when you click **Save**. If there are errors, the save is blocked and an error toast describes the issue. Click **Validate** in the toolbar to open the full validation dialog and see all issues.
***
## Errors (blocking)
Errors must be fixed before the agent can be saved.
| Error | What it means | How to fix |
| ---------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| **No nodes** | The graph is empty. | Add at least one node. |
| **Missing node ID** | A node has no ID. | Open the node inspector and set an ID. |
| **Duplicate node IDs** | Two or more nodes share the same ID. | Rename one so all IDs are unique. |
| **No start node** | No node is marked as the start node. | Select a node and click **Make start node**. |
| **Missing transition target** | A transition points to a node ID that doesn't exist. | Delete the transition or rename the target node to match. |
| **Unreachable tool** | A node references a `function_call` tool that isn't defined in the agent's tools config. | Add the tool in the **Tools** tab or remove the `function_call` reference. |
| **Bad transition parameters** | A transition's `parameters` field has invalid structure. | Edit the transition and fix the parameters JSON (must be `{name: type}` pairs). |
| **Invalid condition type** | A transition has an unrecognised `condition_type`. | Check the trigger type selector; it must be Intent, Rule, or Always. |
| **Invalid expression structure** | A Rule transition's expression is malformed (missing `logic`, empty `conditions`). | Open the edge inspector and ensure every condition row has a variable, operator, and value. |
| **Invalid operator** | A condition uses an operator not in the supported list. | Select a valid operator from the dropdown. |
| **Knowledge base with no vectors** | A node has a knowledge base attached but no vector IDs selected. | Open the node inspector and select at least one vector store, or remove the knowledge base. |
***
## Warnings (non-blocking)
Warnings don't block saving. The validation dialog lets you proceed with warnings acknowledged.
| Warning | What it means | Recommendation |
| ----------------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
| **Unreachable node** | A node has no transitions pointing to it and is not the start node. | Add a transition to it or delete it. |
| **Empty LLM prompt** | An LLM node has no prompt text. | Add a prompt so the LLM knows what to do on this node. |
| **Static node without message** | A static node has no spoken message configured. | Open the node inspector and add a static message. |
| **Empty intent condition** | An Intent transition has no condition text and no label, on a node with multiple outgoing edges. | Add a condition describing when to take this transition. |
| **Duplicate transition priorities** | Two Rule or Always transitions on the same node have the same priority value. | Set distinct priorities to make evaluation order explicit. |
***
## Navigating to issues
Click any issue row in the validation dialog. The dialog closes, the canvas scrolls to the affected node or transition, and the inspector opens on it. Fix the issue, then open validation again to re-check.
***
## Saving with warnings
If your graph has warnings but no errors, you can save it. Saving with warnings proceeds immediately — no confirmation dialog is shown. A toast notification confirms the save completed. Warnings are guidance, not enforcement, and do not affect runtime behaviour.
# Variables
Source: https://www.bolna.ai/docs/graph-agent/variables
Use {variable} tokens in node prompts, the welcome message, and edge conditions — then set values in the variables panel.
Variables are `{name}` tokens you embed in node prompts, the welcome message, or edge conditions. At call time, the platform substitutes real values from `context_data` (the data passed when the call was created or filled in by inline data extraction). In the editor, the Variables panel lets you set test values so the validation and test features use realistic content.
***
## Using variables in content
Place a `{variable_name}` token anywhere in a node prompt, the welcome message, or an edge condition. The token is replaced at runtime with the corresponding value from `context_data`.
**Welcome message:**
```
Hi {customer_name}, thanks for calling. How can I help you today?
```
**Node prompt:**
```
The customer's order ID is {order_id}. Look up the order status and read it back.
```
**Edge condition (Intent):**
```
Customer confirms the order {order_id} should be cancelled
```
Variables in expression conditions (Rule edges) reference context variables by name without braces. The braces syntax `{name}` is only for text substitution in prompts and messages.
***
## The Variables panel
Click **Variables** in the toolbar to open the variables panel. The panel automatically discovers every `{variable_name}` token in:
* All node prompts
* Node examples (multilingual)
* Edge condition text
* Edge parameters
* The welcome message
Each discovered variable appears as a labelled input field. Set any values you want to use during validation checks and test runs.
Values set in the variables panel are saved locally per agent (they don't affect the saved agent payload). They persist across editor sessions in your browser.
### Expression variable types
The Variables panel also shows a second section: **Expression variable types**. For every variable referenced in a Rule (Expression) transition condition, you can declare its type — `string`, `number`, `boolean`, or `auto`. Declared types coerce the value before condition evaluation. Undeclared variables use automatic type inference.
This section only appears when your graph has at least one Expression transition.
***
## Built-in variables
These variables are populated automatically by the platform at call time. You don't need to pass them in `context_data`. They are available in expression conditions and can be referenced in prompts.
| Variable | When to use in prompts |
| -------------------------------- | --------------------------------------------------- |
| `recipient_data.current_hour` | Telling the agent the current hour |
| `recipient_data.current_minute` | Referencing the current minute |
| `recipient_data.current_weekday` | Weekday-aware behaviour (e.g. "closed on weekends") |
| `recipient_data.current_day` | Referencing the day of the month |
| `recipient_data.current_month` | Month-aware behaviour |
| `recipient_data.current_year` | Year-aware behaviour |
| `recipient_data.current_date` | Displaying the current date to the caller |
| `recipient_data.current_time` | Displaying the current time to the caller |
| `recipient_data.timezone` | Informing timezone-aware behaviour |
| `recipient_data.user_number` | Referencing the caller's phone number |
| `detected_language` | Switching language or tone mid-call |
| `_node_turns` | Prompting retry escalation logic |
| `_total_turns` | Prompt context about conversation length |
See [Edges & routing](/docs/graph-agent/edges-and-routing#built-in-variables) for the full reference including numeric types for use in expression conditions.
***
## Variables from inline data extraction
Transitions can capture values from the user's reply and store them as variables. After a transition fires and captures `order_id`, that value becomes available in downstream node prompts as `{order_id}` and in expression conditions as the variable `order_id`.
See [Inline data extraction](/docs/graph-agent/edges-and-routing#inline-data-extraction) for how to set this up on a transition.
# Version History
Source: https://www.bolna.ai/docs/graph-agent/version-history
View every saved version of your graph agent and restore any previous version with one click.
Every time you save a graph agent, the platform creates a version snapshot. The Version history sheet shows all past versions and lets you restore any of them.
***
## Opening version history
Click **Version history** in the toolbar. A sheet slides in from the right side of the canvas, listing all saved versions in reverse chronological order.
***
## Version list
Each version row shows:
* **Version name** — auto-generated name or a custom label if one was set.
* **Saved at** — the date and time the version was created.
* **Status** — `current` for the active version.
* **Tags** — any tags applied to the version (optional).
***
## Restoring a version
1. Find the version you want to restore in the list.
2. Click **Restore** on that row.
3. The editor reloads with the restored version's graph.
Restoring a version replaces the current graph with the restored version's graph. Your current unsaved changes are discarded. Save first if you want to preserve them.
Restoring a version creates a new save rather than overwriting history. The restored version appears as the new most-recent entry. The full version history is preserved.
***
## Versioning vs export
| | Version history | Export |
| -------------------- | ---------------------------------- | ------------------- |
| **Automatic** | Yes — every save creates a version | No — manual |
| **Stored on server** | Yes | No (local file) |
| **Shareable** | No | Yes |
| **Rollback** | Click Restore | Import the file |
| **History depth** | All saves | One file per export |
Use version history for routine rollbacks. Use export when you need a portable copy to share or archive.
# Fetch Agent Executions using APIs
Source: https://www.bolna.ai/docs/guides/fetch-agent-executions
Sample Python guide demonstrating how to query and paginate through agent executions, with support for filters, logging, and best practices.
## API Endpoint Overview
### Endpoint
[Agent Executions API](/docs/api-reference/executions/get_executions) - Fetches executions for a specified `agent_id`.
### Request Details
* **Path Parameters**
* `agent_id` (UUID, required): The ID of your agent.
* **Query Parameters** (all optional unless noted):
* `page_number` (integer, default 1): Page index, starting at 1. Must be ≥ 1.
* `page_size` (integer, default 20, max 50): Results per request.
* **Filters**:
* `status` (enum): Filter by execution status (`scheduled`, `queued`, `in-progress`, `completed`, `failed`, etc.)
* `call_type` (enum): `inbound` or `outbound`
* `provider` (enum): e.g., `twilio`, `plivo`, `websocket`, `web-call`
* `answered_by_voice_mail` (boolean): Filter calls answered by voicemail
* `batch_id` (string): Narrow results by batch
* `from` (string, date-time): Filter by starting timestamp
* `to` (string, date-time): Filter by ending timestamp
### Authorization
Include your API key as a Bearer token in the header:
```http theme={"system"}
Authorization: Bearer
```
***
## Example Python Code
```python theme={"system"}
import aiohttp
import time
all_executions = []
page_number = 1
agent_id = "" # your agent_id
api_key = "" # your Bolna API key
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
async with aiohttp.ClientSession(headers=headers) as session:
while True:
ts_start = time.time() * 1000
print(f"Starting fetch for page {page_number} at {ts_start:.0f} ms")
url = f"https://api.bolna.ai/v2/agent/{agent_id}/executions?page_size=50&page_number={page_number}"
async with session.get(url) as resp:
status_code = resp.status
res = await resp.json()
ts_end = time.time() * 1000
print(f"Fetched page {page_number} in {ts_end - ts_start:.2f} ms")
if status_code != 200:
logger.error(f"Error fetching page {page_number}: status {status_code}")
break
page = res.get("data", [])
all_executions.extend(page)
if res.get("has_more", False):
page_number += 1
else:
print("Completed fetching all executions")
break
```
***
## Why This Matters
| Benefit | Description |
| -------------------------- | --------------------------------------------------------------------------- |
| **Complete History** | Retrieve full call/execution logs for audits, analytics, or dashboards. |
| **Filtering & Efficiency** | Use filters to slice data by status, provider, call type, date, batch, etc. |
***
## Quick FAQs
### How do I fetch all executions for a Bolna agent?
Use the endpoint `/v2/agent/{agent_id}/executions` with pagination and keep fetching while `has_more == true`.
### Can I filter executions by provider or call type?
Yes, you can use query parameters like `provider=twilio`, `call_type=inbound`, `status=completed` and more.
### What is the max page size?
`50` results per page is the maximum allowed. Default is `20`.
### How are extracted fields returned?
In your response under `extracted_data`, with your custom JSON fields—based on your Extraction prompt setup.
***
# Buy Phone Numbers for Your Bolna Voice AI Agents
Source: https://www.bolna.ai/docs/guides/inbound/buying-phone-numbers
Purchase dedicated US and Indian phone numbers from the Bolna dashboard. US numbers use Twilio, Indian numbers use Plivo or Vobiz with regional selection. $5/month per number.
Buy dedicated phone numbers directly from the Bolna dashboard. Each number costs **\$5/month**, billed as a recurring subscription from your Bolna wallet balance.
Buy and view your phone numbers at [platform.bolna.ai/phone-numbers](https://platform.bolna.ai/phone-numbers).
***
## How to Buy a Phone Number
Navigate to **My Numbers** in the sidebar and click the **Buy Phone Number** button in the top right.
Open the **Select Country** dropdown. The available countries are **United States** and **India**. The purchase flow changes based on your selection.
***
## United States Numbers
US numbers are provided through **Twilio**. You can search for numbers by area code pattern.
Type an area code in the **Pattern** field to filter results. For example, enter `718` to find numbers starting with that prefix. Results appear in the format `1718XXXXXXX`.
Click **Select phone number** to browse available numbers. Pick one from the list.
Click **Purchase number** to complete the purchase. The \$5/month cost is deducted from your wallet balance.
***
## India Numbers
Indian numbers require compliance verification. When you select **India**, the purchase flow changes: the **Pattern** field is replaced by a **Region** selector, and you must choose a telephony provider.
Regions: Karnataka (80), Maharashtra (22)
Regions: Karnataka (80), Gujarat (79), NCR (11)
The region code appears after `+91` in the phone number. For example, a Karnataka number looks like `+9180XXXXXXXX`.
### Plivo
### Vobiz
Choose **Plivo** or **Vobiz** from the provider dropdown.
Select a region from the dropdown, or leave it on **All regions** to see all available numbers.
Pick a number from the list and click **Purchase number**.
Indian numbers require compliance approval. You may need to submit identity documents before your number is activated.
***
## Pricing
All phone numbers cost **\$5/month** as a recurring subscription. The amount is deducted automatically from your Bolna wallet balance each month on the renewal date.
Phone number charges are **separate** from call charges. The \$5/month covers only the number itself. Per-minute telephony and provider costs are billed separately when you make or receive calls.
View [call pricing](/docs/pricing/call-pricing) for details on per-minute call costs and telephony charges.
***
## What Can You Do with Purchased Numbers?
Call customers from your dedicated numbers
Route incoming calls to your Voice AI agents
Run calling campaigns at scale with CSV uploads
Learn more about Twilio, Plivo, and Vobiz
# DTMF (Keypad Input)
Source: https://www.bolna.ai/docs/guides/inbound/dtmf
Let callers enter digits on their phone keypad and have your voice agent respond to the input.
## What is DTMF?
DTMF (Dual-Tone Multi-Frequency) is the system behind phone keypad input: the tones produced when a caller presses a digit key (0-9, `*`, `#`).
When enabled, digit presses from the caller are captured and sent to the agent as a text message, which the LLM can read and respond to just like spoken input.
## When to use it
DTMF is useful any time you want callers to enter structured numeric input without speaking it:
* **PIN or OTP verification** -- "Please enter your 6-digit OTP followed by #"
* **Account or order number lookup** -- "Enter your account number and press #"
* **Phone number capture** -- collecting a callback number during a call
* **Confirmation flows** -- "Press 1 to confirm, 2 to cancel"
* **Sensitive input** -- when callers are uncomfortable speaking a number aloud (e.g. a password or card number)
DTMF works alongside speech. A caller can still speak normally between keypad entries.
For branching menu flows ("press 1 for sales, press 2 for support"), use [IVR Inbound Calls](/docs/guides/inbound/ivr-inbound-calls) instead. It handles menu routing natively without an LLM.
## Telephony support
| Provider | Support |
| ---------------- | ----------------------- |
| Plivo | Supported |
| Twilio | Supported |
| SIP Trunk (BYOT) | Currently not supported |
| Exotel | Currently not supported |
| Vobiz | Currently not supported |
## Enabling DTMF
### From the dashboard
Toggle on **Keypad Input (DTMF)** in the **Call Tab** of your agent.
### Via the API
Set `dtmf_enabled: true` inside `task_config` when creating or updating an agent:
```json theme={"system"}
{
"task_config": {
"dtmf_enabled": true
}
}
```
## How it works
1. The agent asks the caller to enter digits and press `#`.
2. The caller presses keys on their keypad.
3. Bolna accumulates the digits until `#` is pressed.
4. The digits are delivered to the agent as: `dtmf_number: `
5. The agent responds to the input.
`#` is the termination key. The agent only receives the input after the caller presses it. The `#` itself is not included in the value.
## Writing the prompt
Tell callers to press `#` after their entry, and tell the agent what to do when it sees a `dtmf_number:` message.
**Example prompt snippet:**
```
When you need the caller's phone number, say:
"Please enter your phone number on your keypad and press the hash key when you are done."
When you receive a message starting with "dtmf_number:", the digits that follow are what the caller entered.
Read them back to confirm and proceed accordingly.
```
**What the agent receives:**
```
dtmf_number: 9876543210
```
The agent treats this like any other message in the conversation. It can confirm the value, use it in a tool call, or move to the next step based on it.
## Next Steps
Menu-based call routing with keypad navigation
All call configuration options
# Set Up IVR for Inbound Calls in Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/inbound/ivr-inbound-calls
Configure IVR menus to route inbound calls to different Bolna Voice AI agents. Support department routing, language selection, and data collection.
## What is IVR?
IVR (Interactive Voice Response) lets callers navigate menus using their phone keypad before connecting to a Voice AI agent.
Send callers to Sales, Support, or Billing agents automatically
Gather account numbers, PINs, or preferences before the conversation
Let callers choose their preferred language before connecting
IVR is currently supported for **Plivo** phone numbers only.
***
## How IVR Works
```mermaid theme={"system"}
flowchart LR
A[Caller Dials] --> B[Welcome Message]
B --> C[IVR Menu Prompt]
C --> D{Caller Presses Digit}
D --> E[Next Menu / Collect Step]
D --> F[Connect to Agent]
E --> D
style A fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style B fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style C fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style D fill:#fff3cd,stroke:#ffc107,stroke-width:2px
style E fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style F fill:#d4edda,stroke:#28a745,stroke-width:2px
```
All collected data (department choice, account number, etc.) is passed to the agent as context.
***
## Setting Up IVR via API
Add `ivr_config` to the [Set Inbound Agent API](/docs/api-reference/inbound/agent):
```bash request theme={"system"}
curl -X POST "https://api.bolna.ai/inbound/setup" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"agent_id": "your-default-agent-id",
"phone_number_id": "your-phone-number-id",
"ivr_config": {
"enabled": true,
"voice": "Polly.Aditi",
"welcome_message": "Welcome to Acme Corp.",
"steps": [
{
"step_id": "main_menu",
"type": "menu",
"prompt": "Press 1 for Sales. Press 2 for Support.",
"field_name": "department",
"options": [
{"digit": "1", "label": "Sales", "agent_id": "sales-agent-id"},
{"digit": "2", "label": "Support", "agent_id": "support-agent-id"}
]
}
]
}
}'
```
```json response theme={"system"}
{
"message": "Phone number is already mapped to the given agent. IVR config updated."
}
```
***
## IVR Configuration Reference
### Top-Level Config
| Field | Type | Default | Description |
| ----------------------- | ------- | ---------------------------------- | ------------------------------------------------ |
| `enabled` | boolean | `false` | Enable or disable IVR |
| `voice` | string | `Polly.Joanna` | Text-to-speech voice for IVR prompts |
| `welcome_message` | string | - | Played once when the call connects |
| `timeout` | integer | `5` | Seconds to wait for caller input |
| `max_retries` | integer | `2` | Retry count on invalid input |
| `invalid_input_message` | string | `Invalid input. Please try again.` | Played on wrong key press |
| `no_input_message` | string | `No input received. Goodbye.` | Played on timeout |
| `steps` | array | **required** | IVR flow steps (see below) |
| `default_agent_id` | string | - | Fallback agent when no option-level agent is set |
### Available Voices
| Voice | Language |
| --------------- | ------------------------ |
| `Polly.Aditi` | Hindi + Indian English |
| `Polly.Raveena` | Indian English |
| `Polly.Joanna` | US English (Female) |
| `Polly.Matthew` | US English (Male) |
| `Polly.Amy` | British English (Female) |
***
## Step Types
Presents options for the caller to select using the keypad.
```json theme={"system"}
{
"step_id": "department",
"type": "menu",
"prompt": "Press 1 for Sales. Press 2 for Support.",
"field_name": "department",
"options": [
{"digit": "1", "label": "Sales", "agent_id": "sales-agent-id"},
{"digit": "2", "label": "Support", "agent_id": "support-agent-id"}
]
}
```
**Option Fields:**
| Field | Type | Required | Description |
| --------------- | ------ | -------- | ---------------------------------- |
| `digit` | string | Yes | Key to press (`"1"`, `"2"`, etc.) |
| `label` | string | Yes | Value stored in collected data |
| `agent_id` | string | No | Route to a specific agent |
| `context_label` | string | No | Additional context passed to agent |
Collects multi-digit input like account numbers or PINs.
```json theme={"system"}
{
"step_id": "account",
"type": "collect",
"prompt": "Enter your 6-digit account number.",
"field_name": "account_number",
"num_digits": 6,
"next_step": "pin_step"
}
```
**Collect Fields:**
| Field | Type | Description |
| --------------- | ------- | ---------------------------------------- |
| `num_digits` | integer | Exact number of digits required |
| `min_digits` | integer | Minimum digits (if `num_digits` not set) |
| `max_digits` | integer | Maximum digits (if `num_digits` not set) |
| `finish_on_key` | string | Submit key (default: `#`) |
***
## Step Navigation
Control flow between steps:
| Field | Usage | Description |
| ------------------ | ----------- | ------------------------------------------------------ |
| `next_step` | Linear flow | Go to specified step after this one |
| `conditional_next` | Branching | Route based on digit: `{"1": "step_a", "2": "step_b"}` |
| *(neither)* | End flow | Routes to the assigned agent |
Use `conditional_next` for language selection or department-specific sub-menus. Combine with `next_step` for sequential data collection.
***
## Data Passed to Agent
All collected IVR data is available in `recipient_data`:
```json theme={"system"}
{
"department": "Sales",
"department_context": "sales_inquiry",
"account_number": "123456",
"ivr_completed_at": "2026-01-15T10:30:00Z"
}
```
Reference these in your agent prompt:
```
Customer selected {department}. Account: {account_number}
```
Learn more about using dynamic variables in [Using Context](/docs/guides/prompting/using-context).
***
## Examples
Route calls to different agents based on selection:
```json theme={"system"}
{
"ivr_config": {
"enabled": true,
"voice": "Polly.Aditi",
"welcome_message": "Welcome to Acme Corp.",
"steps": [
{
"step_id": "department",
"type": "menu",
"prompt": "Press 1 for Sales. Press 2 for Support. Press 3 for Billing.",
"field_name": "department",
"options": [
{"digit": "1", "label": "Sales", "agent_id": "sales-agent-uuid"},
{"digit": "2", "label": "Support", "agent_id": "support-agent-uuid"},
{"digit": "3", "label": "Billing", "agent_id": "billing-agent-uuid"}
]
}
]
}
}
```
Language selection followed by department menu:
```json theme={"system"}
{
"ivr_config": {
"enabled": true,
"voice": "Polly.Aditi",
"welcome_message": "Welcome. Swagat hai.",
"steps": [
{
"step_id": "language",
"type": "menu",
"prompt": "For English press 1. Hindi ke liye 2 dabayein.",
"field_name": "language",
"options": [
{"digit": "1", "label": "English"},
{"digit": "2", "label": "Hindi"}
],
"conditional_next": {"1": "menu_en", "2": "menu_hi"}
},
{
"step_id": "menu_en",
"type": "menu",
"prompt": "Press 1 for Sales. Press 2 for Support.",
"field_name": "department",
"options": [
{"digit": "1", "label": "Sales", "agent_id": "english-sales-agent"},
{"digit": "2", "label": "Support", "agent_id": "english-support-agent"}
]
},
{
"step_id": "menu_hi",
"type": "menu",
"prompt": "Sales ke liye 1 dabayein. Support ke liye 2 dabayein.",
"field_name": "department",
"options": [
{"digit": "1", "label": "Sales", "agent_id": "hindi-sales-agent"},
{"digit": "2", "label": "Support", "agent_id": "hindi-support-agent"}
]
}
]
}
}
```
Collect account details before connecting to an agent:
```json theme={"system"}
{
"ivr_config": {
"enabled": true,
"voice": "Polly.Aditi",
"welcome_message": "Welcome to your bank.",
"default_agent_id": "bank-agent-uuid",
"steps": [
{
"step_id": "account",
"type": "collect",
"prompt": "Please enter your 10-digit account number.",
"field_name": "account_number",
"num_digits": 10,
"next_step": "pin"
},
{
"step_id": "pin",
"type": "collect",
"prompt": "Enter your 4-digit PIN.",
"field_name": "pin",
"num_digits": 4
}
]
}
}
```
***
## Disable IVR
To disable IVR and route calls directly to your agent:
```bash theme={"system"}
curl -X POST "https://api.bolna.ai/inbound/setup" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"agent_id": "your-agent-id",
"phone_number_id": "your-phone-number-id",
"ivr_config": {"enabled": false}
}'
```
***
## Next Steps
Basic inbound calling configuration
Use your own Plivo phone numbers
Pass dynamic data to your agents
# How to Get 140 & 160-Series Phone Numbers in India
Source: https://www.bolna.ai/docs/guides/inbound/obtaining-regulated-phone-numbers
Complete guide to obtaining regulated 140-series and 160-series phone numbers in India for Voice AI calling. Covers DLT registration, required documents, KYC, and the step-by-step provisioning process.
## Why Do You Need Regulated Numbers?
To make commercial or telemarketing calls in India, businesses must use regulated phone numbers issued under TRAI guidelines. These numbers require registration on the **DLT (Distributed Ledger Technology)** platform before they can be used.
| Number Series | Use Case | Telephony Provider |
| -------------- | ---------------------------------------------------------- | ------------------ |
| **140-series** | Telemarketing and promotional calls | Vobiz |
| **160-series** | Transactional and service calls (banking, insurance, etc.) | Plivo |
DLT registration is mandatory to procure 140 or 160-series numbers from Indian telephony providers.
***
## 140-Series Numbers (Telemarketing)
140-series numbers are used for **promotional and telemarketing calls**. Bolna uses **Vobiz** as the telephony provider for Indian calling, and Vobiz recommends registering on the **TATA Teleservices DLT portal**.
### Registration Process
Visit the [TATA Teleservices DLT portal](https://telemarketer.tatateleservices.com/#/) and select **Register as Principal Entity**.
Upload the following documents during registration:
| Document | Details |
| --------------------------------- | ---------------------------------------------------------------------- |
| **Certificate of Incorporation** | Issued by Ministry of Corporate Affairs (MCA) / Registrar of Companies |
| **GST Certificate** | Copy of your GST registration |
| **Company PAN Card** | PAN card in the company's name |
| **Director List & MOA** | Memorandum of Association with the list of directors |
| **Letter of Authorization (LOA)** | Signed by the director whose name is mentioned in the MOA |
The LOA must be signed by a director whose name appears in the Memorandum of Association (MOA). Download the sample LOA template from the DLT portal, fill in the required details, and get it signed before uploading.
Submit the LOA with your official **mobile number** and **email ID**. OTPs for verification will be sent to these details during the registration process. Contact [compliance@bolna.ai](mailto:compliance@bolna.ai) to solicit a sample LOA.
The mobile number and email ID in the LOA become your permanent registered contact for all DLT communications. These cannot be easily changed after submission — choose carefully.
Once your Digital KYC is verified, a payment link for **₹5,900** will be generated on the portal. Complete the payment to finalize your Principal Entity registration.
Keep the mobile number and email from your LOA accessible throughout the process — all OTPs are sent there.
***
## 160-Series Numbers (Transactional & Service Calls)
160-series numbers are used for **transactional and service communication** such as banking alerts, insurance reminders, and regulatory notifications. These require additional provisioning through **Plivo** after DLT registration.
### Documents Required
Required as proof of regulatory compliance during Header registration on DLT
COI and GST Certificate for Plivo KYC verification
Principal Entity ID and Telemarketer ID, generated after DLT registration
Your compliance name to be shared with Plivo during provisioning
### Provisioning Process
Complete your DLT registration as a Principal Entity (same process as the 140-series registration above). This generates your **PE ID** and **TM ID**.
Share your **Certificate of Incorporation (COI)** and **GST Certificate** with Bolna for Plivo KYC verification.
This step can be skipped if your Plivo KYC on Bolna is already completed.
Provide your **PE-ID**, **TM-ID**, and **compliance application name** to Bolna for verification with Plivo.
Plivo will verify the submitted details and allocate the 160-series number to your Plivo KYC previously done on your Bolna account.
The allocated numbers will **not be active** at this stage. Further steps are required before you can start making calls.
Register your Header on the DLT portal. Submit the **RBI / SEBI Certificate** as proof of regulatory compliance during this step.
After Header registration, obtain your **URN (Unique Reference Number)**. Share the URN and the **approval screenshot** with Bolna. Bolna will ensure Plivo coordinates with TATA Teleservices for header approval.
Once the header is approved, proceed with **Template registration** on the DLT portal.
Once the template is approved, your 160-series numbers will be **active** and ready for calling.
***
## Next Steps
Once your DLT registration is approved and numbers are provisioned, you can:
Purchase regulated numbers for your outbound agents
Set up your outbound calling agent
Run calling campaigns at scale
Stay compliant with TRAI regulations
# Handle Inbound Calls with Bolna Voice AI Agents
Source: https://www.bolna.ai/docs/guides/inbound/receiving-incoming-calls
Set up Bolna Voice AI agents to answer incoming calls. Assign phone numbers, configure settings via the dashboard or API, and enhance customer interactions.
## How to set up inbound calls with Bolna?
To handle incoming calls with your Bolna Voice AI agent, you need to assign a phone number to your agent. When someone calls that number, your agent will automatically answer and have a conversation based on your configured prompts and settings.
You will need to assign a phone number to your Bolna Voice AI agent for automatically answering all incoming calls on that phone number
## What are my options for getting a phone number?
### Method 1. Purchase a phone number from the [Bolna Dashboard](https://platform.bolna.ai/phone-numbers).
Please refer to a [step by step tutorial for purchasing phone numbers on Bolna](/docs/guides/inbound/buying-phone-numbers).
### Method 2. Connect your Telephony account and use your own phone numbers.
>
}
href="/twilio-connect-provider"
>
Use your own Twilio phone numbers with Bolna
>
}
href="/plivo-connect-provider"
>
Use your own Plivo phone numbers with Bolna
>
}
href="/vobiz-connect-provider"
>
Use your own Vobiz phone numbers with Bolna
>
}
href="/exotel-connect-provider"
>
Use your own Exotel phone numbers with Bolna
***
## How to set up inbound calls from the dashboard?
## How to set up inbound calls using APIs?
#### Step 1. Use [List Phone Numbers API](api-reference/phone-numbers/get_all) to list all avalable phone numbers.
```curl request-phone-numbers theme={"system"}
curl --request GET \
--url https://api.bolna.ai/phone-numbers/all \
--header 'Authorization: Bearer '
```
```json response-phone-numbers theme={"system"}
[
{
"id": "3c90c3cc0d444b5088888dd25736052a",
"humanized_created_at": "5 minutes ago",
"created_at": "2024-01-23T05:14:37Z",
"humanized_updated_at": "5 minutes ago",
"updated_at": "2024-02-29T04:22:89Z",
"renewal_at": "17th Dec, 2024",
"phone_number": "+19876543210",
"agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"price": "$5.0",
"telephony_provider": "twilio",
"rented": true
}
]
```
#### Step 2. Use [Set Inbound Agent API](api-reference/inbound/agent) to assign a phone number for Bolna Voice AI agent.
```curl request-set-inbound-agent theme={"system"}
curl --request POST \
--url https://api.bolna.ai/inbound/setup \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"phone_number_id": "123e4567-e89b-12d3-a456-426614174000"
}'
```
```json response-setup-inbound-agent theme={"system"}
{
"url": "https://api.bolna.ai/inbound_call?agent_id=3c90c3cc-0d44-4b50-8888-8dd25736052a&user_id=28f9c34b-8eb0-4af5-8689-c2f6c4daec22",
"phone_number": "+19876543210",
"id": "3c90c3cc0d444b5088888dd25736052a"
}
```
## Next steps
Ready to start receiving inbound calls? [Configure your agent](/docs/agent-setup/agent-tab) and explore related features:
* [Make outbound calls](/docs/guides/outbound/making-outgoing-calls) to complement your inbound setup
* [Supported telephony providers](/docs/supported-telephony-providers) for integration options
* [Call transfer functions](/docs/tool-calling/transfer-calls) to route to human agents
* [Monitor call status](/docs/guides/post-call/list-phone-call-status) in real-time
For 24/7 automated support, combine inbound calling with [guardrails](/docs/guardrails) and [custom prompts](/docs/agent-setup/agent-tab).
# Truecaller Verification for Phone Numbers
Source: https://www.bolna.ai/docs/guides/inbound/truecaller-verification
Verify phone numbers with Truecaller to display your business name with logo when making calls to improve answer rates and build trust with Bolna Voice agents.
## What is Truecaller Verification?
Truecaller verification allows your **business name and logo** to be displayed on recipients' phones when your Voice AI agents make outbound calls. This powerful feature significantly increases call answer rates and builds instant trust with your customers by showing them exactly who is calling before they pick up.
## Why Use Truecaller Verification?
Recipients are significantly more likely to answer calls when they see your verified business name
Display your company logo alongside your business name on every call
Verified caller ID establishes credibility and professionalism with customers
Identified calls are far less likely to be marked as spam or blocked
## Verification Status States
Your phone number can be in one of the following Truecaller verification states:
| Status | Icon | Description |
| --------------------- | ----------------- | ----------------------------------------------------------- |
| **Unverified** | REQUEST | Number has not been submitted for Truecaller verification |
| **Pending** | PENDING | Verification request is being processed by our team |
| **Active** | ACTIVE | Number is verified and displaying your business information |
| **Delisting Pending** | DELISTING PENDING | Delisting request is being processed |
| **Delisted** | REQUEST | Number has been removed from Truecaller verification |
**Important**: When a number is in the **Delisting Pending** state, calls cannot be made from that number. Remove the number from any active agents and avoid using it until the delisting process is complete.
## How to Request Truecaller Verification
Follow these steps to get your phone number verified with Truecaller:
1. Navigate to the [Phone Numbers](https://platform.bolna.ai/phone-numbers) page in your Bolna dashboard.
Find the phone number you want to verify and click REQUEST in the **Verify on Truecaller** column.
2. A verification request form will appear. Enter your **Company Name** — this is the business name that will be displayed to call recipients when your Voice AI agents make calls.
3. Select the **Category** that best describes your business from the dropdown menu. Categories include Education, Finance & Insurance, Health & Wellness, and many more.
4. Choose a **Sub-category** that more specifically describes your business type. This helps Truecaller accurately classify your business for recipients.
5. Select the **Reason for Calling** from the options provided. This tells recipients the purpose of your calls, such as Customer Support, Delivery Confirmation, Front Desk, Recruitment, and more.
6. Upload your **Brand Icon** (company logo) that will be displayed alongside your business name.
**Brand Icon Requirements:**
* **File format**: PNG only
* **Dimensions**: Exactly **200 × 200 pixels**
* Use a clear, recognizable version of your logo. Avoid text-heavy images as they may not be legible at small sizes on mobile devices.
7. Click **Submit request** to send your verification application. Your number's status will change to **Pending**.
## After Submitting Your Request
Once you submit your Truecaller verification request:
Our team reviews your application to ensure it meets Truecaller's guidelines
Verification typically takes **a couple of business days**
You'll receive an email notification once your verification is activated
The status icon will change to when active
You can continue making calls while your verification is pending. The Truecaller display will only appear once the verification is active.
## Viewing Verification Details
For numbers with **Pending**, **Active**, or **Delisting Pending** status, click the status icon to view your verification details including:
* Company name
* Category and sub-category
* Reason for calling
## How to Delist a Number
If you no longer want Truecaller verification for a phone number, you can request delisting:
Navigate to [Phone Numbers](https://platform.bolna.ai/phone-numbers) and click the ACTIVE on the verified number.
In the verification details dialog, click the **Delist verification** button.
Your number's status will change to **Delisting Pending** while the delisting is being processed internally by the team. Note that once opted for delisting pending outbound and inbound calls on this number will be blocked.
**Critical Warning**: During the delisting process, your phone number **cannot be used for calls**. This includes both outbound calls and batch campaigns. Make sure to:
* Remove the number from any active Voice AI agents
* Pause any scheduled batch campaigns using this number
* Wait for the delisting to complete before reassigning the number
## Pricing
Truecaller verification is billed as per usage. The charge is:
* Automatically deducted from your Bolna wallet balance
* Billed monthly from the date of verification activation
* Stopped when you delist the number (after the current billing period)
## Frequently Asked Questions
Verification typically takes **1-3 business days**. You'll receive an email notification once your verification is active.
To update your company name, logo, or other details, you'll need to delist the current verification and submit a new request with the updated information.
Common reasons for rejection include:
* **Brand icon not meeting requirements** — must be exactly 200×200 pixels PNG
* **Company name mismatch** — name not matching your registered business
* **Incorrect category** — category selection not appropriate for your business type
If rejected, you can submit a new request with corrected information.
Yes, you can request Truecaller verification for any phone number purchased through Bolna. Each number is verified and billed separately.
If your wallet balance is insufficient for the monthly renewal, your verification may be suspended. Ensure you maintain adequate balance to keep your verifications active.
Delisting typically takes **1-3 business days**. During this time, the number cannot be used for calls.
# Auto-Retry for Failed Calls
Source: https://www.bolna.ai/docs/guides/outbound/auto-retry
Automatically retry calls that fail due to no-answer, busy signals, or errors to improve contact rates.
## What is Auto-Retry?
Auto-retry automatically reschedules calls that fail to connect. When a call ends with statuses like `no-answer` or `busy`, Bolna retries the call after a configurable delay, improving your overall contact rates without manual intervention.
***
## How to Enable Auto-Retry
Add the `retry_config` object when making a call via the [Make Call API](/docs/api-reference/calls/make) or [Create Batch API](/docs/api-reference/batches/create).
```bash Single Call theme={"system"}
curl -X POST 'https://api.bolna.ai/call' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
-d '{
"agent_id": "your-agent-id",
"recipient_phone_number": "+1234567890",
"retry_config": {
"enabled": true,
"max_retries": 3,
"retry_on_statuses": ["no-answer", "busy", "failed"],
"retry_intervals_minutes": [30, 60, 120]
}
}'
```
```bash Batch Call theme={"system"}
curl -X POST 'https://api.bolna.ai/batches' \
-H 'Authorization: Bearer ' \
-F 'agent_id=your-agent-id' \
-F 'file=@contacts.csv' \
-F 'retry_config={"enabled":true,"max_retries":2,"retry_intervals_minutes":[15,30]}'
```
***
## Configuration Options
| Parameter | Type | Default | Description |
| ------------------------- | ------- | --------------------------------- | -------------------------------------------- |
| `enabled` | boolean | `false` | Enable auto-retry |
| `max_retries` | integer | `3` | Maximum retry attempts (1–3) |
| `retry_on_statuses` | array | `["no-answer", "busy", "failed"]` | Statuses that trigger a retry |
| `retry_on_voicemail` | boolean | `false` | Retry if voicemail is detected |
| `retry_intervals_minutes` | array | `[30, 60, 120]` | Delay (in minutes) before each retry attempt |
### Supported Retry Statuses
| Status | Description |
| ----------- | ------------------------------ |
| `no-answer` | Call rang but was not answered |
| `busy` | Line was busy |
| `failed` | Call failed to connect |
| `error` | Technical error occurred |
***
## Monitoring Retries via Webhook
When auto-retry is configured, your webhook receives retry information with each status update:
```json theme={"system"}
{
"id": "execution-id",
"status": "scheduled",
"retry_count": 1,
"retry_config": {
"enabled": true,
"max_retries": 3
},
"retry_history": [
{
"attempt": 1,
"status": "no-answer",
"at": "2026-01-26T10:00:00Z"
}
],
"scheduled_at": "2026-01-26T10:30:00Z"
}
```
***
## Best Practices
Start with 30+ minute intervals to avoid annoying contacts with rapid retries
Keep `retry_on_voicemail: false` (default) to avoid repeated voicemail deposits
Track `retry_count` in webhooks to measure retry effectiveness over time
Use 1–2 retries for time-sensitive calls, 3 for lead outreach campaigns
***
## Related Features
Run campaigns with thousands of contacts
Get real-time call status updates
View execution history and outcomes
# Automate and schedule calls using Batches
Source: https://www.bolna.ai/docs/guides/outbound/batch-calling
Learn how to schedule and manage batch calls using Bolna's Voice AI agents. Upload CSV files, set call parameters, and monitor execution for efficient outreach.
## What is Batch Calling?
Batch calling lets you automate outbound calls to hundreds or thousands of contacts by uploading a CSV file with phone numbers and custom data. Ideal for lead qualification, customer outreach, appointment reminders, and other high-volume calling campaigns.
***
## CSV File Format
Your CSV file must follow these rules:
All phone numbers must include the country prefix in [E.164](https://en.wikipedia.org/wiki/E.164) format (e.g., `+11231237890`).
The phone number column must use `contact_number` as the header.
Include any additional variables (name, address, etc.) as separate columns. These are passed to the agent as context.
```csv example_batch_file.csv theme={"system"}
contact_number,first_name,last_name
+11231237890,Bruce,Wayne
+91012345678,Bruce,Lee
+00021000000,Satoshi,Nakamoto
+44999999007,James,Bond
```
In Excel, typing `+` at the beginning of a cell is interpreted as a formula. **Add an apostrophe (`'`) before the plus sign** to retain it.
[Download an example CSV file](https://bolna-public.s3.amazonaws.com/Bolna+batch+calling+example+csv.csv)
Only the **`contact_number`** column is validated for correctness. Other columns (custom variables like `first_name`, `address`, etc.) are passed through as-is without any validation.
***
## Using the Dashboard
You can upload batches, schedule them, and configure auto-retry directly from the Bolna dashboard.
Navigate to **your agent → Batches** tab. You'll see a list of all your past batches along with their status, execution details, and actions like Run Now, Stop, Download, and Delete.
Click **Upload Batch** to get started.
Drag and drop your CSV file or click to browse. After uploading, you'll see how many rows were parsed and how many contacts have valid phone numbers.
In this dialog you can:
* **Select a phone number** to make calls from (Bolna managed or your own)
* **Choose to Run Now or Schedule** the batch for a future date and time
* **Enable auto-retry** for failed calls
* **Set a webhook URL** to receive real-time call status updates
Select **Run Now** to start calls immediately, or click **Schedule** to pick a future date and time. Use the quick-select buttons to schedule 10 minutes, 30 minutes, or 1 hour from now.
Enable **Auto-retry failed calls** to automatically re-attempt calls that didn't connect. You can configure:
* **Retry on**: Select which call outcomes trigger a retry (No Answer, Busy, Failed, Error, Voicemail)
* **Maximum retry attempts**: Set up to 3 retry attempts per contact
* **Retry intervals**: Define increasing delays between attempts (e.g., 30 min, 60 min, 120 min)
Click **Upload this batch** to confirm. Your batch will appear in the batches list with its scheduled time and status.
### Webhook Notifications
You can provide a **Webhook URL** in the upload dialog to receive real-time updates as each call in the batch completes. Bolna sends a POST request to your webhook endpoint with the call's execution data, including the call status, transcript, extracted data, and cost breakdown.
This is useful for syncing call results to your CRM, triggering follow-up workflows, or logging outcomes in real time without polling the API.
If you don't set a webhook, you can still retrieve all results later using the [List Batch Executions API](/docs/api-reference/batches/executions).
***
## Using the Batch API
Upload your CSV file using the [Create Batch API](/docs/api-reference/batches/create):
```bash request theme={"system"}
curl --location 'https://api.bolna.ai/batches' \
--header 'Authorization: Bearer ' \
--form 'agent_id="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"' \
--form 'file=@"/my-first-batch.csv"' \
--form 'from_phone_numbers="+919876543210"' \
--form 'from_phone_numbers="+919876543211"'
```
```json response theme={"system"}
{
"batch_id": "abcdefghijklmnopqrstuvwxyz012345",
"state": "created"
}
```
Use the `batch_id` to schedule via the [Schedule Batch API](/docs/api-reference/batches/schedule). The date and time must be in **ISO 8601** format with timezone:
```bash request theme={"system"}
curl --location 'https://api.bolna.ai/batches/abcdefghijklmnopqrstuvwxyz012345/schedule' \
--header 'Authorization: Bearer ' \
--form 'scheduled_at="2024-03-20T04:05:00+00:00"'
```
```json response theme={"system"}
{
"message": "success",
"state": "scheduled at 2024-03-20T04:10:00+00:00"
}
```
Monitor progress using the [Get Batch API](/docs/api-reference/batches/get_batch):
```bash request theme={"system"}
curl --location 'https://api.bolna.ai/batches/abcdefghijklmnopqrstuvwxyz012345' \
--header 'Authorization: Bearer '
```
```json response theme={"system"}
{
"batch_id": "abcdefghijklmnopqrstuvwxyz012345",
"humanized_created_at": "19 minutes ago",
"created_at": "2024-03-13T14:12:50.596315",
"updated_at": "2024-03-13T14:19:13.115411",
"status": "scheduled",
"scheduled_at": "2024-03-20T04:10:00+05:30"
}
```
After the batch completes, fetch all execution results using the [List Batch Executions API](/docs/api-reference/batches/executions):
```bash request theme={"system"}
curl --location 'https://api.bolna.ai/batches/abcdefghijklmnopqrstuvwxyz012345/executions' \
--header 'Authorization: Bearer '
```
```json response theme={"system"}
[
{
"id": 7432382142914,
"conversation_duration": 123,
"total_cost": 123,
"transcript": "",
"createdAt": "2024-01-23T01:14:37Z",
"updatedAt": "2024-01-29T18:31:22Z",
"usage_breakdown": {
"synthesizerCharacters": 123,
"synthesizerModel": "polly",
"transcriberDuration": 123,
"transcriberModel": "deepgram",
"llmTokens": 123,
"llmModel": {
"gpt-3.5-turbo-16k": {
"output": 28,
"input": 1826
}
}
}
}
]
```
***
## Complete Example
```python batch_script.py theme={"system"}
import asyncio
import os
from dotenv import load_dotenv
import aiohttp
# Load environment variables from .env file
load_dotenv()
# Load from .env
host = "https://api.bolna.ai"
api_key = os.getenv("api_key", None)
agent_id = 'ee153a6c-19f8-3a61-989a-9146a31c7834' # Agent to create batch for
file_path = '/path/of/csv/file'
schedule_time = '2024-06-01T04:10:00+05:30'
from_phone_numbers = ['+919876543210', '+919876543211']
async def schedule_batch(api_key, batch_id, scheduled_at):
print("Scheduling batch for batch_id: {}".format(batch_id))
url = f"{host}/batches/{batch_id}/schedule"
headers = {'Authorization': f'Bearer {api_key}'}
data = {'scheduled_at': scheduled_at}
try:
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, data=data) as response:
response_data = await response.json()
if response.status == 200:
return response_data
else:
raise Exception(f"Error scheduling batch: {response_data}")
except aiohttp.ClientError as e:
print(f"HTTP Client Error: {str(e)}")
except Exception as e:
print(f"Unexpected error: {str(e)}")
async def get_batch_status(api_key, batch_id):
print("Getting batch status for batch_id: {}".format(batch_id))
url = f"{host}/batches/{batch_id}"
headers = {'Authorization': f'Bearer {api_key}'}
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
response_data = await response.json()
if response.status == 200:
return response_data
else:
raise Exception(f"Error getting batch status: {response_data}")
except aiohttp.ClientError as e:
print(f"HTTP Client Error: {str(e)}")
except Exception as e:
print(f"Unexpected error: {str(e)}")
async def get_batch_executions(api_key, batch_id):
print("Getting batch executions for batch_id: {}".format(batch_id))
url = f"{host}/batches/{batch_id}/executions"
headers = {'Authorization': f'Bearer {api_key}'}
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
response_data = await response.json()
if response.status == 200:
return response_data
else:
raise Exception(f"Error getting batch executions: {response_data}")
except aiohttp.ClientError as e:
print(f"HTTP Client Error: {str(e)}")
except Exception as e:
print(f"Unexpected error: {str(e)}")
async def create_batch():
url = f"{host}/batches"
headers = {'Authorization': f'Bearer {api_key}'}
with open(file_path, 'rb') as f:
form_data = aiohttp.FormData()
form_data.add_field('agent_id', agent_id)
form_data.add_field('file', f, filename=os.path.basename(file_path))
# Add multiple from_phone_numbers
for phone in from_phone_numbers:
form_data.add_field('from_phone_numbers', phone)
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, data=form_data) as response:
response_data = await response.json()
if response_data.get('state') == 'created':
batch_id = response_data.get('batch_id')
res = await schedule_batch(api_key, batch_id, scheduled_at=schedule_time)
if res.get('state') == 'scheduled':
check = True
while check:
# Check status every 1 minute
await asyncio.sleep(60)
res = await get_batch_status(api_key, batch_id)
if res.get('status') == 'completed':
check = False
break
if not check:
res = await get_batch_executions(api_key, batch_id)
print(res)
return res
if __name__ == "__main__":
asyncio.run(create_batch())
```
***
## Next Steps
Understand outbound calling concurrency limits
Set up dedicated phone numbers for campaigns
Personalize each call with dynamic data
Automatically retry failed calls
# Calling Guardrails: Control Outbound Call Timing and Rescheduling
Source: https://www.bolna.ai/docs/guides/outbound/calling-guardrails
Restrict when your Bolna Voice AI agent makes outbound calls. Configure allowed calling hours, automatic rescheduling for off-hours calls, and bypass guardrails for urgent calls via API.
Calling guardrails let you restrict when your agent makes outbound calls. Calls outside the allowed window are automatically rescheduled.
***
## How It Works
Toggle on **Outbound call timing restrictions** in the [Call Tab](/docs/agent-setup/call-tab). It is off by default.
Pick a start and end time (e.g., 9:00 AM to 9:00 PM).
When a call is triggered, the system checks the current time in the **recipient's local timezone** (detected from their phone number).
If the time falls inside the allowed window, the call is made immediately.
If the time falls outside the window, the call status is set to `rescheduled` and it is automatically queued for the next allowed start time.
The time window is based on the **recipient's timezone**, not yours. A 9 AM start means 9 AM where the recipient is located.
***
## Configure via API
You can also set calling guardrails through the API when creating or updating an agent. Use `call_start_hour` and `call_end_hour` in 24-hour format.
| Field | Type | Description |
| ----------------- | -------------- | ----------------------------------- |
| `call_start_hour` | integer (0-23) | Start of the allowed calling window |
| `call_end_hour` | integer (0-23) | End of the allowed calling window |
```bash theme={"system"}
curl --request POST \
--url https://api.bolna.ai/v2/agent \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"agent_config": {
"agent_name": "Sales Agent",
"agent_welcome_message": "Hello, how can I help you?",
"calling_guardrails": {
"call_start_hour": 9,
"call_end_hour": 21
},
"tasks": [...]
},
"agent_prompts": {...}
}'
```
Hours use 24-hour format: 0 = midnight, 9 = 9 AM, 17 = 5 PM, 21 = 9 PM. `call_end_hour` must be greater than or equal to `call_start_hour`.
***
## Bypass Guardrails for Urgent Calls
Use the `bypass_call_guardrails` flag to skip time validation for a specific call. When set to `true`, the call goes through immediately regardless of the configured window.
```bash theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"recipient_phone_number": "+14155551234",
"bypass_call_guardrails": true,
"user_data": {...}
}'
```
Time-sensitive alerts that cannot wait
High-priority calls that need immediate delivery
Use the bypass flag responsibly. Calling outside allowed hours may violate local regulations or disturb recipients.
***
## Common Use Cases
Restrict calls to standard business hours so your agent only reaches out during the workday.
```json theme={"system"}
{
"calling_guardrails": {
"call_start_hour": 9,
"call_end_hour": 17
}
}
```
Calls triggered outside this window are automatically rescheduled to 9 AM the next day in the recipient's timezone.
Sales teams often reach prospects in the evening. Extend the window while still avoiding late-night calls.
```json theme={"system"}
{
"calling_guardrails": {
"call_start_hour": 9,
"call_end_hour": 21
}
}
```
During development, use the bypass flag to test call flows at any time without waiting for the allowed window.
```json theme={"system"}
{
"bypass_call_guardrails": true
}
```
***
## In-Call Reschedule Validation
When a recipient asks to reschedule during a call (e.g., "call me back at 10 PM"), the system validates the requested time against the allowed window before scheduling it.
**Validation priority:**
| Priority | Source | Description |
| -------- | ----------------------------- | -------------------------------------------------------------------------------- |
| 1 | **Calling guardrails config** | `call_start_hour` / `call_end_hour` always takes precedence |
| 2 | **Agent prompt** | If no guardrails are set, the LLM reads time restrictions from the system prompt |
| 3 | **Default window** | Falls back to 9 AM to 9 PM if neither is configured |
If the requested time falls outside the allowed window, the reschedule request is rejected entirely. The system does not adjust it to the nearest boundary.
Keep your agent prompt and guardrails config consistent. If the prompt says "call between 10 AM and 6 PM" but guardrails are set to 9 AM to 9 PM, the stricter guardrails config takes priority.
***
## Calling Regulations to Know
Many countries enforce strict rules on when businesses can make outbound calls. Calling guardrails help you stay compliant.
| Region | Regulation | Allowed Hours |
| ------------------ | -------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| **India** | TRAI (Telecom Regulatory Authority of India) | 9:00 AM to 9:00 PM IST. No calls on national Do Not Disturb (DND) registered numbers without consent. |
| **United States** | TCPA (Telephone Consumer Protection Act) | 8:00 AM to 9:00 PM in the recipient's local time. Prior express consent required for automated calls. |
| **European Union** | ePrivacy Directive | Varies by member state. Most restrict unsolicited calls to business hours and require prior consent. |
This is a general reference, not legal advice. Always verify the specific regulations that apply to your use case and region before making outbound calls.
***
## Next Steps
Configure telephony, noise, and call settings
Schedule calls in bulk with CSV uploads
Automatically retry unanswered calls
Full API reference for the call endpoint
# Terminate Bolna Voice AI calls
Source: https://www.bolna.ai/docs/guides/outbound/disconnect-calls
Optimize call lengths with Bolna Voice AI by setting duration limits. Automatically terminate calls exceeding limits for better resource management.
This page has been merged into [Hangup & Disconnect calls](/docs/guides/outbound/hangup-calls). You will be redirected automatically. Update any bookmarks to point to [/hangup-calls](/docs/guides/outbound/hangup-calls).
## What are Call Duration Limits?
Bolna Voice AI lets you set a maximum call duration (in seconds) for automatic termination. Once the limit is reached, the call ends automatically, providing a safety net against unexpectedly long calls.
***
## Why Set Duration Limits?
Prevent unexpectedly long calls from consuming credits
Ensure fair allocation of concurrent call capacity
Protect against edge cases where calls do not end naturally
Better forecast and manage calling expenses
Learn more about [call pricing](/docs/pricing/call-pricing) and [outbound calling concurrency](/docs/pricing/outbound-calling-concurrency).
***
## Compatibility
| Call Type | Support |
| -------------- | ----------------- |
| Outbound calls | ✓ Fully supported |
| Inbound calls | ✓ Fully supported |
***
## Duration Limits vs. Hangup Prompts
| Feature | Duration Limits | Hangup Prompts |
| ----------------- | --------------------------------- | ----------------------------------- |
| **Trigger** | Hard time-based cutoff | Context-aware conversation analysis |
| **Accuracy** | 100%, always triggers at set time | Prompt-dependent, may need tuning |
| **Use case** | Safety net for runaway calls | Natural, intelligent call endings |
| **Configuration** | Set duration in seconds | Write a custom evaluation prompt |
**Use both together** for optimal call management: hangup prompts for natural conversation endings, and duration limits as a safety net to prevent runaway calls.
***
## Related Features
Configure silence detection and hangup prompts
Monitor the full lifecycle of your calls
Understand call termination reasons
# Hangup and Disconnect Bolna Voice AI calls
Source: https://www.bolna.ai/docs/guides/outbound/hangup-calls
Discover methods to disconnect live Bolna Voice AI calls. Implement time-based hangups, custom prompts, and personalized messages for seamless call termination.
## How to Configure Call Hangup
Bolna offers multiple ways to intelligently end voice calls based on user behavior and conversation context.
***
## Hangup Methods
Set a `silence time` threshold (in seconds) for detecting user inactivity. If no audio is detected for the specified duration, the call disconnects automatically, preventing unnecessary call durations.
Add a custom prompt that evaluates whether the conversation is complete. The LLM assesses the conversation context and decides when to end the call.
Since this is prompt-based, it may not be 100% accurate. Tune the prompt based on your use case for best results.
**Example hangup prompt:**
```text hangup prompt example theme={"system"}
You are an AI assistant determining if a conversation is complete. A conversation is complete if:
1. The user explicitly says they want to stop (e.g., "That's all," "I'm done," "Goodbye," "thank you").
2. The user seems satisfied, and their goal appears to be achieved.
3. The user's goal appears achieved based on the conversation history, even without explicit confirmation.
If none of these apply, the conversation is not complete.
```
***
## Personalized Hangup Message
Add a closing message spoken by the agent as the final message before the call ends. This accepts [dynamic context variables](/docs/using-context#custom-variables) using `{}` for a personalized closing statement.
Use variables like `{first_name}` in your hangup message for a personal touch, e.g., *"Thank you , have a great day!"*
***
***
## Call Duration Limits
Set a maximum call duration (in seconds) for automatic termination. Once the limit is reached, the call ends automatically — a safety net against runaway calls.
### Duration limits vs. hangup prompts
| Feature | Duration Limits | Hangup Prompts |
| ----------------- | --------------------------------- | ----------------------------------- |
| **Trigger** | Hard time-based cutoff | Context-aware conversation analysis |
| **Accuracy** | 100%, always triggers at set time | Prompt-dependent, may need tuning |
| **Use case** | Safety net for runaway calls | Natural, intelligent call endings |
| **Configuration** | Set duration in seconds | Write a custom evaluation prompt |
**Use both together**: hangup prompts for natural conversation endings, duration limits as a hard safety net.
***
## Related Features
Monitor call statuses in real time
Understand who ended the call and why
Understand how call duration affects cost
# Make Outbound Calls Using Bolna Voice AI Agents
Source: https://www.bolna.ai/docs/guides/outbound/making-outgoing-calls
Make outbound Voice AI calls with Bolna using default or dedicated phone numbers. Integrate telephony providers and automate calls via dashboard and APIs.
## How to make outbound calls with Bolna?
Bolna Voice AI enables you to make outbound calls in three ways: using Bolna's default phone numbers, purchasing dedicated numbers from Bolna, or connecting your own telephony provider. Choose the option that best fits your use case and brand requirements.
## Can I use Bolna's default numbers for outgoing calls?
By default, you can make outbound calls using Bolna's centralized phone numbers.
| Callee country | Phone number prefix |
| ------------------- | ---------------------------------------------------------- |
| 🇺🇸 United States | Callee will recieve the phone call from `+1` prefix phone |
| 🇬🇧 United Kingdom | Callee will recieve the phone call from `+1` prefix phone |
| 🇦🇺 Australia | Callee will recieve the phone call from `+1` prefix phone |
| 🇮🇳 India | Callee will recieve the phone call from `+91` prefix phone |
| 🌍 Others | Callee will recieve the phone call from `+1` prefix phone |
## How to use your own dedicated phone number?
### Method 1. Purchase a phone number from the [Bolna Dashboard](https://platform.bolna.ai/phone-numbers).
Please refer to a [step by step tutorial for purchasing phone numbers on Bolna](/docs/guides/inbound/buying-phone-numbers).
### Method 2. Connect your Telephony account and use your own phone numbers.
>
}
href="/twilio-connect-provider"
>
Use your own Twilio phone numbers with Bolna
>
}
href="/plivo-connect-provider"
>
Use your own Plivo phone numbers with Bolna
>
}
href="/vobiz-connect-provider"
>
Use your own Vobiz phone numbers with Bolna
>
}
href="/exotel-connect-provider"
>
Use your own Exotel phone numbers with Bolna
***
## How to make outbound calls from the dashboard?
## How to make outbound calls using APIs?
Use [`/call` API](api-reference/calls/make) to place the call to the agent
```curl default-centralized-phone-numbers theme={"system"}
# No need to add `from_phone_number`
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789"
}'
```
```curl dedicated-phone-numbers theme={"system"}
# Add your purchased phone number or your own connected phone number in `from_phone_number` field
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789",
"from_phone_number": "+1987654321"
}'
```
## How to make outbound calls using Zapier & Make.com?
>
}
href="https://zapier.com/apps/bolna/integrations"
>
Connect Zapier to start making outbound calls using Bolna Voice AI agents
>
}
href="https://www.make.com/en/integrations/bolna"
>
Connect Make.com to start making outbound calls using Bolna Voice AI agents
## Next steps
Ready to start making outbound calls? [Set up your first agent](/docs/agent-setup/agent-tab) or explore related features:
* [Batch calling](/docs/guides/outbound/batch-calling) for high-volume campaigns
* [Supported telephony providers](/docs/supported-telephony-providers) for integration options
* [Context variables](/docs/guides/prompting/using-context) to personalize each call
* [Call pricing](/docs/pricing/call-pricing) to understand costs
For receiving calls instead, see how to [handle inbound calls](/docs/guides/inbound/receiving-incoming-calls).
# List of Call Hangup Statuses and Codes in Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/post-call/list-phone-call-hangup-status
Explore all hangup statuses, provider codes, and termination reasons in Bolna Voice AI calls. Debug disconnections and improve reliability.
## Introduction
Every Bolna Voice AI call records metadata about how and why it was terminated. This data is essential for debugging, analytics, and improving call completion rates.
Each call termination includes three fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------- |
| `hangup_by` | Party or system that initiated the hangup (caller, callee, carrier, etc.) |
| `hangup_code` | Numeric code from the telecom provider indicating the specific reason |
| `hangup_reason` | Human-readable description of why the call ended |
***
## Why Hangup Codes Matter
Identify whether disconnections are user-initiated, carrier-caused, or system errors
Track telecom partner performance across providers like Twilio and Plivo
Optimize call handling based on termination patterns and regional issues
Pinpoint geographic routing problems (US, India, Southeast Asia, MENA, etc.)
***
## Hangup Status and Provider Codes
| Hangup By | Description | Provider Codes |
| --------------- | ------------------------------------- | ------------------------------------------------------ |
| **API Request** | Call ended via Bolna API request | `4000`, `4020` |
| **Callee** | Recipient hung up (outbound calls) | `3020`, `4000` |
| **Caller** | Caller ended the call (inbound calls) | `4000` |
| **Carrier** | Terminated by telecom carrier | `2000`, `3000`, `3010`, `3020`, `3040`, `3050`, `3070` |
| **Error** | Ended due to unexpected error | `3080`, `3090`, `3110`, `5010`, `5020`, `7011`, `8011` |
| **Plivo** | Plivo provider disconnected the call | `1010`, `4010`, `5020`, `6000`, `6010`, `6020` |
| **Unknown** | Termination reason unknown | `0` |
| *(empty)* | No hangup reason recorded | *(empty)* |
Code `4000` appears across multiple categories (API, Caller, Callee). The correct interpretation depends on **call direction** (inbound vs outbound) and context.
***
## Hangup Reasons
Bolna provides specific hangup reasons based on your agent configuration:
| Reason | Description |
| --------------------- | ----------------------------------------------------- |
| `inactivity_timeout` | Call ended because the silence threshold was exceeded |
| `llm_prompted_hangup` | Call ended based on custom prompt evaluation |
Configure inactivity timeout and hangup prompts in your [Agent Setup](/docs/agent-setup/agent-tab) to control these behaviors.
Reasons provided by the telephony provider (Twilio, Plivo, etc.):
| Reason | Description |
| -------------------------------------------------------- | ------------------------------------------------------- |
| `Call recipient was busy` | Called party was busy |
| `Call unanswered` | Called party did not answer |
| `Call recipient number invalid` | Invalid or unreachable phone number |
| `Call recipient hung up` | Recipient ended the call |
| `Carrier declined` | Call declined by carrier |
| `Call recipient rejected` | Call rejected by the called party |
| `failed` | Call could not be initiated |
| `Carrier ended because call limit exceeded` | Call terminated due to duration limits |
| `Bolna Error` | Error from Bolna system |
| `Carrier unable to receive media` | Media connection issues |
| `Network Congestion From Carrier` | Network congestion from carrier |
| `End of inputs from Bolna` | Call ended after complete conversation (without prompt) |
| `Carrier unable to reach bolna` | Carrier connectivity issue to Bolna |
| `Carrier ended call because MPC duration limit exceeded` | Multi-party call duration limit reached |
| `Telephony Internal Error` | Internal telephony system error |
| `Carrier Internal Error` | Internal carrier error |
| `Call completed` | Call completed successfully |
| `Call canceled` | Call was canceled |
| `Call ended` | Call terminated normally |
| `Call timed out` | Call exceeded timeout limit |
| `Unknown` | Unknown reason |
***
## Notes on Code Interpretation
Multiple provider codes may map to a single `hangup_by` status depending on network or device behavior. Always check the `hangup_reason` field for additional context.
Codes like `4000` appear in multiple categories. Interpretation depends on **call direction** (inbound vs outbound) and the `hangup_by` field.
Frequent `3010` or `3050` codes in a specific region may indicate local routing or carrier coverage problems. Contact support if you notice persistent regional patterns.
***
## Related Pages
Track the full lifecycle of your calls
Analyze performance across the voice pipeline
Retrieve full execution details programmatically
# List of Call Statuses in Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/post-call/list-phone-call-status
Understand every call status in Bolna Voice AI, from queued to completed. Track successful, unanswered, and failed call states.
## Introduction
Every Bolna Voice AI conversation carries two key fields throughout its lifecycle:
| Field | Purpose |
| --------------- | ---------------------------------------------- |
| `status` | Real-time status of the conversation |
| `error_message` | Explanatory message for errors or failed calls |
***
## Anatomy of a Call
The following diagram shows how a call progresses from initiation to completion:
```mermaid theme={"system"}
flowchart LR
ringing --> no-answer
scheduled --> queued --> initiated --> ringing --> in-progress --> call-disconnected --> completed
ringing --> busy
style scheduled fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style queued fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style initiated fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style ringing fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style in-progress fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style call-disconnected fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
style completed fill:#e0f8e0,stroke:#2e8b57,stroke-width:2px
```
`completed` is the **final** status of every conversation, indicating all post-call processing (recordings, data extraction) is finished.
***
## Call Status Reference
These statuses appear in chronological order during a normal call flow:
| Status | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `scheduled` | Waiting for its `scheduled_at` time to elapse before being queued |
| `queued` | Call received by Bolna and queued for processing |
| `rescheduled` | Call triggered outside allowed hours and automatically rescheduled (requires [call guardrails](/docs/agent-setup/call-tab) configuration) |
| `initiated` | Call initiated from Bolna's servers |
| `ringing` | Call is ringing at the destination |
| `in-progress` | Call answered and conversation is active |
| `call-disconnected` | Call has been disconnected |
| `completed` | All post-call processing finished (recordings, data extraction; may take \~2-3 minutes after disconnect) |
| Status | Description |
| ------------- | ----------------------------------------------- |
| `balance-low` | Insufficient Bolna balance to initiate the call |
| `busy` | Callee was busy |
| `no-answer` | Phone rang but callee did not answer |
| Status | Description |
| ---------- | ------------------------------------------------------------- |
| `canceled` | Call was canceled |
| `failed` | Call failed to connect |
| `stopped` | Call stopped by user or due to no telephony provider response |
| `error` | An error occurred while placing the call |
The payloads for all status events follow the same structure as the [Get Execution API](/docs/api-reference/executions/get_execution) response.
***
## Example Payload
```json {7, 8} theme={"system"}
{
"id": 7432382142914,
"agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"batch_id": "d12abbbe-d16d-4c51-b18c-c7d5c3807962",
"conversation_duration": 123,
"total_cost": 123,
"status": "completed",
"error_message": null,
"answered_by_voice_mail": true,
"transcript": "",
"created_at": "2024-01-23T01:14:37Z",
"updated_at": "2024-01-29T18:31:22Z",
"usage_breakdown": {
"synthesizer_characters": 123,
"synthesizer_model": "polly",
"transcriber_duration": 123,
"transcriber_model": "deepgram",
"llm_tokens": 123,
"llm_model": {
"gpt-3.5-turbo-16k": {
"output": 28,
"input": 1826
},
"gpt-3.5-standard-8k": {
"output": 20,
"input": 1234
}
}
},
"telephony_data": {
"duration": 42,
"to_number": "+10123456789",
"from_number": "+1987654007",
"recording_url": "https://bolna-call-recordings.s3.us-east-1.amazonaws.com/...",
"hosted_telephony": true,
"provider_call_id": "CA42fb13614bfcfeccd94cf33befe14s2f",
"call_type": "outbound",
"provider": "twilio",
"ring_duration": 17,
"post_dial_delay": 1,
"to_number_carrier": "Reliance Jio Infocomm Ltd (RJIL)"
},
"transfer_call_data": {
"provider_call_id": "CA42fb13614bfcfeccd94cf33befe14s2f",
"status": "completed",
"duration": 42,
"cost": 123,
"to_number": "+10123456789",
"from_number": "+1987654007",
"recording_url": "https://bolna-call-recordings.s3.us-east-1.amazonaws.com/...",
"hangup_by": "Caller",
"hangup_reason": "Normal Hangup"
},
"batch_run_details": {
"status": "completed",
"created_at": "2024-01-23T01:14:37Z",
"updated_at": "2024-01-29T18:31:22Z",
"retried": 0
},
"extracted_data": {
"user_interested": true,
"callback_user": false,
"address": "42 world lane",
"salary_expected": "42 bitcoins"
},
"context_details": {},
"extraction_webhook_status": true
}
```
***
## Related Pages
Understand who ended the call and why
Analyze performance across the voice pipeline
Retrieve full execution details programmatically
# Receive Bolna Voice AI call updates
Source: https://www.bolna.ai/docs/guides/post-call/polling-call-status-webhooks
Receive real-time call status updates from Bolna Voice AI using webhooks. Automate workflows, update CRM, and sync data with your systems.
## What are Webhooks?
Webhooks allow you to receive real-time call data from Bolna as call status updates happen. When a call status changes, Bolna sends an HTTP POST request to your server with the execution data.
***
## Setting Up Webhooks
Open your agent and navigate to the **[Extractions Tab](/docs/agent-setup/analytics-tab)**.
In the **"Push all execution data to webhook"** section, enter your webhook endpoint URL.
Click **Save agent** to activate the webhook.
**Your webhook endpoint must be publicly accessible** and able to receive HTTP POST requests. Bolna will POST data to this URL as call status updates.
***
## IP Whitelist
Webhooks are sent from the following IP address. **Whitelist this IP** on your server to ensure you receive all webhook events.
```
13.203.39.153
```
***
## Webhook Payload
The webhook payload is the **same structure as the Raw Call Data** you see in [Call History](/docs/agent-setup/call-history). It matches the [Get Execution API](/docs/api-reference/executions/get_execution) response format.
As call status updates (scheduled → queued → in-progress → completed), Bolna sends POST requests to your webhook with the current execution data.
Test your webhook integration using [webhook.site](https://webhook.site) before implementing a production server.
***
## Pre-call Webhooks
The same payload shape is reused for **pre-call webhooks** — notifications fired by a [custom function tool](/docs/tool-calling/custom-function-calls#pre-call-webhooks) or the [Transfer Call tool](/docs/tool-calling/transfer-calls#pre-call-webhook) *before* the tool runs (for example, to send a transfer reason before a call is transferred).
If a tool sets a `pre_call_webhook_param` without its own `pre_call_webhook_url`, the pre-call webhook is sent to **this agent-level Webhook URL**. The endpoint you configure here may therefore receive in-progress pre-call webhooks in addition to your post-call execution webhooks. Distinguish them by the `in-progress` `status` and the extra fields from the tool's `pre_call_webhook_param`.
Learn more in the [Pre-call Webhooks](/docs/tool-calling/custom-function-calls#pre-call-webhooks) section of the Custom Functions guide, or the [Transfer Call](/docs/tool-calling/transfer-calls#pre-call-webhook) guide.
***
## Use Cases
Automatically update customer records after each call
Build live dashboards with call metrics and analytics
Trigger actions based on call outcomes
Log all call data to your preferred storage system
***
## Call Statuses
Learn about all valid call status types in Bolna Voice AI
***
## Next Steps
Configure post-call extraction and summarization
View raw call data and recordings
Understand the execution data structure
Automate outbound calling campaigns
# Prompting Guide and Best Practices for Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/prompting/prompting-guide
Write effective prompts for Bolna Voice AI agents. Use variables, prompt modules, and best practices to build high-performing conversational agents.
This guide covers how to write effective prompts, use variables and prompt modules, and optimize your agent for performance.
***
## Variables
Variables let you inject dynamic data into your prompts. There are two types:
Defined by you. Passed via the API at call time or from CSV rows during [batch calling](/docs/guides/outbound/batch-calling). Examples: `{customer_name}`, `{order_id}`, `{city}`.
Predefined by Bolna. Available automatically in every call. Examples: `agent_id`, `call_sid`.
### Using Variables in the Prompt Editor
Type `{` in the prompt editor to open the variable dropdown. It shows both **User Variables** and **System Variables**.
With `{`, you can:
* **Select** an existing user or system variable
* **Define a new variable** by typing a name that does not exist yet (e.g., `{appointment_date}`)
### Testing Variables
Any variable you define with `{variable_name}` in your prompt **automatically appears** as an editable input field in the testing section below the prompt. Fill in test values to preview how the prompt behaves before going live.
User variables are passed via the API at call time or from CSV rows during [batch calling](/docs/guides/outbound/batch-calling). System variables like `agent_id` and `call_sid` are filled automatically by Bolna.
***
## Using @ to Insert Modules, Functions, and Variables
Type `@` in the prompt editor to open a dropdown that lets you select and insert:
* **Prompt Modules** - pre-built prompt blocks for common tasks
* **Custom Functions** - functions defined in the [Tools Tab](/docs/agent-setup/tools-tab)
* **Variables** - existing variables already used in your prompt
With `@`, you can only **select** existing items. You cannot create new variables, functions, or modules. To create a new variable, use `{variable_name}` instead.
## Prompt Modules
Prompt modules are pre-built prompt blocks that handle common tasks like email collection, persuasion, objection handling, and more. Insert a module and customize it instead of writing from scratch.
### Browse Modules
Click the **Browse Modules** button in the top-right of the Canvas section to open the full modules library. Browse by category, read what each module does, and insert it into your prompt with one click.
Each module shows:
* **What Prompt Does** - a short description of the module's purpose
* **Prompt** - the full prompt text that will be inserted
* **Insert into editor** - click to add it to your current prompt
### Available Module Categories
| Category | What it contains |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Collection** | Email Collection, Number Collection, Name Collection |
| **Optional** | Persuasion, Variables Reference, Pricing and Plans, Objection Handling, Knowledge Base, Hang Up Prompt, Handover and Escalation, FAQ Block, Extraction Schema, Eligibility Criteria, Compliance Healthcare, Compliance Finance, Closing Branches |
| **Flow** | Outbound Survey, Outbound Lead, Inbound Verification |
| **Sector** | Industry-specific modules |
| **Universal** | General-purpose modules that work across use cases |
Modules are a great starting point. Insert one, then customize the prompt text to fit your specific use case and tone.
***
## Writing Effective Prompts
Begin with a clear, concise prompt. Add details incrementally as you test and refine.
Start with: "You will not speak more than 2 sentences at a time." This keeps responses fast and natural.
| Section | Purpose | Example |
| ---------------- | --------------- | ------------------------------------------- |
| **Personality** | Tone and feel | "warm, perceptive, and results-driven" |
| **Context** | Role background | "You are calling on behalf of Acme Corp..." |
| **Instructions** | Tasks and flow | "Ask for their order number first..." |
| **Guardrails** | Restrictions | "Never discuss competitor products..." |
Prompt engineering takes iteration. If your agent does not follow instructions as expected, refine the prompt step by step rather than rewriting everything at once.
***
## Choosing the Right Agent Type
Natural conversations from a plain-English prompt. Creative and flexible, but requires fine-tuning and costs more.
Full control over exact sentences. Cheaper with no hallucination risk, but conversations are limited to the defined tree.
| | Free Flowing | IVR |
| ---------------------- | -------------- | ------------------------- |
| **Setup** | Write a prompt | Build a conversation tree |
| **Flexibility** | High | Low |
| **Hallucination risk** | Possible | None |
| **Cost** | Higher | Lower |
Start with an [agent template](/docs/agents-library) and customize it. Templates are built to run on default settings.
***
## Optimizing for Performance
For low-latency, high-quality conversations:
| Component | Recommended |
| --------------- | ---------------------------- |
| **LLM** | Azure / gpt-4.1-mini cluster |
| **Voice** | ElevenLabs |
| **Transcriber** | Deepgram |
| **Telephony** | Plivo |
Make sure the voice you choose supports the language you have configured.
Use the [Playground](/docs/agent-setup/agent-tab) to test your agent thoroughly before making live calls. Telephone calling burns credits quickly.
***
## Next Steps
Configure prompts, languages, and advanced settings
Start from a pre-built template
Pass dynamic data into calls with context variables
Writing prompts in native scripts
# Use Dynamic Variables to Personalize Voice AI Calls
Source: https://www.bolna.ai/docs/guides/prompting/using-context
Pass dynamic data into Bolna Voice AI agent prompts using variables. Personalize calls with customer names, order details, and more via the API or CSV batch uploads.
Variables let you inject dynamic data into your agent's prompts at call time. Personalize greetings, reference customer details, and pass metadata without changing the prompt itself.
***
## Variable Types
Predefined by Bolna. Automatically available in every call without any setup.
Defined by you in the prompt with `{variable_name}`. Values are passed via the API or from CSV rows during batch calling.
***
## System Variables
These are injected automatically into every conversation. No setup required.
| Variable | Description |
| -------------- | --------------------------------------------------------------------------------------------- |
| `agent_id` | Unique ID of the agent |
| `execution_id` | Unique ID of the conversation or call |
| `call_sid` | Unique ID of the phone call (Twilio, Plivo, etc.) |
| `from_number` | Phone number that **initiated** the call |
| `to_number` | Phone number that **received** the call |
| `current_date` | Current date in the caller's timezone |
| `current_time` | Current time in the caller's timezone |
| `timezone` | Timezone name per [tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) |
**Inbound calls:** `from_number` = caller, `to_number` = your agent
**Outbound calls:** `from_number` = your agent, `to_number` = recipient
Current date and time are automatically appended to the system prompt. You can also reference them as variables directly in your prompt for more control over placement.
***
## User Variables
Define your own variables by wrapping a name in `{}` in your prompt. Type `{` in the [Agent Tab](/docs/agent-setup/agent-tab) prompt editor to open the variable dropdown, which shows both existing user variables and system variables.
With `{`, you can:
* **Select** an existing user or system variable
* **Define a new variable** by typing a name that does not exist yet (e.g., `{appointment_date}`)
You can also type `@` in the prompt editor to insert existing variables, [prompt modules](/docs/prompting-guide#prompt-modules), or [custom functions](/docs/tool-calling/custom-function-calls). Unlike `{`, `@` cannot create new variables.
Any variable you define **automatically appears** as a test input field in the [prompt variables for testing](/docs/agent-setup/agent-tab#prompt-variables-for-testing) section.
***
## Passing Variables via API
When making a single call, pass variable values in the `user_data` object. Every key in `user_data` maps to a `{variable_name}` in your prompt.
```
Hi {customer_name}, this is Sam from {company_name}.
I see you contacted us on {last_contacted_on} about your order for {product_name}.
Your call reference is {call_sid}.
```
```bash theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789",
"from_phone_number": "+1987654007",
"user_data": {
"customer_name": "Caroline",
"company_name": "Acme Corp",
"last_contacted_on": "4th August",
"product_name": "Pearl shampoo bar"
}
}'
```
```
Hi Caroline, this is Sam from Acme Corp.
I see you contacted us on 4th August about your order for Pearl shampoo bar.
Your call reference is PDFHNEWFHVUWEHC.
```
`call_sid` is a system variable and gets filled automatically.
### Setting the Timezone
Pass `timezone` in `user_data` to ensure accurate date and time values:
```bash theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789",
"user_data": {
"timezone": "America/New_York"
}
}'
```
***
## Passing Variables via CSV (Batch Calling)
When using [batch calling](/docs/guides/outbound/batch-calling), upload a CSV file where each row is a call. The `contact_number` column is required. All other columns are treated as user variables and passed to the agent automatically.
```csv theme={"system"}
contact_number,customer_name,company_name,product_name,last_contacted_on
+11231237890,Bruce Wayne,Wayne Enterprises,Batsuit,3rd March
+91012345678,Bruce Lee,Dragon Corp,Training Kit,15th June
+44999999007,James Bond,MI6,Gadget Pack,1st January
```
Each column name maps directly to a `{variable_name}` in your prompt. For the first row, `{customer_name}` becomes "Bruce Wayne", `{product_name}` becomes "Batsuit", and so on.
CSV columns are passed as-is without validation. Make sure column names match the variable names in your prompt exactly.
***
## Next Steps
Configure prompts and test variables in the editor
Variable syntax, prompt modules, and best practices
Upload CSVs to make calls at scale with variables
Full API docs for the Make Call endpoint
# Using Extractions in Bolna Dashboard
Source: https://www.bolna.ai/docs/guides/prompting/using-extractions
Learn how to create and manage extraction templates in the Bolna dashboard to capture structured data from call transcripts.
## What are Extractions?
Extractions allow you to automatically capture structured data from call transcripts. Organize extractions into categories and define custom questions to extract specific information like lead quality, appointment details, customer sentiment, and more.
Configuring extractions via the API instead of the dashboard? The new Extractions feature is powered by the [Dispositions API](/docs/api-reference/dispositions/overview).
***
## Getting Started with Extractions
### Step 1: Access the Extractions Tab
Navigate to the **Extractions** tab in your agent configuration to find the **Extractions** section.
***
## Creating Categories
Categories help you organize related extractions together. For example, "Agent Handover", "Visit Details", or "Lead Qualification".
Start by creating a category to organize your extractions.
Choose a descriptive name like "Agent Handover" or "Visit Details".
Your category is now ready for extractions.
***
## Creating Extractions
Within each category, you can create multiple extraction templates to capture different data points.
### Extraction Fields
A descriptive name for the extraction (e.g., "Call Outcome", "Customer Sentiment", "Agent Handover Needed").
This name will appear in your extraction results and webhooks.
Instructions that guide the LLM on what to extract from the transcript.
**Example prompts:**
```
What was the outcome of the call? Was the customer satisfied?
Did the agent answer all questions?
```
```
Determine whether an agent handover is required based on the
customer's statements.
```
You can use variables like `{name}`, `{candidate_name}`, `{email}` to reference call-specific data from recipient\_data.
Choose how the LLM should structure its response:
**Free Text**
* LLM generates a custom answer based on conversation context
* Best for open-ended questions and detailed responses
* Example: "Describe the customer's main concern"
**Pre-defined**
* LLM selects from predefined options you configure
* Best for categorical data and structured responses
* Example: Lead quality (hot/warm/cold), Yes/No questions
When creating extractions with Free Text enabled, you can constrain the response format using the **Expected Format** dropdown:
| Format | Description | Example Value |
| ------------------ | ------------------------------ | ---------------------------------------- |
| **Text** (default) | Any free-form text | `"Customer was satisfied with the demo"` |
| **Timestamp** | ISO 8601 date/time | `"2026-04-08T14:30:00"` |
| **Numeric** | Integer or decimal number | `"42"`, `"3.14"` |
| **Boolean** | Exactly `true` or `false` | `"true"` |
| **Email** | Valid email address | `"user@example.com"` |
| **Custom Regex** | Matches a custom regex pattern | `"1234567890"` |
When **Custom Regex** is selected, two additional fields appear:
* **Pattern (required)** — The regex the response must match (e.g., `^\d{10}$`)
* **Description (optional)** — Human-readable label (e.g., "10-digit phone number")
Responses are automatically validated against the expected format. Invalid responses are flagged but preserved — the original response is still returned so no data is lost.
Select the LLM model for extraction processing.
Default: `gpt-4.1-mini` (recommended for most use cases)
***
## Answer Types Explained
### Free Text Extractions
Use free text when you want the LLM to generate custom responses based on the conversation.
**Best for:**
* Summarizing customer concerns
* Extracting reasons or explanations
* Capturing qualitative feedback
* Open-ended questions
**Example:**
* Name: "Customer Concern"
* Prompt: "Summarize the main issue the customer raised during the call"
* Answer Type: Free Text
***
### Pre-defined Extractions
Use pre-defined options when you want structured, categorical responses.
**Best for:**
* Yes/No questions
* Status classifications
* Lead scoring
* Outcome categorization
#### Configuring Pre-defined Answers
Each answer option consists of:
1. **Answer Value** - The value to return (e.g., "Yes", "No", "hot", "warm", "cold")
2. **Condition** - Instructions for when to select this answer
**Example: Agent Handover Detection**
**Answer 1:**
* Value: `Yes`
* Condition: `yield if any one of the triggers for handover are satisfied`
**Answer 2:**
* Value: `No`
* Condition: `yield if none of the triggers for handover are satisfied`
Conditions support variables like `{name}`, `{candidate_name}` for dynamic evaluation based on recipient data.
***
## Managing Extractions
### Edit an Extraction
1. Click the **edit icon** (pencil) on any extraction card
2. Modify the name, prompt, answer type, or model
3. Click **Save Changes**
### Delete an Extraction
1. Click the **delete icon** (trash) on any extraction card
2. Confirm deletion
***
## Testing Extractions
Before deploying extractions to production, test them against sample or real transcripts to validate accuracy and refine your prompts.
### How to Test Extractions
In the Extractions section, click the **Test Extractions** button to open the testing modal.
Select from sample transcripts (Sales Call, Support Call, Appointment) or provide your own:
* **Paste** - Paste a transcript directly into the text area
* **Import** - Upload a transcript file
Click the **Run Test** button to process the transcript through all your extraction templates.
View extraction results organized by category. Each extraction shows:
* **SUBJECTIVE** - Free text responses generated by the LLM
* **OBJECTIVE** - Pre-defined values selected by the LLM
### Understanding Test Results
Extraction results are displayed hierarchically by category. Each extraction shows its full result including confidence and reasoning:
```
CATEGORY NAME
├─ EXTRACTION NAME
│ ├─ SUBJECTIVE: [Free text response]
│ ├─ OBJECTIVE: [Pre-defined value or null]
│ ├─ CONFIDENCE: 0.92 (High)
│ ├─ REASONING (SUBJECTIVE): [LLM explanation]
│ └─ REASONING (OBJECTIVE): [LLM explanation]
```
**Example:**
```
VISIT DETAILS
├─ RESCHEDULED VISIT TIME
│ ├─ SUBJECTIVE: 14:00
│ ├─ OBJECTIVE: null
│ └─ CONFIDENCE: 0.89 (High)
├─ RESCHEDULED VISIT DATE
│ ├─ SUBJECTIVE: 24/03/2026
│ ├─ OBJECTIVE: null
│ └─ CONFIDENCE: 0.91 (High)
```
`null` appears when an extraction type isn't configured or no matching value is found. Low-confidence results (below 0.5) are worth reviewing manually.
### Testing Best Practices
Test your extractions against various conversation types to ensure they work across different scenarios.
If using both free text and pre-defined answers, verify both are extracting correctly.
If results aren't accurate, edit your extraction prompts and conditions, then test again.
For production validation, test with actual call transcripts from your agent.
### Sample Transcripts
The Test Extractions interface provides three sample transcript types:
* **Sales Call** - Conversation about products and services
* **Support Call** - Customer support interaction
* **Appointment** - Scheduling and booking conversation
These samples help you quickly validate extraction logic without needing your own transcripts.
***
## Working with Categories
### Rename a Category
Click the **edit icon** next to the category name to rename it.
### Delete a Category
Click the **delete icon** next to the category name. This will remove the category and all extractions within it.
Deleting a category is permanent and cannot be undone. All extractions in the category will be deleted.
### Add Extractions to a Category
Click **Add Extraction to \[Category Name]** button at the bottom of each category section.
***
### Extraction Output Format
Each extraction result is a JSON object with the following fields:
| Field | Type | Description |
| ---------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `subjective` | `string \| null` | Free Text LLM response. `""` if no relevant info found; `null` if `is_subjective` is `false` |
| `objective` | `string \| null` | Selected Pre-defined value. `null` if not configured or no condition matched |
| `confidence` | `float` | LLM confidence score from `0.0` to `1.0` |
| `confidence_label` | `string` | Human-readable label: `"High"` (≥ 0.8), `"Medium"` (≥ 0.5), or `"Low"` (\< 0.5) |
| `reasoning_subjective` | `string \| null` | LLM's reasoning for the free-text response. `null` if `is_subjective` is `false` |
| `reasoning_objective` | `string \| null` | LLM's reasoning for the pre-defined selection. `null` if `is_objective` is `false` |
| `validation` | `object \| null` | Post-LLM validation result for typed free-text responses. `null` for plain `text` type or when `is_subjective` is `false` |
Results are nested by category and extraction name under `extracted_data`:
```json theme={"system"}
{
"extracted_data": {
"Category Name": {
"Extraction Name": {
"subjective": "Free text response from LLM",
"objective": "Pre-defined value or null",
"confidence": 0.92,
"confidence_label": "High",
"reasoning_subjective": "LLM's explanation for the free-text answer",
"reasoning_objective": "LLM's explanation for the selected option",
"validation": null
}
}
}
}
```
**Complete Example:**
```json theme={"system"}
{
"extracted_data": {
"Lead Quality": {
"Call Outcome": {
"subjective": "Customer expressed strong interest and asked about enterprise pricing options.",
"objective": "interested",
"confidence": 0.92,
"confidence_label": "High",
"reasoning_subjective": "Customer asked about enterprise pricing and requested a follow-up demo.",
"reasoning_objective": "Customer explicitly expressed interest and agreed to a next step.",
"validation": null
}
},
"Contact Info": {
"Customer Email": {
"subjective": "user@example.com",
"objective": null,
"confidence": 0.95,
"confidence_label": "High",
"reasoning_subjective": "Customer clearly provided their email address during the call.",
"reasoning_objective": null,
"validation": {
"is_valid": true,
"expected_type": "email"
}
}
},
"Agent Handover": {
"Agent Handover Needed": {
"subjective": "",
"objective": "No",
"confidence": 0.88,
"confidence_label": "High",
"reasoning_subjective": null,
"reasoning_objective": "Customer did not request to speak with a human agent at any point.",
"validation": null
}
}
}
}
```
### Understanding the Output
Contains the **free text response** generated by the LLM based on the extraction prompt.
* Returns a string with the LLM's analysis
* Empty string `""` if no information found
* `"null"` (string) if extraction wasn't applicable
**Example:** `"The customer expressed interest and agreed to a demo appointment"`
Contains the **pre-defined value** selected by the LLM from configured answer options.
* Returns the configured answer value (e.g., `"Yes"`, `"No"`, `"hot"`, `"warm"`, `"cold"`)
* `null` if pre-defined answers aren't configured
* `null` if no matching condition was satisfied
**Example:** `"No"` (from answer options "Yes" or "No")
Every extraction result includes a **confidence score** explaining how certain the LLM was about its answer.
| Field | Type | Description |
| ------------------ | ------ | --------------------------------------------------------- |
| `confidence` | float | Score from `0.0` to `1.0` — higher means more certain |
| `confidence_label` | string | `"High"` (≥ 0.8), `"Medium"` (≥ 0.5), or `"Low"` (\< 0.5) |
Use these to build confidence-based routing — for example, flag `"Low"` results for human review.
Brief explanations from the LLM explaining *why* it produced each answer.
* `reasoning_subjective` — present when `is_subjective` is `true`; explains the free-text response
* `reasoning_objective` — present when `is_objective` is `true`; explains the pre-defined selection
Both are `null` when their respective answer type is disabled. Useful for auditing unexpected results.
Present when a Free Text extraction has an **Expected Format** constraint (anything other than plain `text`). Contains:
```json theme={"system"}
{
"is_valid": true,
"expected_type": "email"
}
```
* `is_valid: false` means the LLM's response didn't match the expected format — the original response is still returned in `subjective` so no data is lost
* `null` for plain `text` type or when `is_subjective` is `false`
Different empty states have different meanings:
| Value | Meaning |
| ------------------- | -------------------------------------------- |
| `""` (empty string) | No relevant information found in transcript |
| `"null"` (string) | Extraction wasn't applicable to this call |
| `null` (JSON null) | Field not configured OR no condition matched |
## Accessing Extraction Results
Extracted data is part of the call execution result and is available as `extracted_data` in every execution response. You can access it in the following ways:
Fetch any execution by ID using `GET /executions/{execution_id}` or list all executions for an agent using `GET /v2/agent/{agent_id}/executions`. The `extracted_data` field is returned in the response body.
```json theme={"system"}
{
"execution_id": "abc123",
"status": "completed",
"transcript": "...",
"extracted_data": {
"Agent Handover": {
"Agent Handover Needed": {
"subjective": "Customer asked to speak with a human.",
"objective": "Yes",
"confidence": 0.95,
"confidence_label": "High",
"reasoning_subjective": "Customer explicitly said they want to talk to a person.",
"reasoning_objective": "Customer requested a human agent.",
"validation": null
}
}
}
}
```
If you've configured a webhook, the `extracted_data` field is included in the post-call webhook payload, the same execution object sent to your endpoint after every call.
Open any call record from the **Call History** tab in the dashboard to see extraction results alongside the transcript and call summary.
For batch campaigns, `extracted_data` is returned in each execution record when fetching batch execution results.
## Common Use Cases
| Use Case | What to extract | What it enables |
| ----------------------- | ------------------------------------------ | ------------------------------------------------------------------ |
| **Agent Handover** | Did the caller ask for a human? | Route to a live agent in real time without manual review |
| **Lead Scoring** | Budget, timeline, decision-maker | Push hot leads to your CRM or Slack before the rep hangs up |
| **Appointment Sync** | Confirmed date, time, location | Write bookings to Google Calendar or Cal.com automatically |
| **Churn Prevention** | Sentiment, unresolved complaints | Flag unhappy customers and trigger a follow-up workflow |
| **Compliance Auditing** | Disclaimer read, consent given | Structured Yes/No record across thousands of calls |
| **Call Intelligence** | Objections, outcomes, cancellation reasons | Spot trends and measure what's working without reading transcripts |
***
## Best Practices
1. **Write specific prompts :** Clearly define what to capture and how to interpret the conversation. Avoid vague or multi-part instructions.
2. **Pick the right answer type :** Use Pre-defined for categorical data like Yes/No or status fields, and Free Text for open-ended responses.
3. **Keep extractions focused :** Split complex logic into multiple simple extractions rather than one long prompt.
4. **Test before deploying :** Run your extractions against real or sample transcripts to catch issues early.
***
## Next Steps
Access extractions programmatically
Receive extraction data in real-time
View extraction results for past calls
Configure other post-call tasks
# Exotel Integration with Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/telephony/exotel
Connect Exotel with Bolna Voice AI for inbound and outbound calling. Configure multilingual phone automation for India & global markets. Complete setup guide.
## Understanding Exotel Integration with Bolna Voice AI
Exotel serves as a powerful telephony infrastructure provider that seamlessly integrates with Bolna's Voice AI platform. This integration enables businesses to deploy intelligent conversational AI agents that can handle both incoming and outgoing phone calls with natural language understanding and multilingual capabilities.
When you connect Exotel to Bolna, you gain full control over your telephony operations while leveraging advanced AI-powered voice automation. The integration allows you to maintain your existing Exotel phone numbers and infrastructure while adding sophisticated AI capabilities for customer engagement, support automation, sales outreach, and appointment scheduling.
## Getting Started with Exotel on Bolna
Configure AI agents to initiate automated phone calls through your Exotel numbers
Set up AI agents to answer and handle inbound calls on your Exotel phone lines
Link your existing Exotel account credentials to Bolna for seamless integration
## Why use Exotel with Bolna?
Exotel offers several advantages:
* **Cost-effective**: Enjoy competitive domestic calling rates tailored for Indian businesses.
* **Reliable infrastructure**: Built on robust Indian telecom networks for high uptime and clear call quality.
* **Pan-India and global reach**: Seamlessly connect with customers across India and in multiple countries.
* **Easy integration**: Set up quickly and integrate effortlessly with the Bolna Voice AI platform.
For high-volume calling needs, consider using [batch calling](/docs/guides/outbound/batch-calling) to scale efficiently. Compare Exotel with [Plivo](/docs/plivo) to choose the best provider for your needs.
# Connect Your Exotel Account to Bolna
Source: https://www.bolna.ai/docs/guides/telephony/exotel-connect-provider
Securely connect your Exotel account with Bolna. Enable your Voice AI agents to utilize Exotel phone numbers for managing inbound and outbound calls.
## Connecting Your Exotel Account for AI-Powered Calling
Linking your personal or business Exotel account to Bolna gives you complete ownership and control over your telephony infrastructure. Once connected, all voice calls initiated by Bolna's AI agents will route through your Exotel account, utilizing your provisioned phone numbers and billing directly to your Exotel subscription.
This approach ensures transparency in call costs, maintains your existing phone number reputation, and provides full visibility into call analytics through both Bolna and Exotel dashboards.
## Step-by-Step Integration Process
### Step 1: Access the Providers Configuration Panel
Begin by logging into your Bolna platform account and locating the `Providers` section in the left navigation menu. Click the **Exotel connect button** to initiate the account linking process.
### Step 2: Enter Your Exotel Authentication Credentials
You'll need to provide your Exotel API credentials, which include your `API_KEY`, `API_TOKEN`, `ACCOUNT_SID`, `DOMAIN` and `PHONE_NUMBER`. These credentials can be found in your Exotel account dashboard under API settings.
These credentials allow Bolna to securely communicate with Exotel's API on your behalf.
### Step 3: Finalize the Connection
After entering your credentials click the **connect button** to establish the secure link between your Exotel account and Bolna's Voice AI platform. The system will validate your credentials and establish the integration.
### Step 4: Verify Successful Integration
Upon successful connection, you'll receive a confirmation message indicating that your Exotel account is now active on Bolna.
From this point forward, all AI-powered voice calls initiated through Bolna cab be utilized with your Exotel infrastructure, phone numbers, and account balance. You can now configure your AI agents to make outbound calls or handle inbound calls using your Exotel telephony resources.
# Make Outbound Calls with Exotel and Bolna
Source: https://www.bolna.ai/docs/guides/telephony/exotel-outbound-calls
Set up & run outbound calling campaigns in India with Bolna Voice AI on Exotel. Follow this step-by-step guide for dashboard setup and seamless API integration.
## Launching Outbound Calls Through the Bolna Dashboard
### Step 1: Access Your Bolna Platform Account
Navigate to [https://platform.bolna.ai](https://platform.bolna.ai) and authenticate using your registered account credentials.
### Step 2: Configure Exotel as Your Telephony Provider
Within your agent configuration settings, select `Exotel` from the available call provider options. This designation tells Bolna to route all outbound calls through Exotel's telephony infrastructure.
### Step 3: Initiate Calls to Your Target Recipients
Enter the phone numbers of your intended call recipients in the designated input field. Bolna will automatically initiate calls through your Exotel connection, engaging with each recipient using the voice agents you've configured.
To utilize your own dedicated Exotel phone numbers for outbound calling, you must first establish a connection between your Exotel account and Bolna. Detailed instructions for linking your Exotel account are available in the [providers configuration guide](/docs/exotel-connect-provider).
## Programmatic Outbound Calling Using Bolna APIs
For developers building custom applications or integrating voice AI into existing systems, Bolna provides comprehensive REST APIs for programmatic call management.
### Step 1: Obtain Your API Authentication Key
1. Generate and save your [Bolna API Key](/docs/api-reference/introduction#steps-to-generate-your-api-key)
### Step 2: Configure Agent with Exotel Provider
When creating or updating your Bolna agent through the [`/create` Agent API](/docs/api-reference/agent/create), specify `exotel` as both the input and output provider within your tools configuration.
```create-agent.json theme={"system"}
...
...
"tools_config": {
"output": {
"format": "wav",
"provider": "exotel"
},
"input": {
"format": "wav",
"provider": "exotel"
},
"synthesizer": {...},
"llm_agent": {...},
"transcriber": {...},
"api_tools": {...}
}
...
...
```
### Step 3: Trigger Outbound Calls Programmatically
Execute the [`/call` API endpoint](api-reference/calls/make) to initiate outbound calls to your target recipients. Include your agent ID and the recipient's phone number in E.164 international format. The API will return a call ID that you can use to track call status and retrieve conversation analytics.
```call.json theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "fd3d9b56-0742-4a39-aaac-50dec1f37d00",
"recipient_phone_number": "+919876543210"
}'
```
# Bolna Voice AI Integrations
Source: https://www.bolna.ai/docs/guides/telephony/integrations
Integrate Bolna Voice AI with tools like Twilio, Plivo, OpenAI, ElevenLabs, Deepgram, and Zapier to enable seamless voice automation and workflows.
## Telephony Integrations
>
}
href="/twilio-connect-provider"
>
Connect your Twilio phone numbers with Bolna
>
}
href="/plivo-connect-provider"
>
Connect your Plivo phone numbers with Bolna
>
}
href="/exotel-connect-provider"
>
Connect your Exotel phone numbers with Bolna
>
}
href="/vobiz-connect-provider"
>
Connect your Vobiz phone numbers with Bolna
## Model Integrations
>
}
href="https://platform.bolna.ai/auth/openai"
>
Connect your OpenAI account with Bolna
>
}
href="https://github.com/deepseek-ai/awesome-deepseek-integration/?tab=readme-ov-file#others"
>
Connect your Deepseek account with Bolna
>
}
href="https://platform.bolna.ai/auth/elevenLabs"
>
Connect your ElevenLabs account with Bolna
>
}
href="https://platform.bolna.ai/auth/cartesia"
>
Connect your Cartesia account with Bolna
>
}
href="https://platform.bolna.ai/auth/deepgram"
>
Connect your Deepgram account with Bolna
>
}
href="https://platform.bolna.ai/auth/azure"
>
Connect your Azure account with Bolna
## External Integrations
>
}
href="https://zapier.com/apps/bolna/integrations"
>
Connect your Zapier account with Bolna
>
}
href="https://www.make.com/en/integrations/bolna"
>
Connect your Make.com account with Bolna
>
}
href="https://platform.bolna.ai/auth/calcom"
>
Connect your Cal.com account with Bolna
>
}
href="https://viasocket.com/integrations/bolna"
>
Use Bolna as a node in your viaSocket workflows
# Serving Twilio On Prem
Source: https://www.bolna.ai/docs/guides/telephony/on-prem-twilio
Enterprises can now connect their Twilio infrastructure securely to Bolna
Bolna will provide access to docker image for hosting a Twilio application which you can deploy and connect with your Twilio account in your own infrastructure (AWS/GCP/DigitalOcean etc.)
## Login to docker
Use the docker login command to access the docker images: `docker login -u bolnahq`.
You will be given a password for authentication.
## Inject Twilio credentials as environment variables
Create a `.env` file:
```.env theme={"system"}
# Bolna API and Websocket hosts
BOLNA_HOST=https://api.bolna.ai
BOLNA_WS_URL=wss://ws.bolna.dev
# Twilio credentials
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_API_KEY=
TWILIO_API_SECRET=
# Twilio external auth URL
TWILIO_CREDENTIALS_FROM_URL=
# Call recording enable/disable
RECORD_CALL=True
RECORDING_CHANNELS=dual
```
Bolna will never have access to the recordings.
This `.env` file will be used to inject the variables while running the docker image.
## Starting docker
The following example illustrates on how to start the docker image using docker compose using the `.env` file in the same directory. You can have any other method of starting docker.
```docker-compose.yml theme={"system"}
services:
twilio-app:
image: bolnahq/twilio-app:1.0.0
ports:
- "8081:5000"
env_file:
- .env
```
The `twilio-app` service uses the `bolnahq/twilio-app:1.0.0` image which runs on `5000` port.
It then binds the container and the host machine to the exposed port, `8081`. You can specify any other port to bind the container with the host machine.
# Enhance Call Capabilities with Bolna's Plivo Integration
Source: https://www.bolna.ai/docs/guides/telephony/plivo
Integrate Plivo with Bolna to manage outbound & inbound calls for India. Access setup guides for seamless Voice AI agent communication using your Plivo numbers.
## What is Plivo integration in Bolna?
Plivo is a cost-effective telephony provider supported by Bolna Voice AI. By integrating Plivo with Bolna, you can make outbound calls, receive inbound calls, and use your own Plivo account for complete control over your phone numbers and calling infrastructure.
Learn more about [supported telephony providers](/docs/supported-telephony-providers) or [purchase phone numbers](/docs/guides/inbound/buying-phone-numbers) directly through Bolna.
## How to get started with Plivo
Bolna agents make phone calls using Plivo numbers
Bolna agents receive phone calls on Plivo numbers and answers them
Use your own Plivo account with Bolna
## Why use Plivo with Bolna?
Plivo offers several advantages:
* **Cost-effective**: Competitive international calling rates
* **Reliable infrastructure**: Good uptime and call quality
* **Global coverage**: Support for calls in many countries
* **Easy integration**: Seamless setup with Bolna platform
For high-volume calling needs, consider using [batch calling](/docs/guides/outbound/batch-calling) to scale efficiently. Compare Plivo with [Twilio](/docs/twilio) to choose the best provider for your needs.
# Link Your Plivo Account to Bolna for Voice AI
Source: https://www.bolna.ai/docs/guides/telephony/plivo-connect-provider
Securely connect your Plivo account with Bolna. Enable your Voice AI agents to utilize Plivo phone numbers for managing inbound and outbound calls.
## Use your own Plivo account to make outbound calls
You can connect your own Plivo account and start using it on Bolna. All calls initiated from Bolna will be from your own Plivo account and use your own Plivo phone numbers.
1. Navigate to `Providers` tab from the left menu bar & Click **Plivo connect button**.
2. Fill in the required details.
3. Save details by clicking on the **connect button**.
4. You'll see that your Plivo account was successfully connected. All your calls will now go via your own Plivo account and phone numbers.
# Using Plivo for inbound calls
Source: https://www.bolna.ai/docs/guides/telephony/plivo-inbound-calls
Make Bolna agents answer your inbound calls using Plivo
## Make inbound calls from dashboard
1. Navigate to the agent and copy the inbound URL displayed
2. Next, you'll need to create a `XML Application` in [Plivo Console](https://console.plivo.com/voice/applications/) as illustrated here:
[https://www.plivo.com/docs/voice/use-cases/receive-incoming-calls/node#xml-assign-a-plivo-number-to-your-application](https://www.plivo.com/docs/voice/use-cases/receive-incoming-calls/node#xml-assign-a-plivo-number-to-your-application)
3. Paste the copied link in Step#1 above in following text boxes and save your Application. Note the Application Name:
* `Primary Answer URL`
* `Hangup URL`
4. Go to your `Active Numbers` and select the phone number for which you want to assign the Bolna AI. Select the XML Application in this step and save it by clicking on `Update Number`.
5. Voila! All set. Now try placing a call to the selected Plivo phone number and have your conversation with Bolna AI
# Initiate Outbound Calls via Plivo with Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/telephony/plivo-outbound-calls
Configure Bolna Voice AI agents to make outbound calls through Plivo. Learn to set up calls using the dashboard and APIs for effective outreach.
## Making outbound calls from dashboard
1. Login to the dashboard at [https://platform.bolna.ai](https://platform.bolna.ai) using your account credentials
2. Choose `Plivo` as the Call provider for your agent and save it
3. Start placing phone calls by providing the recipient phone numbers.
Bolna will place the calls to the provided phone numbers.
You can place calls using your own custom Plivo phone numbers only if you've connected your Plivo account.
You can read more on how to connect your Plivo account [here](/docs/providers).
## Making outbound calls Using APIs
1. Generate and save your [Bolna API Key](/docs/api-reference/introduction#steps-to-generate-your-api-key)
2. Set your agent `input` and `output` tools as `plivo` while using [`/create` Agent API](/docs/api-reference/agent/create)
```create-agent.json theme={"system"}
...
...
"tools_config": {
"output": {
"format": "wav",
"provider": "plivo"
},
"input": {
"format": "wav",
"provider": "plivo"
},
"synthesizer": {...},
"llm_agent": {...},
"transcriber": {...},
"api_tools": {...}
}
...
...
```
3. Use [`/call` API](api-reference/calls/make) to place the call to the agent
```call.json theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789"
}'
```
# Setup Exotel with Bolna for Inbound Calling
Source: https://www.bolna.ai/docs/guides/telephony/setup-exotel-app-for-inbound-calls
Create, setup and configure Exotel Application with your account for enabling Inbound calls with Bolna Voice AI Platform
## How to Create an Exotel App for Inbound Calls
To enable inbound calling functionality with Bolna's Voice AI agents through Exotel, you'll need to create and configure a dedicated app in your Exotel dashboard. This app serves as the communication bridge between Bolna's AI voice agents and Exotel's telephony infrastructure for making incoming calls.
### Understanding Exotel Apps for Voice AI Integration
An Exotel app is a customizable workflow that defines how your inbound calls are handled, routed, and connected. For Bolna integration, you'll configure a specialized app that connects the Voicebot functionality with Bolna's API endpoints, enabling seamless AI-powered inbound calling capabilities.
### Prerequisites for Creating Your Exotel Inbound App
Before you begin, ensure you have:
* An active Exotel account with API access
* Access to your Exotel dashboard at [my.exotel.com](https://my.exotel.com/)
### Step 1: Access the Exotel App Bazaar
Navigate to your [Exotel dashboard](https://my.exotel.com/) and locate the **App Bazaar** section under the **Manage** menu. The App Bazaar is where you'll create and configure custom apps for your telephony workflows.
### Step 2: Create a New App for Bolna Integration
Click the **Create** button to start building your new app. Give it a descriptive name such as **"Bolna Inbound"** (you can customize this name based on your preference for easy reference in your dashboard).
### Step 3: Add the Voicebot App Component
Drag the **Voicebot** app from the available components and drop it into the **"Drop app here"** box. This is the primary component that will handle the AI voice interaction.
### Step 4: Configure the Voicebot Component
Once dropped, a configuration popup will appear for the Voicebot settings:
* In the URL field, copy and paste the following Bolna API endpoint:
```
https://api.bolna.ai/inbound_call
```
* Enable the **"Record this"** checkbox to record your inbound calls for quality assurance and compliance purposes
### Step 5: Configure App for Transfer calling
Within the Voicebot popup, you'll notice another **"Drop app here"** section at the bottom. This is where you'll configure the call connection logic.
Drag and drop the **Connect** voice app into this designated area. This component manages the actual phone call connection and routing.
When the Connect app popup opens, you'll need to specify how connection parameters are controlled:
1. Look for the section titled **"How do you want to control your Connect params?"**
2. Select the option: **"Configure parameters dynamically by providing a URL"**
3. In the **Primary URL** field, copy and paste the following Bolna API endpoint:
```
https://api.bolna.ai/exotel_connect_transfer
```
This configuration allows Bolna to dynamically control call parameters while transferring a live call.
### Step 6: Save Your Exotel App Configuration
Click the **Save** button to finalize your app configuration. Your Exotel inbound app is now ready to work with Bolna's Voice AI platform.
Click the **Save** button to finalize your app configuration. Your Exotel inbound app is now ready to work with Bolna's Voice AI platform.
### Step 7: Connect the Exophone with the created Exotel App
### Obtaining Your Exotel App ID
After saving your app, Exotel will generate a unique **App ID** for your configuration. This ID is what you'll use when configuring inbound calling campaigns in Bolna. You can find this ID in your Exotel App Bazaar dashboard next to your newly created app.
**Important**: Make sure to test your app configuration with a test call before launching production campaigns to ensure all components are working correctly together.
# Setup Exotel with Bolna for Outbound Calling
Source: https://www.bolna.ai/docs/guides/telephony/setup-exotel-app-for-outbound-calls
Create, setup and configure Exotel Application with your account for enabling Outbound calls with Bolna Voice AI Platform
## How to Create an Exotel App for Outbound Calls
To enable outbound calling functionality with Bolna's Voice AI agents through Exotel, you'll need to create and configure a dedicated app in your Exotel dashboard. This app serves as the communication bridge between Bolna's AI voice agents and Exotel's telephony infrastructure for making outbound calls.
### Understanding Exotel Apps for Voice AI Integration
An Exotel app is a customizable workflow that defines how your outbound calls are handled, routed, and connected. For Bolna integration, you'll configure a specialized app that connects the Voicebot functionality with Bolna's API endpoints, enabling seamless AI-powered outbound calling capabilities.
### Prerequisites for Creating Your Exotel Outbound App
Before you begin, ensure you have:
* An active Exotel account with API access
* Access to your Exotel dashboard at [my.exotel.com](https://my.exotel.com/)
### Step 1: Access the Exotel App Bazaar
Navigate to your [Exotel dashboard](https://my.exotel.com/) and locate the **App Bazaar** section under the **Manage** menu. The App Bazaar is where you'll create and configure custom apps for your telephony workflows.
### Step 2: Create a New App for Bolna Integration
Click the **Create** button to start building your new app. Give it a descriptive name such as **"Bolna Outbound"** (you can customize this name based on your preference for easy reference in your dashboard).
### Step 3: Add the Voicebot App Component
Drag the **Voicebot** app from the available components and drop it into the **"Drop app here"** box. This is the primary component that will handle the AI voice interaction.
### Step 4: Configure the Voicebot Component
Once dropped, a configuration popup will appear for the Voicebot settings:
* In the URL field, copy and paste the following Bolna API endpoint:
```
https://api.bolna.ai/exotel_callback
```
* Enable the **"Record this"** checkbox to record your outbound calls for quality assurance and compliance purposes
### Step 5: Configure App for Transfer calling
Within the Voicebot popup, you'll notice another **"Drop app here"** section at the bottom. This is where you'll configure the call connection logic.
Drag and drop the **Connect** voice app into this designated area. This component manages the actual phone call connection and routing.
When the Connect app popup opens, you'll need to specify how connection parameters are controlled:
1. Look for the section titled **"How do you want to control your Connect params?"**
2. Select the option: **"Configure parameters dynamically by providing a URL"**
3. In the **Primary URL** field, copy and paste the following Bolna API endpoint:
```
https://api.bolna.ai/exotel_connect_transfer
```
This configuration allows Bolna to dynamically control call parameters while transferring a live call.
### Step 6: Save Your Exotel App Configuration
Click the **Save** button to finalize your app configuration. Your Exotel outbound app is now ready to work with Bolna's Voice AI platform.
### Obtaining Your Exotel App ID
After saving your app, Exotel will generate a unique **App ID** for your configuration. This ID is what you'll use when configuring outbound calling campaigns in Bolna. You can find this ID in your Exotel App Bazaar dashboard next to your newly created app.
### Next Steps: Using Your Exotel App with Bolna
With your Exotel app configured and your App ID obtained, you can now:
* Configure outbound calling campaigns in Bolna using your Exotel App ID
* Launch AI-powered outbound voice campaigns through your Exotel infrastructure
* Monitor call performance and analytics through both Bolna and Exotel dashboards
**Important**: Make sure to test your app configuration with a test call before launching production campaigns to ensure all components are working correctly together.
# Integrate Twilio with Bolna for Enhanced Calling
Source: https://www.bolna.ai/docs/guides/telephony/twilio
Leverage Twilio with Bolna to handle inbound and outbound calls seamlessly. Follow setup guides and connect your Twilio account for tailored experiences.
## What is Twilio integration in Bolna?
Twilio is one of the leading telephony providers supported by Bolna Voice AI. By integrating Twilio with Bolna, you can make outbound calls, receive inbound calls, and use your own Twilio account for complete control over your phone numbers and calling infrastructure.
Learn more about [supported telephony providers](/docs/supported-telephony-providers) or [purchase phone numbers](/docs/guides/inbound/buying-phone-numbers) directly through Bolna.
## How to get started with Twilio
Bolna agents make phone calls using Twilio numbers
Bolna agents receive phone calls on Twilio numbers and answers them
Use your own Twilio account with Bolna
## Why use Twilio with Bolna?
Twilio offers several advantages:
* **Global coverage**: Make and receive calls in 100+ countries
* **Reliability**: Industry-leading uptime and call quality
* **Flexibility**: Use your existing Twilio infrastructure
* **Advanced features**: Access to Twilio's full feature set
For high-volume calling needs, consider using [batch calling](/docs/guides/outbound/batch-calling) to scale to millions of calls efficiently.
# Securely Link Your Twilio Account to Bolna
Source: https://www.bolna.ai/docs/guides/telephony/twilio-connect-provider
Follow detailed steps to connect your Twilio account with Bolna. Enable the use of your Twilio phone numbers for both inbound and outbound Voice AI calls.
## Use your own Twilio account to make outbound calls
We connect your `Twilio` account securely via using [infisical](https://infisical.com/).
You can connect your own Twilio account and start using it on Bolna. All calls initiated from Bolna will be from your own Twilio account and use your own Twilio phone numbers.
1. Navigate to `Providers` tab from the left menu bar & Click **Twilio connect button**.
2. Fill in the required details.
3. Save details by clicking on the **connect button**.
4. You'll see that your Twilio account was successfully connected. All your calls will now go via your own Twilio account and phone numbers.
# Using Twilio for inbound calls
Source: https://www.bolna.ai/docs/guides/telephony/twilio-inbound-calls
Make Bolna agents answer your inbound calls using Twilio
## Make inbound calls from dashboard
1. Navigate to the agent and copy the inbound URL displayed
2. Next, you'll need to go to your `Active Numbers` in Twilio Console ([https://console.twilio.com/us1/develop/phone-numbers/manage/incoming](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming))
3. Select and click the phone number for which you want to assign the Bolna AI.
4. Paste the copied link in Step#1 above in the Webhook URL. Make sure the HTTP Method is POST
5. Your settings should look like the following:
6. Voila! All set. Now try placing a call to the selected Twilio phone number and have your conversation with Bolna AI
## Making inbound calls Using APIs
Inbound Agent functionality using APIs currently requires connecting your **Twilio account**.
You can connect your Twilio account from [Twilio connect](/docs/twilio-connect-provider).
1. Use [Inbound agent API](/docs/api-reference/inbound/agent) to connect a Twilio phone number with Bolna agent
2. Upon a successful connection, all incoming calls to that phone number will be answered via Bolna
# Make Outbound Calls via Twilio with Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/telephony/twilio-outbound-calls
Set up Bolna Voice AI agents to place outbound calls through Twilio. Learn dashboard configurations and API methods for efficient call management.
## Making outbound calls from dashboard
1. Login to the dashboard at [https://platform.bolna.ai](https://platform.bolna.ai) using your account credentials
2. Choose `Twilio` as the Call provider for your agent and save it
3. Start placing phone calls by providing the recipient phone numbers.
Bolna will place the calls to the provided phone numbers.
You can place calls using your own custom Twilio phone numbers only if you've connected your Twilio account.
You can read more on how to connect your Twilio account [here](/docs/providers).
## Making outbound calls Using APIs
1. Generate and save your [Bolna API Key](/docs/api-reference/introduction#steps-to-generate-your-api-key)
2. Set your agent `input` and `output` tools as `twilio` while using [`/create` Agent API](/docs/api-reference/agent/create)
```create-agent.json theme={"system"}
...
...
"tools_config": {
"output": {
"format": "wav",
"provider": "twilio"
},
"input": {
"format": "wav",
"provider": "twilio"
},
"synthesizer": {...},
"llm_agent": {...},
"transcriber": {...},
"api_tools": {...}
}
...
...
```
3. Use [`/call` API](api-reference/calls/make) to place the call to the agent
```call.json theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789"
}'
```
# Enhance Call Capabilities with Bolna's Vobiz Integration
Source: https://www.bolna.ai/docs/guides/telephony/vobiz
Integrate Vobiz with Bolna to manage outbound & inbound calls for India. Access setup guides for seamless Voice AI agent communication using your Vobiz numbers.
## What is Vobiz integration in Bolna?
Vobiz is a cost-effective telephony provider supported by Bolna Voice AI. By integrating Vobiz with Bolna, you can make outbound calls, receive inbound calls, and use your own Vobiz account for complete control over your phone numbers and calling infrastructure.
Learn more about [supported telephony providers](/docs/supported-telephony-providers) or [purchase phone numbers](/docs/guides/inbound/buying-phone-numbers) directly through Bolna.
## How to get started with Vobiz
Bolna agents make phone calls using Vobiz numbers
Bolna agents receive phone calls on Vobiz numbers and answers them
Use your own Vobiz account with Bolna
## Why use Vobiz with Bolna?
Vobiz offers several advantages:
* **Cost-effective**: Competitive international calling rates
* **Reliable infrastructure**: Good uptime and call quality
* **Global coverage**: Support for calls in many countries
* **Easy integration**: Seamless setup with Bolna platform
For high-volume calling needs, consider using [batch calling](/docs/guides/outbound/batch-calling) to scale efficiently. Compare Vobiz with [Twilio](/docs/twilio) to choose the best provider for your needs.
# Link Your Vobiz Account to Bolna for Voice AI
Source: https://www.bolna.ai/docs/guides/telephony/vobiz-connect-provider
Securely connect your Vobiz account with Bolna. Enable your Voice AI agents to utilize Vobiz phone numbers for managing inbound and outbound calls.
## Use your own Vobiz account to make outbound calls
You can connect your own Vobiz account and start using it on Bolna. All calls initiated from Bolna will be from your own Vobiz account and use your own Vobiz phone numbers.
1. Navigate to `Providers` tab from the left menu bar & Click **Vobiz connect button**.
2. Fill in the required details.
3. Save details by clicking on the **connect button**.
4. You'll see that your Vobiz account was successfully connected. All your calls will now go via your own Vobiz account and phone numbers.
# Initiate Outbound Calls via Vobiz with Bolna Voice AI
Source: https://www.bolna.ai/docs/guides/telephony/vobiz-outbound-calls
Configure Bolna Voice AI agents to make outbound calls through Vobiz. Learn to set up calls using the dashboard and APIs for effective outreach.
## Making outbound calls from dashboard
1. Login to the dashboard at [https://platform.bolna.ai](https://platform.bolna.ai) using your account credentials
2. Choose `Vobiz` as the Call provider for your agent and save it
3. Start placing phone calls by providing the recipient phone numbers.
Bolna will place the calls to the provided phone numbers.
You can place calls using your own custom Vobiz phone numbers only if you've connected your Vobiz account.
You can read more on how to connect your Vobiz account [here](/docs/providers).
## Making outbound calls Using APIs
1. Generate and save your [Bolna API Key](/docs/api-reference/introduction#steps-to-generate-your-api-key)
2. Set your agent `input` and `output` tools as `vobiz` while using [`/create` Agent API](/docs/api-reference/agent/create)
```create-agent.json theme={"system"}
...
...
"tools_config": {
"output": {
"format": "wav",
"provider": "vobiz"
},
"input": {
"format": "wav",
"provider": "vobiz"
},
"synthesizer": {...},
"llm_agent": {...},
"transcriber": {...},
"api_tools": {...}
}
...
...
```
3. Use [`/call` API](api-reference/calls/make) to place the call to the agent
```call.json theme={"system"}
curl --request POST \
--url https://api.bolna.ai/call \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "123e4567-e89b-12d3-a456-426655440000",
"recipient_phone_number": "+10123456789"
}'
```
# Writing Prompts in Non-English Languages
Source: https://www.bolna.ai/docs/guides/writing-prompts-in-non-english-languages
Write multilingual prompts in native scripts for Bolna Voice AI. Ensure natural pronunciation & accurate responses in English, Hindi, Tamil, Telugu & more.
Bolna Voice AI agents have multilingual support and can have conversations in serveral languages ([see list of all support languages](/docs/customizations/multilingual-languages-support)). To ensure **natural speech output**, it is important to write your prompts in the **native script** of the target language, rather than phonetically using the English alphabet.
## Multilingual setup
Bolna supports multilingual configurations. You can add multiple languages to a single agent, set one as primary, and write a separate prompt for each.
> Example configurations:
>
> * English (Primary) + Hindi
> * English (Primary) + Hindi + Dutch
> * English (Primary) + French + Spanish
See the [Multilingual Support](/docs/customizations/multilingual-languages-support) guide for full setup details.
## Prompting for non-english language
If you want to switch languages dynamically you can instruct the prompt to follow the customer's language. For example, for Spanish you may write:
> You will keep your sentences short and crisp. You will never reply with more than 2 sentences at a time.
> You will stick to context throughout. You must speak in Spanish but if the customer wishes to communicate in English, you will immediately shift your language to English and then remain in english.
> Generate the text response in the same language as the customer.
***
## Write the prompt in the native script
Using the correct script:
* Enables more accurate pronunciation
* Helps the AI identify the intended language
* Improves contextual understanding and tone
* Prevents misclassification as English
## Tips for Writing in native scripts
* Use Google Input Tools or built-in language keyboards on your phone/laptop.
* For European languages, make sure to include accented characters (like é, ñ, ü, ¿, ç, etc.).
* Double-check spellings and punctuation using tools like [Google Translate](https://translate.google.com/), but avoid relying on it for full sentence correctness.
## Examples of prompts in native scripts
❌ Incorrect
> Bonjour! Comment ca va? Nous allons commencer l'entretien maintenant.
✅ Correct
> Bonjour ! Comment ça va ? Nous allons commencer l’entretien maintenant.
Notice the accents (ç, é, ’). These help the AI pronounce words like a native speaker.
❌ Incorrect
> Hola! Como estas? Vamos a comenzar la entrevista ahora.
✅ Correct
> ¡Hola! ¿Cómo estás? Vamos a comenzar la entrevista ahora.
Accents and inverted punctuation (¿, ¡) matter for tone and pronunciation accuracy.
❌ Incorrect
> Namaste! Aap kaise ho? Ham aapka interview lene wale hain.
✅ Correct
> नमस्ते! आप कैसे हैं? हम आपका इंटरव्यू लेने वाले हैं।
Accents and inverted punctuation (¿, ¡) matter for tone and pronunciation accuracy.
***
## Common Mistake to Avoid
Don’t write in "English-style" phonetic spelling for non-English prompts.
> ❌ Kaise ho?
> ✅ कैसे हो?
> ❌ Como estas?
> ✅ ¿Cómo estás?
## FAQs
You can add multiple languages to a single agent. Set one as primary and add secondary languages as needed. Each language gets its own prompt tab in the [Agent Tab](/docs/agent-setup/agent-tab).
Bolna agents can dynamically switch between any of the configured languages. Use the **Language Switching Instructions** field in the [Agent Tab](/docs/agent-setup/agent-tab) to define when the agent should switch. If a customer speaks a language not configured on the agent, it will fall back to the primary language.
It depends on your audience and brand tone. Ensure your prompts reflect the appropriate politeness level (e.g., “vous” vs. “tu” in French, or “आप” vs. “तुम” in Hindi) for a consistent and professional experience.
Use Bolna's Preview Voice feature in \[Voice Labs]\[[https://platform.bolna.ai/voices](https://platform.bolna.ai/voices)] to test generated responses before finalizing your prompts. Adjust words and punctuation if needed for more natural pronunciation.
# Importing your voices to use with Bolna Voice AI
Source: https://www.bolna.ai/docs/import-voices
Easily import voices from multiple providers like ElevenLabs, Cartesia including custom voices into Bolna for seamless voice agent personalization.
## What is Voice Importing?
Voice importing allows you to bring voices from external providers (like ElevenLabs, Cartesia) into your Bolna workspace. This enables you to use provider-specific voices or custom voices you've created with those providers in your Bolna Voice AI agents.
***
## How to Import Voices
Go to your agent in the Bolna Playground and click the **Audio** tab. Scroll down to the **Text-to-Speech** section and click **Add Voice +**.
Choose your voice provider from the list
Provide the **Voice ID** you want to import
Toggle to import custom voices from your own connected account
Click **"Import"** - your voice will be available within seconds!
Need help finding Voice IDs? Check your voice provider's dashboard or [contact support](mailto:support@bolna.ai).
***
## Next Steps
Create brand-specific voice identities
Configure voice settings in the Playground
Browse voice provider integrations
Set up multilingual agents with imported voices
# Home
Source: https://www.bolna.ai/docs/index
Bolna — the AI Voice API for India. Deploy multilingual conversational Voice AI agents to automate calls, qualify leads, boost sales, support customers, & more.
Bolna Documentation
Create conversational voice agents to qualify leads, boost sales, automate support, streamline hiring, and more.
# Bolna AI: Create and deploy Voice AI Agents
Source: https://www.bolna.ai/docs/introduction
Build and deploy conversational Voice AI agents with Bolna. Qualify leads, automate support, and book appointments through natural phone conversations.
## See Bolna in Action
***
## Why Businesses Choose Bolna
Never miss a lead again. Your AI agent handles calls 24/7, even at 3 AM.
Sub-600ms responses with natural voices. Callers can't tell the difference.
40+ languages including Hindi, Tamil, Telugu, and Bengali with native accents.
Handle 1 call or 10,000 calls simultaneously. No hiring, no training.
***
## Explore What You Can Build
From lead qualification to customer support, appointment booking to sales outreach, Bolna agents handle it all.
Explore pre-built agents for sales, support, HR, healthcare, and more. Clone any template and customize it for your business.
***
## Get Started
Talk to a live AI agent, no signup required
Build and deploy in under 5 minutes
Clone pre-built agents for common use cases
Get a personalized demo for your business
# Voice AI Platform Architecture & Concepts
Source: https://www.bolna.ai/docs/platform-concepts
Understand how Bolna Voice AI works including voice pipeline, agent configuration, real-time capabilities, and multilingual conversational AI agents.
## What is Bolna?
Bolna is a platform for building **conversational Voice AI agents** that can handle phone calls naturally, just like a human. Whether you're automating customer support, qualifying leads, or scheduling appointments, Bolna provides the infrastructure to create, deploy, and scale voice agents.
Configure agents with prompts, voice, and tools
Connect to phone numbers for inbound/outbound calls
Handle thousands of concurrent conversations
***
## How Voice AI Works
Every conversation flows through a **three-step pipeline** that happens in real-time:
**Speech-to-Text (ASR)** converts the caller's voice into text that your AI can understand.
Bolna supports [Deepgram](/docs/providers/transcriber/deepgram), [Azure](/docs/providers/transcriber/azure), [ElevenLabs](/docs/providers/transcriber/elevenlabs), and more.
**Large Language Model (LLM)** processes the text, understands context, and generates an intelligent response.
Connect [OpenAI](/docs/providers/llm-model/openai), [Anthropic](/docs/providers/llm-model/anthropic), [Azure OpenAI](/docs/providers/llm-model/azure-openai), or your own LLM.
**Text-to-Speech (TTS)** converts the response into natural-sounding speech played back to the caller.
Choose voices from [ElevenLabs](/docs/providers/voice/elevenlabs), [Cartesia](/docs/providers/voice/cartesia), [Azure](/docs/providers/voice/azure), and more.
Bolna orchestrates this entire pipeline in **under 600ms**, enabling natural, real-time conversations with minimal latency.
***
## Key Terms Explained
New to Voice AI? Here's what the technical terms mean in plain English:
**Think of it as**: The brain of your AI agent.
An LLM is an AI system (like ChatGPT) that understands language and generates human-like responses. When someone speaks to your agent, the LLM reads the transcribed text, understands what the person wants, and writes a response, just like a customer service rep would.
**Examples**: OpenAI GPT-4, Anthropic Claude, Google Gemini
**Think of it as**: The ears of your AI agent.
ASR (Automatic Speech Recognition) listens to what someone says on a call and converts their spoken words into written text. This text is then sent to the LLM so it can understand and respond.
**Examples**: Deepgram, Azure Speech, Google STT
**Think of it as**: The voice of your AI agent.
TTS (Text-to-Speech) takes the written response from the LLM and speaks it out loud in a natural-sounding voice. You can choose different voices, accents, and speaking styles to match your brand.
**Examples**: ElevenLabs, Cartesia, Azure TTS
**Think of it as**: The phone company that connects your calls.
A telephony provider handles the actual phone infrastructure for buying phone numbers, connecting calls, and ensuring audio quality. Bolna integrates with providers so your AI agent can make and receive real phone calls.
**Examples**: Twilio, Plivo, Exotel, Vobiz
**Think of it as**: Your virtual employee.
An agent is a complete Voice AI system configured with a personality, instructions, voice, and capabilities. It's like hiring a virtual employee; you tell it what to say, how to act, and what tasks to perform.
**Think of it as**: The training manual for your agent.
A prompt is a set of instructions you write to tell the agent how to behave. It includes the agent's personality, what information to collect, how to handle different situations, and what NOT to say.
**Think of it as**: Response time, how fast the agent replies.
Latency is the delay between when someone finishes speaking and when the agent starts responding. Lower latency (under 1 second) feels more natural, like a real conversation. Bolna optimizes for sub-600ms latency.
**Think of it as**: Reference documents your agent can read.
A knowledge base is a collection of documents (PDFs, websites, FAQs) that your agent can search during conversations. RAG (Retrieval-Augmented Generation) is the technology that lets the agent find relevant information and use it in responses.
***
## What Can Bolna Agents Do?
### Handle Phone Calls
Answer customer calls 24/7 with AI-powered responses
Proactively reach customers for sales, reminders, and follow-ups
Launch campaigns with thousands of concurrent calls
Route to human agents when AI assistance isn't enough
***
### Execute Actions During Calls
Agents can perform **real-time actions** by calling external APIs and tools:
| Tool | What It Does |
| ------------------------ | --------------------------------------------- |
| **Check Calendar Slots** | Query available appointment slots via Cal.com |
| **Book Appointments** | Schedule meetings directly during the call |
| **Transfer Calls** | Route to human agents or other numbers |
| **Custom Functions** | Call any API endpoint based on conversation |
Configure function tools in the [Tools Tab](/docs/agent-setup/tools-tab). Your agent can access CRMs, databases, payment systems, and more, all while on the call.
***
### Extract Insights After Calls
Every conversation generates valuable data:
Full conversation text with speaker labels
Audio recordings for review and training
AI-generated call summaries
Configure **post-call extractions** in the [Extractions Tab](/docs/agent-setup/analytics-tab) to automatically extract:
* Customer intent and sentiment
* Key data points (name, email, order ID)
* Custom fields you define
***
## Agent Configuration
Every Bolna agent is customized through **8 configuration tabs**:
**Prompts & Personality**
Define your agent's welcome message, instructions, and conversation behavior.
**Intelligence & Knowledge**
Choose your language model and connect knowledge bases for context-aware responses.
**Voice & Transcription**
Select voice provider, language, and transcription settings.
**Latency & Behavior**
Fine-tune response timing, interruption handling, and user detection.
**Telephony & Features**
Configure voicemail detection, DTMF input, and call timeouts.
**API Integrations**
Connect Cal.com, CRMs, and custom function tools.
**Webhooks & Extraction**
Set up post-call summaries, data extraction, and webhooks.
**Caller Matching**
Match callers to your database and prevent spam.
***
## Use Cases
Handle FAQs, troubleshoot issues, and escalate complex cases
Qualify inbound leads and schedule meetings with sales reps
Book, reschedule, and confirm appointments automatically
Screen candidates and schedule interviews at scale
***
## Get Started
Build an agent in under 5 minutes
Explore all configuration options
Set up voice, LLM, and telephony providers
Start from pre-built templates
# Bolna Voice AI usage pricing
Source: https://www.bolna.ai/docs/pricing/call-pricing
Discover detailed insights into Bolna Voice AI's pricing structure. Learn about cost breakdowns and flexible plans tailored to your business needs.
## How much does Bolna Voice AI cost?
Bolna Voice AI uses a transparent, usage-based pricing model. You only pay for what you use, with costs broken down into three components: Voice AI processing (STT + LLM + TTS), telephony charges, and a Bolna platform fee.
See all available plans, volume tiers, and per-minute rates on our pricing page.
***
## What does call pricing depend on?
Every call's total cost is the sum of five components across three parts.
**Part A - Voice AI (STT + LLM + TTS)**
Your choice of Speech-to-Text (STT) model and provider.
Billed by **call duration** (rounded to seconds).
Your choice of Large Language Model (LLM) and provider.
Billed by **tokens generated**.
Your choice of TTS model and provider.
Billed by **characters synthesized**.
**Part B & C - Telephony and Platform**
Your telephony provider and the country/region of the phone numbers.
Billed by **call duration** (rounded to minutes).
A flat per-minute fee charged by Bolna on top of your provider costs.
Billed by **call duration**.
***
## Which models are included in my rate?
Every workspace's flat per-minute rate already bundles a curated set of ASR, LLM, and TTS models — Bolna calls these your **preferred models**. Using only preferred models keeps your Voice AI cost at the flat rate; picking any other model bills that component separately at variable, usage-based rates.
View the current preferred ASR, LLM, and TTS model list and how it affects billing.
***
## How can I reduce my Voice AI costs?
You can significantly reduce costs by connecting your own provider accounts. When you bring your own keys (BYOK), Bolna does not charge for those components. You only pay your providers directly, plus Bolna's platform fee.
Head to the [Providers page](https://platform.bolna.ai/providers) to link your own STT, LLM, and TTS accounts.
Lighter LLM models (e.g. `gpt-4o-mini`) and efficient TTS voices can meaningfully lower per-call costs.
For predictable workloads, a volume-based plan offers better per-minute rates than pay-as-you-go.
See available tiers at [bolna.ai/pricing](https://bolna.ai/pricing).
[Learn more about supported providers](/docs/providers) and how to connect your accounts.
***
## Where can I see my call costs?
After each conversation, go to the [Agent Executions page](https://platform.bolna.ai/agent-executions) to see how many credits the conversation consumed.
***
## Next steps
Explore pay-as-you-go, pilots, and enterprise plans
Bring your own keys to reduce per-call costs
See which models are included in your flat rate
Track credits consumed per call
Custom pricing for high-volume deployments
For customized volume-based pricing, reach out to us at [enterprise@bolna.ai](mailto:enterprise@bolna.ai).
# Account based concurrency tiers
Source: https://www.bolna.ai/docs/pricing/outbound-calling-concurrency
Learn how Bolna Voice AI account tiers affect outbound call concurrency. Explore limits, scaling tiers, and enterprise options for high-volume operations.
## What are concurrency limits in Bolna?
Concurrency limits determine how many **simultaneous outbound calls** your account can make at once. Higher call volumes automatically increase your concurrency tier, ensuring smooth operations for growing businesses.
Up to **2 concurrent calls**, restricted to verified phone numbers only.
Starts at **10 concurrent calls**, scaling automatically with monthly usage.
**Elevated concurrency levels** for high-volume operations. Calls over your limit are automatically queued.
**No concurrency limits** - inbound calls are never restricted or queued.
You can read more about our enterprise offering here [Bolna enterprise](/docs/enterprise/plan).
Running an organization with sub-accounts? See [Concurrency management](/docs/enterprise/concurrency-management) for how a shared concurrency pool is split across accounts using guaranteed minimums and maximum caps.
## What happens to calls above your limit?
Outbound calls that don't fit your concurrency limit are **queued, not rejected**. They dial automatically as active calls finish, so a batch or campaign larger than your limit still runs end to end — it just paces itself.
### Each telephony provider queues independently
Your queued calls are tracked **per telephony provider**, so what happens on one provider doesn't affect the others:
If one provider is temporarily out of capacity, your calls on the other providers keep dialing at your usual concurrency instead of waiting behind it.
Calls placed on [your own provider account](/docs/providers) are limited only by your account concurrency — never by how busy that provider is for other Bolna customers.
Calls over [SIP trunking (BYOT)](/docs/sip-trunking/introduction) are the exception to the point above: they run on Bolna's SIP infrastructure, so they share platform capacity even though the trunk is yours.
### How your limit is shared between providers
Dialing is **not** first-come-first-served across your whole queue. Your concurrency limit is **split evenly between the providers you have calls waiting on**, and any share a provider can't use passes to the others. Within a single provider, calls dial in the order they were queued.
**Example** — your limit is **700**, with **15,000** calls queued on provider A and **15,000** on provider B:
| Queued on | Slots used |
| ---------- | ---------- |
| Provider A | 350 |
| Provider B | 350 |
Both providers dial continuously at 350 concurrent calls, each working through its own queue in order — so neither campaign has to wait for the other to finish. If provider A only had 200 calls waiting, it would use 200 slots and provider B would get the remaining 500.
Inbound calls are never queued, regardless of provider.
## How to check my account's concurrency limits?
Go to your **Workplace settings** in the Bolna dashboard.
See your **Account limits** to check your current concurrency tier and available slots.
## Next steps
Ready to scale your calling operations? Explore related features:
Set up batch calling for high-volume campaigns
Learn about making outbound calls efficiently
Explore elevated concurrency levels with our Enterprise plan
Monitor call details and execution results
For custom concurrency needs, [contact our team](mailto:support@bolna.ai) to discuss your requirements.
# Preferred models included in the flat rate
Source: https://www.bolna.ai/docs/pricing/preferred-models
See exactly which ASR, LLM, and TTS models are bundled into Bolna's flat per-minute rate, so you know when you're on the included tier versus paying variable provider costs.
## What are preferred models?
Every Bolna workspace ships with a **flat per-minute rate** — **\$0.06/min (₹5.52/min)** at standard wallet tiers — that already includes a curated set of transcriber (ASR), LLM, and voice (TTS) models. As long as your agent uses only these models, your Voice AI cost is the flat rate — you don't see separate line items for STT, LLM, or TTS usage.
If you pick a model outside this list (a premium model, a [BYOK provider](/docs/pricing/call-pricing#how-can-i-reduce-my-voice-ai-costs), or a model not yet marked as preferred), that component is billed at variable, usage-based rates instead of the flat rate. This is the single biggest reason two agents with the same call volume can see very different bills.
Preferred models change over time as Bolna negotiates provider rates and adds new options. This page is a snapshot — always check the **Add Funds** panel in your dashboard for the current list on your account.
Larger wallet top-ups (e.g. \$600+) get a lower effective per-minute rate as a volume discount — the preferred model bundle itself is the same across tiers.
***
## Where to see your preferred models
Go to [platform.bolna.ai](https://platform.bolna.ai) and click the **+** button next to your wallet balance in the top-right corner.
This opens the **Add Funds** modal. Scroll to the **"Your Selection"** section below the top-up amount options.
Under **"Your preferred models (included in the 6¢/min rate)"**, click **Show models** to expand the panel. It lists every ASR, LLM, and TTS model bundled into your current rate, grouped by category.
Compare this list with the transcriber, LLM, and voice selected on your agent's [Audio Tab](/docs/agent-setup/audio-tab) and [LLM Tab](/docs/agent-setup/llm-tab). If your agent uses a model not on this list, expect variable pricing for that component.
***
## Current preferred model list
| Provider | Preferred models |
| -------- | ------------------------------------------ |
| Deepgram | `nova-2`, `nova-3` |
| Azure | `azure` |
| Sarvam | `saarika:v2.5`, `saaras:v2.5`, `saaras:v4` |
See the [Transcriber providers](/docs/providers/transcriber/deepgram) for setup details on each.
| Provider | Preferred models |
| ------------ | ------------------------------------------------------------------- |
| OpenAI | `gpt-4.1-mini`, `gpt-4o-mini` |
| Azure OpenAI | `azure/gpt-4.1-mini`, `azure/gpt-4o-mini`, `azure/ptu-gpt-4-1-mini` |
See the [LLM providers](/docs/providers/llm-model/openai) for setup details on each.
| Provider | Preferred models |
| ---------- | -------------------------------------------------------------------- |
| ElevenLabs | `eleven_turbo_v2_5`, `eleven_flash_v2_5`, `eleven_v3_conversational` |
| Sarvam | `bulbul:v2` |
| Cartesia | `sonic-3`, `sonic-3.5`, `sonic-preview` |
See the [Voice providers](/docs/providers/voice/elevenlabs) for setup details on each.
Model names above match what's shown in the dashboard exactly (including casing and version suffixes like `:v2.5`). Selecting a similarly-named model from a different provider, or a newer/older version of the same model, may fall outside the preferred list.
***
## Why does this matter for my bill?
Agent uses only preferred ASR + LLM + TTS models → you pay the flat per-minute rate plus telephony and platform fee. No separate Voice AI usage line items.
Agent uses any non-preferred model → that component (STT, LLM, or TTS) is billed at variable, usage-based rates on top of telephony and platform fee. See the [call pricing breakdown](/docs/pricing/call-pricing#what-does-call-pricing-depend-on).
You can mix and match: for example, run a preferred LLM with a non-preferred TTS voice. Only the non-preferred component is billed separately — everything else stays on the flat rate.
***
## Related
* [Call pricing breakdown](/docs/pricing/call-pricing) — how the flat rate, telephony, and platform fee fit together
* [Choosing providers](/docs/concepts/choosing-providers) — pick the right model for latency, language, and quality
* [Bring your own keys](/docs/pricing/call-pricing#how-can-i-reduce-my-voice-ai-costs) — connect your own provider accounts instead
* [Enterprise plan](/docs/enterprise/plan) — custom rates and preferred model lists for high-volume accounts
# Supported Providers for Bolna Voice AI
Source: https://www.bolna.ai/docs/providers
Explore the list of providers supported by Bolna Voice AI, including integrations for telephony, transcription, and text-to-speech services to lower your costs
We don't charge for any usage for providers that you have connected to Bolna.
We connect all your `Provider` accounts securely via using [infisical](https://infisical.com/).
### Steps to add your own Provider credentials:
Login to the dashboard at [https://platform.bolna.ai](https://platform.bolna.ai)
Navigate to `Developers` tab from the left menu bar
Head over to the `Provider Keys` tab
Click the button `Add Provider Key` to your Provider key-value pair
Save your Provider
We currently have the following providers which you can connect to Bolna.
All these keys **must** be added for the respective provider.
| Property | Description |
| --------------------- | ------------------- |
| `TWILIO_ACCOUNT_SID` | Twilio account SID |
| `TWILIO_AUTH_TOKEN` | Twilio token |
| `TWILIO_PHONE_NUMBER` | Twilio phone number |
For creating a free Twilio Account you can checkout their blog [How to Work with your Free Twilio Trial Account](https://www.twilio.com/docs/messaging/guides/how-to-use-your-free-trial-account)
| Property | Description |
| -------------------- | ------------------ |
| `PLIVO_AUTH_ID` | Plivo auth ID |
| `PLIVO_AUTH_TOKEN` | Plivo auth token |
| `PLIVO_PHONE_NUMBER` | Plivo phone number |
| Property | Description |
| -------------------- | ------------------ |
| `VOBIZ_AUTH_ID` | Vobiz Auth ID |
| `VOBIZ_AUTH_TOKEN` | Vobiz Auth Token |
| `VOBIZ_PHONE_NUMBER` | Vobiz phone number |
| Property | Description |
| ------------------------ | ------------------------------ |
| `EXOTEL_API_KEY` | Exotel API Key |
| `EXOTEL_API_TOKEN` | Exotel API token |
| `EXOTEL_ACCOUNT_SID` | Exotel Account SID |
| `EXOTEL_DOMAIN` | Exotel Domain |
| `EXOTEL_PHONE_NUMBER` | Exotel phone number |
| `EXOTEL_OUTBOUND_APP_ID` | Exotel Outbound Application ID |
| `EXOTEL_INBOUND_APP_ID` | Exotel Inbound Application ID |
| Property | Description |
| -------- | ------------------- |
| `OPENAI` | Your OpenAI API key |
| Property | Description |
| ------------ | ----------------------- |
| `OPENROUTER` | Your OpenRouter API key |
| Property | Description |
| -------------------------- | ---------------------------- |
| `AZURE_OPENAI_API_KEY` | Your Azure API key |
| `AZURE_OPENAI_MODEL` | Your Azure OpenAI model |
| `AZURE_OPENAI_API_BASE` | Your Azure URL |
| `AZURE_OPENAI_API_VERSION` | Your Azure Model API version |
| Property | Description |
| -------- | -------------------------- |
| `GOOGLE` | Your Google Gemini API key |
For custom llm simply keep provider in the `llm_agent` key as `custom` and add a openai compatible `base_url`
#### Example LLM Agent key for the
```
"llm_agent": {
"max_tokens": 100.0,
"presence_penalty": 0.0,
"base_url": "https://custom.llm.model/v1",
"extraction_details": null,
"top_p": 0.9,
"agent_flow_type": "streaming",
"request_json": false,
"routes": null,
"min_p": 0.1,
"frequency_penalty": 0.0,
"stop": null,
"provider": "custom",
"top_k": 0.0,
"temperature": 0.2,
"model": "custom-llm-model",
"family": "llama"
}
```
| Property | Description |
| ------------ | ----------------------- |
| `ELEVENLABS` | Your Elevenlabs API key |
| Property | Description |
| ---------- | --------------------- |
| `CARTESIA` | Your Cartesia API key |
| Property | Description |
| -------- | ------------------- |
| `SARVAM` | Your Sarvam API key |
| Property | Description |
| ---------- | --------------------- |
| `SMALLEST` | Your Smallest API key |
| Property | Description |
| ---------- | ----------------- |
| `DEEPGRAM` | Your Deepgram key |
| Property | Description |
| -------- | --------------- |
| `SONIOX` | Your Soniox key |
# Anthropic Claude Models for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/llm-model/anthropic
Configure Claude Sonnet 5 or Claude Haiku 4.5 as the LLM for your Bolna voice agent.
[Anthropic's](https://www.anthropic.com/) Claude models are known for precise instruction following and strong reasoning. `claude-sonnet-5` is the recommended production choice — best speed-to-quality ratio. `claude-haiku-4-5-20251001` is the fastest and most cost-efficient option for high-volume agents.
***
## Quick config
```json theme={"system"}
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {
"provider": "anthropic",
"model": "claude-sonnet-5",
"max_tokens": 150,
"temperature": 0.2
}
}
```
To use your own Anthropic API key, connect it at [platform.bolna.ai/auth/anthropic](https://platform.bolna.ai/auth/anthropic).
***
## Supported models
| Model | Context | Best for | Notes |
| --------------------------- | ----------- | ------------------------------------------ | -------------------------------------------- |
| `claude-fable-5` | 1M tokens | Most complex reasoning, long-horizon tasks | Flagship; highest capability and cost |
| `claude-opus-4-8` | 1M tokens | Complex reasoning, agentic workflows | High capability; slower than Sonnet |
| `claude-sonnet-5` | 1M tokens | Most production voice agents | **Recommended** — best speed/quality balance |
| `claude-haiku-4-5-20251001` | 200K tokens | High-volume, cost-sensitive agents | Fastest TTFT; lowest cost |
**Recommendation:** Start with `claude-sonnet-5`. Drop to `claude-haiku-4-5-20251001` if you need lower latency or cost at scale. Upgrade to `claude-opus-4-8` for complex multi-step reasoning or sensitive domains.
***
## Key settings
| Setting | Type | Recommended | Description |
| ----------------- | ------- | ------------------- | --------------------------------------------- |
| `provider` | string | `"anthropic"` | Provider name |
| `model` | string | `"claude-sonnet-5"` | Model to use |
| `max_tokens` | integer | `150` | Cap on response length — keep short for voice |
| `temperature` | float | `0.2` | Lower = more deterministic; good for scripts |
| `agent_flow_type` | string | `"streaming"` | Always `"streaming"` for voice |
***
## Writing prompts for voice
Claude follows instructions very precisely — avoid vague phrasing.
* **Be explicit about format**: "Respond in 1–2 sentences maximum. Never use bullet points."
* **Define your scope**: "Only discuss topics related to appointment scheduling."
* **Set the persona clearly**: "You are a friendly receptionist for Acme Clinic. Your name is Priya."
See [Prompting Guide](/docs/guides/prompting/prompting-guide) for full guidance.
***
## Function calling
All current Claude models support function calling. Functions are defined in the [Tools Tab](/docs/agent-setup/tools-tab) and called automatically during conversation.
See [Custom Function Calls](/docs/tool-calling/custom-function-calls) for configuration.
***
## FAQ
`claude-sonnet-5` for most agents — strong instruction following at low latency. Use `claude-haiku-4-5-20251001` when cost or speed is the primary constraint. Use `claude-opus-4-8` or `claude-fable-5` only for the most complex reasoning tasks.
Lower temperature makes the model more consistent and predictable — important for scripted outbound calls. For more conversational or discovery-type agents, 0.5–0.7 is fine.
Use `claude-haiku-4-5-20251001` (significantly faster than Sonnet), keep `max_tokens` low (150 is a good ceiling), and write concise system prompts. See [Latency](/docs/concepts/latency) for a full breakdown.
Yes. Connect your Anthropic account at [platform.bolna.ai/auth/anthropic](https://platform.bolna.ai/auth/anthropic). LLM costs will be charged to your Anthropic account.
***
## Related
* [LLM Tab](/docs/agent-setup/llm-tab) — configure LLM in the dashboard
* [OpenAI](/docs/providers/llm-model/openai) — GPT-5 family alternative
* [OpenRouter](/docs/providers/llm-model/openrouter) — access Claude via unified gateway
* [Prompting Guide](/docs/guides/prompting/prompting-guide) — write effective prompts for voice
* [Custom Function Calls](/docs/tool-calling/custom-function-calls) — add tools to your agent
# Azure OpenAI Models for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/llm-model/azure-openai
Use GPT-5.4-mini, GPT-5.4, GPT-4.1, or GPT-4o through Azure OpenAI for enterprise data residency and compliance.
[Azure OpenAI Service](https://azure.microsoft.com/en-us/products/ai-services/openai-service) provides the same OpenAI models through Microsoft's cloud infrastructure — adding data residency controls, private networking, and enterprise compliance (SOC 2, HIPAA, ISO 27001). Use this provider when your deployment requires regional data handling or Azure-native security.
***
## Quick config
```json theme={"system"}
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {
"provider": "azure-openai",
"model": "gpt-5.4-mini",
"max_tokens": 150,
"temperature": 1
}
}
```
GPT-5-series models require `"temperature": 1`. Any other value is rejected with `400 For GPT-5 models, temperature must be 1`, and the field defaults to `0.1` when omitted, so send it explicitly.
Connect your Azure account at [platform.bolna.ai/auth/azure](https://platform.bolna.ai/auth/azure). You'll need your Azure endpoint URL, API key, and deployment name.
***
## Supported models
| Model | Context | Best for | Notes |
| -------------- | ----------- | ------------------------------- | ------------------------------------------- |
| `gpt-5.5` | 1M tokens | Maximum quality; complex tasks | Flagship; highest cost |
| `gpt-5.4` | 1M tokens | General-purpose production | Strong reasoning at lower cost than 5.5 |
| `gpt-5.4-mini` | 400K tokens | Most voice agents | **Recommended** — best latency/cost balance |
| `gpt-5.4-nano` | 400K tokens | Ultra-high-volume, simple tasks | Cheapest option |
| `gpt-4.1` | 1M tokens | Previous gen; still available | Stable if already deployed |
| `gpt-4.1-mini` | 1M tokens | Previous gen; still available | Stable if already deployed |
| `gpt-4o` | 128K tokens | Previous gen; still available | Stable if already deployed |
| `gpt-4o-mini` | 128K tokens | Previous gen; still available | Stable if already deployed |
Azure model availability varies by region. Not all models are available in all Azure regions immediately at launch. Check the [Azure OpenAI model availability](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models) page for your region.
***
## Key settings
| Setting | Type | Recommended | Description |
| ------------------ | ------- | ---------------- | --------------------------------------------------------------------------- |
| `provider` | string | `"azure-openai"` | Provider name |
| `model` | string | `"gpt-5.4-mini"` | Model/deployment name |
| `max_tokens` | integer | `150` | Cap on response length — keep short for voice |
| `temperature` | float | `1` | Required value on GPT-5 models; no other value is accepted |
| `reasoning_effort` | string | `"none"` | How much the model reasons first. GPT-5 only; valid values differ per model |
| `verbosity` | string | `"low"` | How long answers run. GPT-5 only |
| `agent_flow_type` | string | `"streaming"` | Always `"streaming"` for voice |
### GPT-5 settings with custom deployment names
Azure deployment names are chosen freely, so `model` here is often not the model name. Keep the underlying model name inside the deployment name — `prod-gpt-5.4-mini` rather than `prod-voice-01`. Bolna resolves the deployment to the model it serves, and that resolution is what selects GPT-5 handling and the right default `reasoning_effort`. A name it cannot resolve is treated as a non-GPT-5 model and gets the wrong defaults.
`reasoning_effort` is only checked against the [per-model table](/docs/providers/llm-model/openai#reasoning-effort) when `model` is an exact model name such as `gpt-5.4-mini` or `azure/gpt-5.4-mini`. With a custom deployment name, an unsupported value is accepted when you create the agent and then fails on the call instead. Check the table yourself when using custom deployment names.
***
## When to use Azure OpenAI vs direct OpenAI
Use **Azure OpenAI** when:
* Your data must stay within a specific region (EU data residency, HIPAA)
* You need private networking (VNet, private endpoints)
* Your organization already uses Azure for infrastructure
* You need enterprise SLA guarantees
Use **direct OpenAI** when:
* Simplest setup is preferred
* You don't have compliance requirements for data residency
* You want access to the latest models as soon as they launch (Azure has a short lag)
***
## FAQ
Yes. In Azure OpenAI, you create a named deployment for each model in the Azure portal. The deployment name is what you pass as the `model` field in Bolna config.
Azure mirrors OpenAI's lineup but with a short availability lag after new models launch. All GPT-5.x, GPT-4.1, and GPT-4o variants are available. Check [Microsoft's model page](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models) for your region.
Keep `reasoning_effort` at `none`, use `gpt-5.4-mini`, keep `max_tokens` at 150, and deploy to an Azure region geographically close to your users. See [Latency](/docs/concepts/latency) for more.
***
## Related
* [LLM Tab](/docs/agent-setup/llm-tab) — configure LLM in the dashboard
* [OpenAI](/docs/providers/llm-model/openai) — same models without Azure overhead
* [Prompting Guide](/docs/guides/prompting/prompting-guide) — write effective prompts for voice
* [Custom Function Calls](/docs/tool-calling/custom-function-calls) — add tools to your agent
# DeepSeek Models for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/llm-model/deepseek
Configure DeepSeek V4 Flash or V4 Pro as the LLM for your Bolna voice agent.
[DeepSeek](https://www.deepseek.com/) offers highly cost-effective LLMs with 1M token context windows. `deepseek-v4-flash` is the recommended option for voice agents — very low cost per token, high concurrent request limits, and competitive quality for conversational tasks.
`deepseek-chat` and `deepseek-reasoner` are deprecated as of **July 24, 2026**. Migrate to `deepseek-v4-flash` or `deepseek-v4-pro` before that date.
***
## Quick config
```json theme={"system"}
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {
"provider": "deepseek",
"model": "deepseek-v4-flash",
"max_tokens": 150,
"temperature": 0.2
}
}
```
To use your own DeepSeek API key, connect it at [platform.bolna.ai/auth/deepseek](https://platform.bolna.ai/auth/deepseek).
***
## Supported models
| Model | Context | Best for | Notes |
| ----------------------- | --------- | ----------------------- | ---------------------------------------------- |
| `deepseek-v4-flash` | 1M tokens | Most voice agents | **Recommended** — fastest, most cost-effective |
| `deepseek-v4-pro` | 1M tokens | Complex reasoning tasks | Higher quality; lower concurrency limit |
| ~~`deepseek-chat`~~ | — | — | Deprecated July 24, 2026 |
| ~~`deepseek-reasoner`~~ | — | — | Deprecated July 24, 2026 |
**Recommendation:** Use `deepseek-v4-flash` for all new deployments. It supports up to 2,500 concurrent requests — well-suited for high-volume outbound campaigns.
***
## Key settings
| Setting | Type | Recommended | Description |
| ----------------- | ------- | --------------------- | ------------------------------------------------ |
| `provider` | string | `"deepseek"` | Provider name |
| `model` | string | `"deepseek-v4-flash"` | Model to use |
| `max_tokens` | integer | `150` | Cap on response length — keep short for voice |
| `temperature` | float | `0.2` | Lower = more consistent; good for scripted calls |
| `agent_flow_type` | string | `"streaming"` | Always `"streaming"` for voice |
### Prompt caching
DeepSeek V4 models support prompt caching — repeated system prompts cost significantly less on cache hits. For agents that run many calls with the same system prompt, this can reduce LLM costs substantially. Cache hits are automatic; no configuration needed.
***
## FAQ
Use `deepseek-v4-flash` for most agents — lower cost, higher concurrency (2,500 vs 500 requests), and lower latency. Switch to `deepseek-v4-pro` if your use case requires more complex reasoning (e.g., nuanced financial conversations, detailed troubleshooting).
Change `"model": "deepseek-chat"` to `"model": "deepseek-v4-flash"` in your agent's LLM config. The API is compatible — no other changes needed. Test your prompt to confirm behavior since V4 is a newer generation.
DeepSeek V4 is significantly cheaper and has a 1M token context window. For simple to moderate conversational tasks (reminders, qualification, COD confirmation), quality is comparable. For complex reasoning or precise instruction-following in English, GPT-5.4-mini may have an edge. Test on your specific use case.
***
## Related
* [LLM Tab](/docs/agent-setup/llm-tab) — configure LLM in the dashboard
* [OpenAI](/docs/providers/llm-model/openai) — GPT-5 family alternative
* [OpenRouter](/docs/providers/llm-model/openrouter) — access DeepSeek and others via unified gateway
* [Prompting Guide](/docs/guides/prompting/prompting-guide) — write effective prompts for voice
# Google Gemini Models for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/llm-model/gemini
Configure Gemini 2.5 Flash or Gemini 3.x models as the LLM for your Bolna voice agent.
[Google Gemini](https://ai.google.dev/) models offer large context windows (up to 1M tokens), strong multilingual capability, and competitive latency. `gemini-2.5-flash` is the stable production recommendation for most agents — good speed-quality balance. The Gemini 3.x series is the newer generation with higher capability.
***
## Quick config
```json theme={"system"}
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {
"provider": "google",
"model": "gemini-2.5-flash",
"max_tokens": 150,
"temperature": 0.2
}
}
```
To use your own Google API key, connect it at [platform.bolna.ai/auth/google](https://platform.bolna.ai/auth/google).
***
## Supported models
| Model | Context | Best for | Notes |
| ----------------------- | --------- | ------------------------------ | -------------------------------------- |
| `gemini-3.5-flash` | 1M tokens | Complex reasoning, agent tasks | Latest generation; stable |
| `gemini-3.1-pro` | 1M tokens | Complex tasks, highest quality | Gemini 3 premium model |
| `gemini-3.1-flash-lite` | 1M tokens | Budget, high-volume agents | Fastest in Gemini 3 family |
| `gemini-2.5-pro` | 1M tokens | Advanced reasoning | Gemini 2.5 premium; stable |
| `gemini-2.5-flash` | 1M tokens | Most production voice agents | **Recommended** — proven, stable, fast |
| `gemini-2.5-flash-lite` | 1M tokens | Cost-sensitive high volume | Cheapest in 2.5 family |
**Recommendation:** Use `gemini-2.5-flash` for proven production stability. Try `gemini-3.5-flash` or `gemini-3.1-flash-lite` for improved performance on newer deployments.
***
## Key settings
| Setting | Type | Recommended | Description |
| ----------------- | ------- | -------------------- | --------------------------------------------- |
| `provider` | string | `"google"` | Provider name |
| `model` | string | `"gemini-2.5-flash"` | Model to use |
| `max_tokens` | integer | `150` | Cap on response length — keep short for voice |
| `temperature` | float | `0.2` | Lower = more deterministic |
| `agent_flow_type` | string | `"streaming"` | Always `"streaming"` for voice |
***
## Multilingual support
Gemini models have strong native multilingual capability. For Indian language agents (Hindi, Tamil, Bengali, etc.), Gemini is a good alternative to Sarvam if you need broader LLM capability alongside multilingual handling.
Always set the language explicitly in your prompt — Gemini handles it well, but auto-detection adds latency.
***
## FAQ
Both are stable. `gemini-2.5-flash` is the battle-tested choice with predictable performance. `gemini-3.5-flash` or `gemini-3.1-flash-lite` offer newer capability and are worth testing — especially for complex reasoning tasks. Switch once you've validated quality on your agent.
Comparable latency. Gemini has an edge on multilingual tasks and large-context scenarios (1M token window). GPT-5.4-mini has a slight edge on English instruction following consistency. Test both on your specific use case.
Yes. Connect at [platform.bolna.ai/auth/google](https://platform.bolna.ai/auth/google). API costs will be charged to your Google account.
***
## Related
* [LLM Tab](/docs/agent-setup/llm-tab) — configure LLM in the dashboard
* [OpenAI](/docs/providers/llm-model/openai) — GPT-5 family alternative
* [Multilingual Support](/docs/customizations/multilingual-languages-support) — configure language for your agent
* [Prompting Guide](/docs/guides/prompting/prompting-guide) — write effective prompts for voice
# OpenAI GPT Models for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/llm-model/openai
Configure GPT-5.6 (Sol, Terra, Luna), GPT-5.5, GPT-5.4, or GPT-5.4-mini as the LLM for your Bolna voice agent. Covers model selection, streaming config, prompt tips, and function calling.
[OpenAI's](https://openai.com/) GPT-5 family is the current generation, with **GPT-5.6** (Sol, Terra, Luna) the newest release. `gpt-5.4-mini` remains the default recommendation for most voice agents: it has low time-to-first-token and strong instruction following at a fraction of the cost of the full models.
***
## Quick config
```json theme={"system"}
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {
"provider": "openai",
"model": "gpt-5.4-mini",
"max_tokens": 150,
"temperature": 1
}
}
```
GPT-5-series models require `"temperature": 1`. Any other value is rejected with `400 For GPT-5 models, temperature must be 1`, and the field defaults to `0.1` when omitted, so send it explicitly.
To use your own OpenAI API key, connect it at [platform.bolna.ai/auth/openai](https://platform.bolna.ai/auth/openai).
***
## Supported models
| Model | Context | Best for | Notes |
| --------------- | ----------- | -------------------------------------------------------- | --------------------------------------------------------------- |
| `gpt-5.6-sol` | 1M tokens | Hardest tasks: complex coding, deep multi-step reasoning | Newest flagship; highest cost |
| `gpt-5.6-terra` | 1M tokens | High-volume production agents; balanced quality and cost | Newest; about 2x cheaper than Sol |
| `gpt-5.6-luna` | 1M tokens | Fast, low-cost everyday voice agents | Newest low-cost tier; strong quality per dollar |
| `gpt-5.5` | 1M tokens | Most demanding reasoning and quality | Flagship 5.5 line; high cost |
| `gpt-5.5-pro` | 1M tokens | Maximum quality on complex reasoning | Highest cost and latency; not ideal for latency-sensitive voice |
| `gpt-5.4` | 1M tokens | General-purpose production agents | Strong reasoning, lower cost than 5.5 |
| `gpt-5.4-mini` | 400K tokens | Most voice agents | **Recommended**: fastest TTFT, lowest cost |
| `gpt-4.1` | 1M tokens | Previous-gen; still available | Use if already deployed |
| `gpt-4.1-mini` | 1M tokens | Previous-gen; still available | Use if already deployed |
| `gpt-4o` | 128K tokens | Previous-gen; still available | Use if already deployed |
**Recommendation:** Start with `gpt-5.4-mini`. Step up to `gpt-5.6-terra` or `gpt-5.6-luna` for newest-generation quality at moderate cost, or `gpt-5.6-sol` / `gpt-5.5` when you need the strongest multi-step reasoning and highest output quality (financial, medical, nuanced escalation).
***
## Key settings
| Setting | Type | Recommended | Description |
| ------------------ | ------- | ---------------- | --------------------------------------------------------------------------- |
| `provider` | string | `"openai"` | Provider name |
| `model` | string | `"gpt-5.4-mini"` | Model to use |
| `max_tokens` | integer | `150` | Cap on response length — keep short for voice |
| `temperature` | float | `1` | Required value on GPT-5 models; no other value is accepted |
| `reasoning_effort` | string | `"none"` | How much the model reasons first. GPT-5 only; valid values differ per model |
| `verbosity` | string | `"low"` | How long answers run. GPT-5 only |
| `agent_flow_type` | string | `"streaming"` | Always `"streaming"` for voice |
### Keep max\_tokens short
Voice responses should be 1–3 sentences. `max_tokens: 150` is appropriate for most turns. A higher cap doesn't hurt quality but increases tail latency on long responses.
On GPT-5 models `max_tokens` is sent as `max_completion_tokens` and reasoning tokens come out of the same budget. At `reasoning_effort` above `none`/`minimal`, reasoning can consume most of a 150-token cap and truncate the spoken reply, so raise the cap whenever you raise the effort.
***
## Reasoning effort
GPT-5 models reason before answering. Effort controls how much, and it is the main quality-versus-latency dial on the LLM leg of a call. Leave it unset and the model gets the lowest-latency effort it supports, which is what most voice agents want.
Every model accepts a different subset, and an unsupported value is rejected when the agent is created:
| Model | Accepted `reasoning_effort` |
| ---------------------------------------------- | ---------------------------------------- |
| `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | `none`, `low`, `medium`, `high`, `xhigh` |
| `gpt-5.5` | `none`, `low`, `medium`, `high`, `xhigh` |
| `gpt-5.5-pro` | `medium`, `high`, `xhigh` |
| `gpt-5.4` | `none`, `low`, `medium`, `high`, `xhigh` |
| `gpt-5.4-mini`, `gpt-5.4-nano` | `none`, `low`, `medium`, `high` |
| `gpt-5.2` | `none`, `low`, `medium`, `high`, `xhigh` |
| `gpt-5.1` | `none`, `low`, `medium`, `high` |
| `gpt-5`, `gpt-5-mini`, `gpt-5-nano` | `minimal`, `low`, `medium`, `high` |
`minimal` is valid only on `gpt-5`, `gpt-5-mini` and `gpt-5-nano`. On `gpt-5.1` and later the equivalent is `none`.
For live calls, stay at `none` or `low`. Each step up adds reasoning tokens before the first spoken word, which lands directly in time-to-first-token. See [Latency](/docs/concepts/latency).
***
## Writing prompts for voice
Prompts for voice agents differ from chat prompts:
* **Use imperative sentences**: "Keep all responses under 3 sentences."
* **Specify spoken format**: "Never use bullet points or markdown — speak in complete sentences."
* **Define handling for off-topic questions**: "If asked something outside your scope, say: 'I can only help with appointment scheduling today.'"
* **Include the welcome message in the prompt or agent config**, not as part of the system prompt instructions.
See [Prompting Guide](/docs/guides/prompting/prompting-guide) for full guidance.
***
## Function calling
All GPT-5 and GPT-4.1 models support function calling. In Bolna, functions are defined in the [Tools Tab](/docs/agent-setup/tools-tab) and called automatically by the LLM during conversation.
`gpt-5.4`, `gpt-5.5` and `gpt-5.6` run through OpenAI's Responses API automatically, because function calling combined with `reasoning_effort` is not accepted on chat completions for those models. You don't need to configure anything for this.
See [Custom Function Calls](/docs/tool-calling/custom-function-calls) for configuration.
***
## FAQ
Use `gpt-5.4-mini` for most agents: lowest time-to-first-token and significantly lower cost per call. Step up to `gpt-5.6-terra` or `gpt-5.6-luna` for newest-generation quality at moderate cost, or `gpt-5.6-sol` / `gpt-5.5` for the most demanding tasks (complex financial/medical, long multi-step tool chains) where quality is the top priority. Avoid `gpt-5.5-pro` for live voice; its latency is too high for real-time calls.
No. GPT-5-series models accept only `temperature: 1`, and anything else fails agent creation with a 400. Use the prompt to constrain behaviour instead: state the exact wording, the sentence limit, and the fallback line for off-topic questions. On the previous-generation GPT-4.1 models a lower temperature still applies.
Keep `reasoning_effort` at `none` (or `minimal` on `gpt-5`/`gpt-5-mini`/`gpt-5-nano`), lower `max_tokens`, use `gpt-5.4-mini` instead of the larger models, and write shorter system prompts (large prompts increase prefill time). Reasoning effort is usually the biggest single lever. See [Latency](/docs/concepts/latency) for a full breakdown.
Yes. Connect your OpenAI account at [platform.bolna.ai/auth/openai](https://platform.bolna.ai/auth/openai). Costs will be charged to your OpenAI account, not Bolna's platform wallet (for the LLM component).
***
## Related
* [LLM Tab](/docs/agent-setup/llm-tab) — configure LLM in the dashboard
* [Anthropic Claude](/docs/providers/llm-model/anthropic) — alternative LLM
* [Azure OpenAI](/docs/providers/llm-model/azure-openai) — OpenAI models with enterprise data residency
* [Prompting Guide](/docs/guides/prompting/prompting-guide) — write effective prompts for voice
* [Custom Function Calls](/docs/tool-calling/custom-function-calls) — add tools to your agent
# OpenRouter for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/llm-model/openrouter
Access models from OpenAI, Anthropic, Google, Mistral, Meta, and more through a single OpenRouter API key.
[OpenRouter](https://openrouter.ai) is a unified API gateway that lets you access models from multiple providers — OpenAI, Anthropic, Google, Mistral, Meta, and others — through a single integration. Use it when you want to avoid managing multiple API keys, need automatic fallback between providers, or want to experiment with models without separate provider accounts.
***
## Quick config
```json theme={"system"}
"llm_agent": {
"agent_type": "simple_llm_agent",
"agent_flow_type": "streaming",
"llm_config": {
"provider": "openrouter",
"model": "openai/gpt-4o-mini",
"max_tokens": 150,
"temperature": 0.2
}
}
```
Connect your OpenRouter account at [platform.bolna.ai/auth/openrouter](https://platform.bolna.ai/auth/openrouter). Get your API key at [openrouter.ai](https://openrouter.ai).
***
## Recommended models for voice
OpenRouter uses `provider/model-name` slugs. These are the top picks for voice agents:
| Model slug | Context | Best for |
| ----------------------------- | ------- | ------------------------------------ |
| `openai/gpt-4o-mini` | 128K | Best OpenAI balance via OpenRouter |
| `openai/gpt-4o` | 128K | Higher quality OpenAI via OpenRouter |
| `anthropic/claude-haiku-4.5` | 200K | Fast, cost-efficient Claude |
| `anthropic/claude-sonnet-4.1` | 200K | High-quality Claude |
| `google/gemini-3-flash` | 1M | Fast Gemini, good multilingual |
| `google/gemini-3-flash-lite` | 1M | Cheapest large-context option |
| `mistralai/mistral-small` | 32K | Fast, low-cost European option |
| `meta-llama/llama-3.1-70b` | 128K | Open-weight; cost-effective |
| `deepseek/deepseek-chat` | 1M | Ultra-low cost (DeepSeek V4) |
For the full model catalog, see [openrouter.ai/models](https://openrouter.ai/models).
***
## Key settings
| Setting | Type | Recommended | Description |
| ----------------- | ------- | --------------------------- | --------------------------------------------- |
| `provider` | string | `"openrouter"` | Provider name |
| `model` | string | e.g. `"openai/gpt-4o-mini"` | Full OpenRouter model slug |
| `max_tokens` | integer | `150` | Cap on response length — keep short for voice |
| `temperature` | float | `0.2` | Lower = more consistent |
| `agent_flow_type` | string | `"streaming"` | Always `"streaming"` for voice |
***
## When to use OpenRouter vs direct providers
Use **OpenRouter** when:
* You want one API key for multiple providers
* You need automatic fallback if a provider is down
* You're testing and comparing models quickly
* You don't have existing API relationships with providers
Use **direct provider integrations** when:
* You need the absolute latest model versions (OpenRouter has a short lag)
* Your compliance requires knowing exactly which provider handles your data
* You want provider-specific features (Azure data residency, Anthropic Workspaces, etc.)
***
## FAQ
Minimal — typically a few milliseconds for routing. For most voice agents this is negligible. If you're highly latency-sensitive, benchmark against a direct provider connection.
`google/gemini-3-flash` has strong multilingual capability including Indian languages. For the best Indian language support, consider using [Sarvam](/docs/providers/llm-model) directly as the LLM provider.
Yes — OpenRouter supports model routing and fallback configuration through their dashboard. Set your primary model in Bolna and configure fallback logic in the OpenRouter console.
***
## Related
* [LLM Tab](/docs/agent-setup/llm-tab) — configure LLM in the dashboard
* [OpenAI](/docs/providers/llm-model/openai) — direct OpenAI integration
* [Anthropic](/docs/providers/llm-model/anthropic) — direct Anthropic integration
* [Google Gemini](/docs/providers/llm-model/gemini) — direct Gemini integration
* [Prompting Guide](/docs/guides/prompting/prompting-guide) — write effective prompts for voice
# AssemblyAI Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/assemblyai
Integrate AssemblyAI with your Bolna Voice AI agents for accurate English transcription with Universal model and real-time streaming.
## 1. What is AssemblyAI STT?
[AssemblyAI](https://www.assemblyai.com/) Speech-to-Text (STT) is an advanced automatic speech recognition platform that uses AI to transcribe spoken English into text with high accuracy. AssemblyAI provides real-time streaming transcription with their Universal model.
AssemblyAI is designed for enterprise-grade applications requiring accurate English transcription with features like speaker diarization, turn-based conversation management, and customizable confidence thresholds, making it ideal for voice agents, customer support systems, and conversational AI applications.
## 2. Key Features of AssemblyAI STT
AssemblyAI offers comprehensive features for enterprise speech recognition:
* **Universal Model**: High-accuracy English speech recognition model with enterprise-grade performance.
* **Real-Time Streaming**: WebSocket-based streaming API with immutable transcripts and turn-based transcription for voice agent applications.
* **Speaker Diarization**: Identify and separate different speakers in English audio streams.
* **Turn-Based Transcription**: Provides speaking turns with unique identifiers, word-level metadata, and configurable silence detection.
* **High Accuracy**: English transcription with enterprise-grade accuracy and low word error rates.
* **Format Flexibility**: Supports PCM16 and Mu-law encoding with configurable sample rates for different telephony providers.
* **Enterprise Features**: Batch and real-time processing, custom vocabulary, confidence scoring, and detailed analytics.
## 3. How Bolna Uses AssemblyAI for STT
Bolna AI integrates AssemblyAI's STT technology to enable accurate multilingual transcription for voice agents. Here's how Bolna leverages AssemblyAI:
* **Real-Time Voice Processing**:
Bolna uses AssemblyAI's streaming WebSocket API (v3) to convert spoken language into text in real time. The immutable transcript feature ensures stable text progression without overwrites.
* **English Voice Agent Support**:
Bolna voice agents use AssemblyAI's streaming API for real-time English transcription with high accuracy and low latency.
* **Turn-Based Conversation Management**:
Bolna leverages AssemblyAI's turn-based transcription to structure conversations, with each speaking turn having unique identifiers for better context management and response generation.
* **Telephony Provider Optimization**:
Bolna automatically configures audio encoding (Mu-law for Twilio, Linear16 for others) and sample rates (8kHz for telephony, 16kHz for web) based on the provider.
* **Streaming and Batch Processing**:
Bolna supports both real-time streaming for live conversations and batch processing for recorded calls, using AssemblyAI's HTTP API for non-streaming scenarios.
* **Enterprise-Grade Reliability**:
Bolna uses AssemblyAI's enterprise features including automatic language detection, confidence thresholds, and detailed latency tracking for production voice applications.
## 4. List of AssemblyAI models supported on Bolna AI
| Model |
| --------- |
| universal |
## 5. Supported Languages
For real-time voice agents, AssemblyAI streaming supports:
* **English** - en
## Conclusion
AssemblyAI's STT capabilities empower Bolna AI to deliver highly accurate, real-time English speech-to-text transcription for voice agents. By integrating AssemblyAI's streaming technology, Bolna provides turn-based conversation management, immutable transcripts, and enterprise-grade reliability for production voice AI applications.
# Azure Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/azure
Integrate Azure Speech-to-Text with Bolna Voice AI for real-time, multilingual, high-accuracy transcriptions and enterprise-grade scalability.
## What is Azure Speech-to-Text?
Azure Speech-to-Text, part of Microsoft Azure Cognitive Services, offers cloud-based automatic speech recognition (ASR). It converts spoken language into text using advanced deep learning models—enabling real-time transcription, batch processing, and support for custom model training. It’s designed to handle enterprise-grade workloads with high accuracy and multi-language capabilities.
## Why choose Azure for speech transcription?
Azure offers a variety of features that make it a leading STT solution:
* **Real-Time Streaming & Batch Transcription**: Supports both low-latency streaming for live interactions and batch processing for recorded files.
* **Speaker Diarization & Language Identification**: Detects speaker turns and identifies languages in multi-party, multilingual scenarios.
* **Noise Reduction**: Advanced noise suppression techniques improve transcription accuracy in challenging audio conditions.
* **Secure & Scalable**: Fully managed service with options for resource control, webhook callbacks, and deployment across regions.
## How does Bolna integrate with Azure Speech-to-Text?
Bolna AI integrates Azure’s STT technology to enable real-time, high-accuracy speech transcription for its AI-powered voice agents. Here’s how Bolna leverages Azure:
* **Live Conversation Transcription**:
Bolna uses Azure's real-time streaming to convert user speech into text with minimal delay, enabling dynamic agent interaction.
* **Multi-Language, Multi-Speaker Context**:
With speaker diarization and language detection, Bolna agents accurately follow multilingual or multi-party calls.
* **Speaker Identification and Context Retention**:
Bolna uses Azure’s speaker diarization capabilities to differentiate between the agent and the caller in conversations. This feature helps in maintaining context and structuring responses effectively.
* **Recording & Post-Call Analysis**:
Bolna supports batch transcription of stored calls via REST, using callbacks/webhooks to asynchronously retrieve results for insights, compliance, and analytics.
## Next steps
Ready to configure Azure Speech-to-Text for your voice AI agent? Start by [setting up your transcriber in the Playground](/docs/agent-setup/audio-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [Deepgram transcriber](/docs/providers/transcriber/deepgram) for alternative transcription
* Explore [Azure OpenAI](/docs/providers/llm-model/azure-openai) for a complete Azure ecosystem
* Learn about [data residency options](/docs/enterprise/data-residency) for compliance
* Configure [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
* You can also connect your own Azure account and use it with [Bolna AI](https://platform.bolna.ai/auth/azure)
Integrating Azure Speech-to-Text with Bolna empowers voice AI agents to deliver seamless, real-time, and highly accurate transcriptions across diverse languages and speaker scenarios.e.
# Deepgram Real-Time Transcription for Bolna Voice Agents
Source: https://www.bolna.ai/docs/providers/transcriber/deepgram
Configure Deepgram Nova-3 or Nova-2 streaming speech-to-text in your Bolna voice agent. Covers models, endpointing, multilingual config, and troubleshooting.
[Deepgram](https://deepgram.com/) is Bolna's default transcriber for English. Its streaming Nova-3 model delivers sub-150ms transcription latency, making it the fastest option for real-time voice AI.
***
## Quick config
```json theme={"system"}
"transcriber": {
"provider": "deepgram",
"model": "nova-3",
"language": "en",
"stream": true,
"encoding": "linear16",
"sampling_rate": 16000,
"endpointing": 250
}
```
Set this in your agent's `tools_config.transcriber` block. See [Create Agent API](/docs/api-reference/agent/v2/create) for the full schema.
To use your own Deepgram account, connect it at [platform.bolna.ai/auth/deepgram](https://platform.bolna.ai/auth/deepgram).
***
## Supported models
| Model | Languages | Best for |
| ------------------------- | ------------- | ------------------------------------ |
| `nova-3` | English | Lowest latency; recommended default |
| `nova-3-medical` | English | Clinical terminology |
| `nova-2` | 30+ languages | Multilingual; see supported list |
| `nova-2-phonecall` | English | Phone audio with background noise |
| `nova-2-conversationalai` | English | Optimized for AI agent conversations |
| `nova-2-meeting` | English | Multiple speakers |
| `nova-2-medical` | English | Medical terminology |
| `nova-2-finance` | English | Financial and trading terminology |
| `nova-2-atc` | English | Air traffic control |
| `nova-2-drivethru` | English | Fast-food/quick-service ordering |
| `nova-2-automotive` | English | In-car applications |
| `flux` | English | Flux model (English only) |
| `flux-multilingual` | Multiple | Flux multilingual |
**Recommendation:** Use `nova-3` for English agents. Use `nova-2` with `language` set explicitly for non-English.
***
## Key settings
| Setting | Type | Default | Description |
| --------------- | ------- | ---------- | --------------------------------------------- |
| `model` | string | `nova-3` | Model variant |
| `language` | string | `en` | BCP-47 language code — always set explicitly |
| `stream` | bool | `true` | Enable streaming; never disable in production |
| `encoding` | string | `linear16` | Audio encoding format |
| `sampling_rate` | integer | `16000` | Hz — match your telephony provider |
| `endpointing` | integer | `250` | ms of silence before final transcript |
### Endpointing guidance
* **250ms** — default; works well for fluent English speakers
* **350–500ms** — better for non-native speakers, elderly callers, or callers who pause mid-sentence
* **100–150ms** — fast-paced scripts; reduces dead air but may interrupt on pauses
***
## Multilingual config
Set `language` explicitly. Auto-detect adds 100–200ms latency and occasionally misclassifies.
```json theme={"system"}
"transcriber": {
"provider": "deepgram",
"model": "nova-2",
"language": "hi",
"stream": true,
"encoding": "linear16",
"sampling_rate": 16000
}
```
For Indian languages, [Sarvam](/docs/providers/transcriber/sarvam) may give better accuracy. See [Multilingual Voice Agents](/docs/customizations/multilingual-languages-support).
***
## FAQ
Use `nova-3` for English — it's faster and more accurate. Use `nova-2` when you need a non-English language or a domain-specific variant (`nova-2-phonecall`, `nova-2-medical`, etc.).
Your `endpointing` value is too low. Increase it to 350–500ms. If callers have a strong accent or speak with filler words ("um", "uh"), a higher endpointing value gives them more time to complete their thought.
Match the telephony provider's output: Plivo and Exotel use `linear16` at 16000 Hz. Twilio uses `mulaw` at 8000 Hz. If you use the wrong values, transcription accuracy degrades.
Yes — the same transcriber config applies to both outbound and inbound calls. There's no separate configuration.
***
## Related
* [Audio Tab](/docs/agent-setup/audio-tab) — configure transcriber in the dashboard
* [Latency](/docs/concepts/latency) — how transcription affects end-to-end response time
* [Deepgram Flux](/docs/providers/transcriber/deepgram-flux) — the Flux model variant
* [Sarvam transcriber](/docs/providers/transcriber/sarvam) — Indian languages
* [Azure transcriber](/docs/providers/transcriber/azure) — enterprise multilingual option
# Deepgram Flux Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/deepgram-flux
Use Deepgram's next-generation Flux models with Bolna Voice AI agents for ultra-low-latency streaming transcription and intelligent turn detection.
## What is Deepgram Flux?
Deepgram Flux is Deepgram's latest generation of speech-to-text models, purpose-built for real-time conversational AI. Unlike Nova models that rely on external Voice Activity Detection (VAD) for turn boundaries, Flux models have turn detection built directly into the model — producing a richer event stream that lets Bolna start responding sooner and handle barge-ins more accurately.
## Why choose Deepgram Flux for voice AI transcription?
* **Speculative LLM responses**: Bolna can start generating an LLM response on `EagerEndOfTurn` before the speaker has fully stopped, cutting perceived response time significantly.
* **Accurate barge-in detection**: The `StartOfTurn` event fires as soon as speech begins, allowing Bolna to interrupt playback with zero VAD delay.
* **Language Identification (Flux Multi)**: `flux-general-multi` identifies the spoken language per turn and returns it alongside the transcript, enabling dynamic multilingual handling without pre-configuring a language.
* **Configurable turn sensitivity**: End-of-turn thresholds and timeouts are exposed as tunable parameters, so you can balance responsiveness against accuracy for your specific use case.
## Which Deepgram Flux models are supported on Bolna AI?
| Model | Description |
| --------------------- | ------------------------------------------------------------- |
| `Flux (English)` | English-only Flux model optimised for accuracy and latency |
| `Flux (Multilingual)` | Multilingual Flux model with built-in Language Identification |
## Configurable parameters
### EndOfTurn Threshold (`eot_threshold`)
Controls how confident the model must be that the speaker has finished their turn before emitting a final transcript.
| Value | Behaviour |
| ----- | ----------------------------------------------------------- |
| `0.5` | Responds sooner, higher chance of cutting off the speaker |
| `0.7` | **Default** — balanced for most voice agent use cases |
| `0.9` | Waits longer, reduces false endings on incomplete sentences |
**Range:** `0.5` – `0.9` (step `0.05`)
***
### EndOfTurn Timeout (`eot_timeout_ms`)
Maximum silence duration (in milliseconds) the model waits after the last detected speech before forcing an EndOfTurn event. Acts as a safety net when the model's confidence score alone is insufficient.
| Value | Behaviour |
| ------------------- | --------------------------------------------------------- |
| `300 ms` – `900 ms` | Aggressive — good for fast back-and-forth interactions |
| `1 s` | **Default** — works well for most voice agent use cases |
| `2 s` – `3 s` | Patient — useful for agents that ask open-ended questions |
**Options:** `300 ms`, `400 ms`, `500 ms`, `600 ms`, `700 ms`, `800 ms`, `900 ms`, `1 s`, `2 s`, `3 s`
***
### Eager EndOfTurn (`eager_eot_threshold`)
When enabled, Flux emits an `EagerEndOfTurn` event before the final `EndOfTurn`. Bolna uses this to start LLM inference speculatively — if the speaker continues (`TurnResumed`), the speculative request is cancelled; if the speaker stops (`EndOfTurn`), the response is already in flight.
Enable this toggle to activate eager turn detection. When enabled, set the **Eager Threshold**:
| Value | Behaviour |
| ----- | ------------------------------------------------------------------------- |
| `0.3` | Triggers very early — maximum latency reduction, higher cancellation rate |
| `0.5` | **Default** — good balance between speed and accuracy |
| `0.9` | Triggers late — nearly as conservative as standard EndOfTurn |
**Range:** `0.3` – `0.9` (step `0.05`)
Enable Eager EndOfTurn with a threshold of `0.4`–`0.5` for the lowest perceived response latency. If you see frequent mid-sentence interruptions, raise the threshold or disable it.
## Next steps
Ready to configure Deepgram Flux for your voice AI agent? Open the **Audio** tab in the [Bolna Playground](/docs/agent-setup/audio-tab), select `Flux (English)` or `Flux (Multilingual)` as your transcriber model, and tune the parameters above.
For related integrations:
* Compare with [Deepgram Nova](/docs/providers/transcriber/deepgram) for a widely-deployed production alternative
* Learn about [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
* Explore [LLM providers](/docs/providers/llm-model/openai) to process transcribed text
# ElevenLabs Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/elevenlabs
Integrate ElevenLabs Scribe with Bolna Voice AI agents for real-time, low-latency speech transcription. Supports word-level timestamps & VAD-based endpointing.
## What is ElevenLabs Scribe STT?
[ElevenLabs](https://elevenlabs.io/) Scribe is a state-of-the-art real-time speech-to-text (STT) model designed for low-latency transcription in voice AI applications. The Scribe v2 Realtime model delivers accurate transcription across 90 languages with approximately 150ms latency, making it ideal for conversational AI agents, customer support systems, and interactive voice applications.
ElevenLabs Scribe combines advanced deep learning with real-time streaming capabilities, providing precise word-level timestamps, automatic language detection, and intelligent voice activity detection (VAD) for natural conversation flow.
## Why choose ElevenLabs Scribe for voice AI transcription?
ElevenLabs Scribe offers several features that make it a powerful choice for real-time speech recognition:
* **Ultra-Low Latency**: With approximately 150ms latency (excluding network overhead), Scribe v2 Realtime enables natural, responsive conversations without noticeable delays.
* **Extensive Language Support**: Supports 90 languages with high accuracy, making it suitable for global voice AI deployments and multilingual applications.
* **Word-Level Timestamps**: Provides precise timestamps for each transcribed word, enabling accurate synchronization and detailed conversation analysis.
* **Automatic Language Detection**: Detects the spoken language automatically during transcription, supporting code-switching scenarios where speakers switch between languages.
* **VAD-Based Endpointing**: Uses intelligent voice activity detection to determine when a speaker has finished talking, ensuring accurate turn-taking in conversations.
* **High Accuracy**: Achieves industry-leading word error rates, outperforming many competitors on standard benchmarks like FLEURS and Common Voice.
* **Streaming WebSocket API**: Real-time streaming via WebSocket enables continuous transcription as audio is received, perfect for live voice agent interactions.
## How does Bolna integrate with ElevenLabs Scribe?
Bolna AI integrates ElevenLabs Scribe STT technology to enable real-time, high-accuracy speech transcription for its AI-powered voice agents. Here's how Bolna leverages ElevenLabs:
* **Real-Time Voice Processing**:
Bolna uses ElevenLabs' streaming WebSocket API to convert spoken language into text in real time. The low-latency design ensures that AI agents can understand and respond to user input without perceptible delays, creating natural conversation experiences.
* **Multilingual Voice Agent Support**:
With support for 90 languages, Bolna voice agents can handle conversations in virtually any language. The automatic language detection feature allows agents to adapt to the speaker's language dynamically.
* **Intelligent Turn Detection**:
Bolna leverages ElevenLabs' VAD-based commit strategy to accurately detect when users have finished speaking. Configurable silence thresholds (0.3 to 3.0 seconds) allow fine-tuning for different conversation styles and use cases.
* **Telephony Provider Optimization**:
Bolna automatically configures audio encoding based on the telephony provider. For Twilio, it uses mulaw at 8kHz; for Exotel and Plivo, it uses linear16 at 8kHz; and for web-based calls, it uses linear16 at 16kHz for optimal quality.
* **Word-Level Latency Tracking**:
Bolna tracks per-word latency using ElevenLabs' timestamp data, providing detailed analytics on transcription performance and helping optimize voice agent responsiveness.
* **Code-Switching Detection**:
When language detection is enabled, Bolna can identify when speakers switch between languages within a conversation, tracking per-word language breakdown for multilingual scenarios.
## Which ElevenLabs models are supported on Bolna AI?
| Model | Description |
| -------------------- | ------------------------------------------------- |
| scribe\_v2\_realtime | Real-time speech recognition with \~150ms latency |
## Next steps
Ready to configure ElevenLabs transcription for your voice AI agent? Start by [setting up your transcriber in the Playground](/docs/agent-setup/audio-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [Deepgram transcriber](/docs/providers/transcriber/deepgram) for alternative transcription
* Explore [ElevenLabs synthesizer](/docs/providers/voice/elevenlabs) for a complete ElevenLabs ecosystem
* Learn about [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
* Configure [LLM providers](/docs/providers/llm-model/openai) to process transcribed text
ElevenLabs Scribe STT capabilities empower Bolna AI to deliver highly accurate, real-time speech-to-text transcription with ultra-low latency, making voice interactions seamless and responsive.
# Gladia Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/gladia
Integrate Gladia with Bolna Voice AI agents for real-time multilingual transcription. Supports code-switching, custom vocabulary, and sub-300ms latency.
## What is Gladia STT?
[Gladia](https://www.gladia.io/) is a state-of-the-art audio transcription and intelligence platform that provides real-time speech-to-text capabilities with industry-leading accuracy. Powered by their Solaria ASR model, Gladia delivers transcription with less than 300 milliseconds latency, making it ideal for voice AI agents, contact centers, and real-time communication applications.
Gladia combines advanced speech recognition with audio intelligence features like sentiment analysis, named entity recognition, and automatic language detection, providing a comprehensive solution for voice-driven applications.
## Why choose Gladia for voice AI transcription?
Gladia offers several features that make it a powerful choice for real-time speech recognition:
* **Ultra-Low Latency**: With sub-300ms latency, Gladia enables natural, responsive conversations without noticeable delays, essential for voice AI agents and real-time applications.
* **Extensive Language Support**: Supports over 100 languages interchangeably, making it suitable for global deployments and multilingual customer interactions.
* **Code-Switching Support**: Handles seamless language switching within conversations, accurately transcribing when speakers alternate between languages like English and Hindi (Hinglish) or other language combinations.
* **Custom Vocabulary**: Allows boosting recognition of specific words, phrases, brand names, or industry-specific terminology to improve accuracy for specialized use cases.
* **Native Mulaw Support**: Directly supports mulaw audio encoding used by Twilio, eliminating the need for audio conversion and reducing latency in telephony applications.
* **Audio Enhancement**: Built-in audio preprocessing improves transcription accuracy in challenging conditions with background noise or poor audio quality.
* **Configurable Endpointing**: Adjustable silence detection thresholds allow fine-tuning for different conversation styles and turn-taking patterns.
* **Sentiment Analysis**: Real-time sentiment detection helps understand caller emotions and enables dynamic agent responses.
## How does Bolna integrate with Gladia?
Bolna AI integrates Gladia's STT technology to enable real-time, high-accuracy speech transcription for its AI-powered voice agents. Here's how Bolna leverages Gladia:
* **Real-Time Voice Processing**:
Bolna uses Gladia's streaming WebSocket API to convert spoken language into text in real time. The two-step connection process (session creation followed by WebSocket connection) ensures reliable, authenticated streaming with optimal performance.
* **Multilingual Voice Agent Support**:
With support for over 100 languages, Bolna voice agents can handle conversations in virtually any language. When code-switching is enabled, agents can accurately transcribe conversations where speakers switch between languages.
* **Telephony Provider Optimization**:
Bolna automatically configures audio encoding based on the telephony provider. For Twilio, it uses native mulaw at 8kHz (wav/ulaw); for Exotel and Plivo, it uses linear16 at 8kHz; and for web-based calls, it uses linear16 at 16kHz for optimal quality.
* **Audio Enhancement for Telephony**:
Bolna enables Gladia's audio enhancer for telephony providers (Twilio, Exotel, Plivo) to improve transcription accuracy in real-world call conditions with background noise and varying audio quality.
* **Custom Vocabulary Integration**:
Bolna supports passing custom vocabulary keywords to Gladia, allowing voice agents to accurately recognize company names, product names, and industry-specific terminology.
* **Intelligent Turn Detection**:
Bolna leverages Gladia's configurable endpointing to accurately detect when users have finished speaking. The endpointing threshold can be adjusted to balance responsiveness with accuracy for different conversation styles.
* **Code-Switching for Multilingual Markets**:
For markets like India where code-switching is common, Bolna configures Gladia to recognize both the primary language and English, enabling accurate transcription of mixed-language conversations.
## Which Gladia models are supported on Bolna AI?
| Model | Description |
| ------- | ---------------------------------------------------- |
| Solaria | Universal real-time STT model with sub-300ms latency |
Gladia's Solaria model is the default and recommended model for real-time voice agent applications.
## Next steps
Ready to configure Gladia transcription for your voice AI agent? Start by [setting up your transcriber in the Playground](/docs/agent-setup/audio-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [Deepgram transcriber](/docs/providers/transcriber/deepgram) for alternative transcription
* Explore [Azure transcriber](/docs/providers/transcriber/azure) for enterprise deployments
* Learn about [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
* Configure [LLM providers](/docs/providers/llm-model/openai) to process transcribed text
Gladia's STT capabilities empower Bolna AI to deliver highly accurate, real-time speech-to-text transcription with ultra-low latency and comprehensive multilingual support, making voice interactions seamless across global markets.
# OpenAI Realtime Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/openai
Integrate OpenAI's Realtime transcription API with Bolna Voice AI agents for low-latency, streaming speech recognition using GPT Realtime Whisper.
## What is OpenAI Realtime STT?
[OpenAI's Realtime API](https://platform.openai.com/docs/guides/realtime-transcription) provides a WebSocket-based streaming speech-to-text service. Unlike batch transcription, audio is streamed continuously and transcripts are returned with low latency as the caller speaks, making it well-suited for live voice agent conversations.
## Why choose OpenAI Realtime for voice AI transcription?
* **Ultra-low latency**: Streams audio and returns interim transcript deltas as the caller speaks, with final results delivered on turn boundaries.
* **Built-in server VAD**: `GPT Realtime Whisper` has voice activity detection built in — it automatically detects speech start and end without any manual configuration.
* **Streaming interim transcripts**: Partial transcripts arrive as the caller is still speaking, giving your agent an early signal to start processing.
* **Optional noise reduction**: Near-field noise reduction can be enabled to improve accuracy in office or call-centre environments.
* **Delay tuning**: The `delay` parameter lets you trade off transcription latency against accuracy — useful for noisy environments or accented speech.
## Which OpenAI models are supported?
| Model | Description |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| `GPT Realtime Whisper` | GA streaming transcription model. Natively designed for real-time sessions with built-in VAD. |
## Configurable parameters
These parameters appear in the **Audio** tab of the Bolna Playground when OpenAI is selected as the transcriber provider.
### Transcription Delay (`delay`)
Controls the trade-off between transcription speed and accuracy. A lower delay emits results sooner; a higher delay gives the model more audio context before committing to a transcript.
| Value | Behaviour |
| --------- | -------------------------------------------------------- |
| `minimal` | Fastest — best for simple, clean audio |
| `low` | Low latency with good accuracy |
| `medium` | **Default** — balanced for most use cases |
| `high` | Higher accuracy — useful for accents or background noise |
| `xhigh` | Maximum accuracy — highest latency |
### Noise Reduction
Toggle on to enable near-field noise reduction. Recommended for call-centre or office environments where background noise is common.
## Supported languages
`GPT Realtime Whisper` supports a wide range of languages. Pass the ISO 639-1 code as the `language` parameter when configuring the transcriber.
Common supported languages include: `en`, `es`, `fr`, `de`, `hi`, `pt`, `ja`, `it`, `nl`, `zh`, `ko`, `ar`, `ru`.
## Next steps
Ready to configure OpenAI transcription for your voice AI agent? Open the **Audio** tab in the [Bolna Playground](/docs/agent-setup/audio-tab), select `openai` as the transcriber provider and `GPT Realtime Whisper` as the model, then tune the parameters above.
For related integrations:
* Compare with [Deepgram Flux](/docs/providers/transcriber/deepgram-flux) for an alternative with configurable turn detection
* Compare with [Deepgram Nova](/docs/providers/transcriber/deepgram) for a widely-deployed production alternative
* Learn about [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
# Pixa Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/pixa
Integrate Pixa with Bolna Voice AI agents for accurate Hindi speech transcription. Optimized for Indian language recognition with real-time streaming support.
## What is Pixa STT?
[Pixa](https://heypixa.ai/) (HeyPixa) is a speech-to-text platform specifically optimized for Hindi and Indian language transcription. Pixa provides real-time streaming transcription through a WebSocket API, making it ideal for voice AI agents serving Indian markets where accurate Hindi recognition is essential.
Pixa's models are trained on diverse Hindi datasets, enabling high accuracy for regional accents, conversational speech patterns, and the natural variations found in spoken Hindi across different regions of India.
## Why choose Pixa for voice AI transcription?
Pixa offers several features that make it a strong choice for Hindi speech recognition:
* **Hindi Language Expertise**: Pixa's models are specifically optimized for Hindi transcription, delivering high accuracy for native Hindi speakers and various regional accents.
* **Real-Time Streaming**: WebSocket-based streaming API provides continuous transcription as audio is received, enabling responsive voice agent interactions.
* **Multiple Audio Encodings**: Supports linear16, linear32, mulaw, and alaw audio encodings, ensuring compatibility with various telephony providers and audio sources.
* **Multiple Model Options**: Offers both the native pixa-1 model optimized for Hindi and a whisper-1 model for broader language support.
* **Low Latency Design**: Designed for real-time applications with minimal delay between speech and transcription output.
* **Telephony Integration**: Native support for common telephony audio formats makes integration with Twilio, Exotel, and Plivo straightforward.
## How does Bolna integrate with Pixa?
Bolna AI integrates Pixa's STT technology to enable real-time Hindi speech transcription for its AI-powered voice agents. Here's how Bolna leverages Pixa:
* **Real-Time Hindi Voice Processing**:
Bolna uses Pixa's streaming WebSocket API to convert Hindi speech into text in real time. This enables AI agents to understand and respond to Hindi-speaking users without noticeable delays.
* **Hindi Market Voice Agents**:
For businesses serving Indian customers, Pixa's Hindi-optimized transcription ensures accurate understanding of customer queries, names, addresses, and other Hindi content that general-purpose transcribers might struggle with.
* **Telephony Provider Optimization**:
Bolna automatically configures audio encoding based on the telephony provider. For Twilio, it uses mulaw at 8kHz; for Exotel and Plivo, it uses linear16 at 8kHz; and for web-based calls, it uses linear16 at 16kHz.
* **Intelligent Turn Detection**:
Since Pixa relies on final transcript markers rather than VAD events, Bolna implements intelligent turn detection based on the is\_final flag, with configurable timeout handling for edge cases.
* **Utterance Timeout Handling**:
Bolna monitors for stuck utterances and implements force-finalization when transcripts don't receive final confirmation within the configured timeout, ensuring conversations continue smoothly.
* **Connection Management**:
Bolna handles WebSocket connection lifecycle including authentication, heartbeat messages, and graceful disconnection to ensure reliable transcription throughout calls.
## Which Pixa models are supported on Bolna AI?
| Model | Description |
| --------- | --------------------------------------------------------- |
| pixa-1 | Native Hindi-optimized speech recognition model (default) |
| whisper-1 | Whisper-based model for broader language support |
## Next steps
Ready to configure Pixa transcription for your Hindi voice AI agent? Start by [setting up your transcriber in the Playground](/docs/agent-setup/audio-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [Sarvam transcriber](/docs/providers/transcriber/sarvam) for comprehensive Indian language support
* Explore [Deepgram transcriber](/docs/providers/transcriber/deepgram) for multilingual alternatives
* Learn about [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
* Configure [LLM providers](/docs/providers/llm-model/openai) to process transcribed text
Pixa's Hindi-optimized STT capabilities empower Bolna AI to deliver accurate, real-time speech-to-text transcription for Indian market voice agents, ensuring seamless Hindi conversations with high recognition accuracy.
# Sarvam Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/sarvam
Integrate Sarvam with your Bolna Voice AI agents for accurate Indian language transcription. Supports 11 Indian languages with Saarika and Saaras speech models.
## 1. What is Sarvam STT?
[Sarvam](https://sarvam.ai/) Speech-to-Text (STT) is an advanced automatic speech recognition (ASR) platform specifically designed for Indian languages. Sarvam specializes in understanding regional accents, code-mixed speech, and multilingual conversations common in the Indian subcontinent.
Sarvam's "Saarika" and "Saaras" models are built for real-time transcription with a focus on Indian language accuracy. Saarika provides transcription in the original language, while Saaras offers direct speech-to-English translation with automatic language detection, making them ideal solutions for voice-driven applications serving Indian markets.
## 2. Key Features of Sarvam STT
Sarvam offers specialized features for Indian language transcription:
* **Indian Language Expertise**: Deep neural networks specifically trained on diverse Indian language datasets, achieving high accuracy for regional accents and code-mixed speech patterns.
* **Real-Time Processing**: Designed for streaming transcription with low latency, enabling natural conversation flow in live applications.
* **Code-Mixed Speech Recognition**: Excels at understanding code-mixed languages, handling seamless switches between English and Indian languages within conversations.
* **Multilingual Support**: Supports 10 Indian languages including Hindi, Bengali, Tamil, Telugu, Gujarati, Kannada, Malayalam, Marathi, Punjabi, Odia, plus English (India).
* **Speaker Diarization**: Identifies and separates different speakers in audio streams for better conversation structure.
* **Voice Activity Detection**: Advanced VAD capabilities with configurable sensitivity levels for better speech boundary detection.
* **Automatic Language Detection**: Can automatically detect the spoken language when configured with "unknown" language code.
* **WebSocket Streaming**: Real-time streaming API for continuous speech recognition with immediate results and timestamp support.
## 3. How Bolna Uses Sarvam for STT
Bolna AI integrates Sarvam's STT technology to enable high-accuracy Indian language transcription for voice agents. Here's how Bolna leverages Sarvam:
* **Real-Time Indian Language Processing**:
Bolna uses Sarvam's streaming STT API to convert Indian language speech into text in real time. This enables AI agents to understand and process user input in regional languages without delays.
* **Regional Language Voice Agent Support**:
With Sarvam's specialized Indian language support, Bolna voice agents can handle conversations in Hindi, Bengali, Tamil, Telugu, and other regional languages with high accuracy.
* **Accent-Aware Transcription**:
Bolna leverages Sarvam's training on diverse Indian accents and speaking patterns to ensure accurate transcription across different regions and demographics.
* **Voice Activity Detection for Better Accuracy**:
Bolna uses Sarvam's VAD capabilities to detect speech boundaries accurately, improving conversation flow and reducing false transcriptions from background noise.
* **Indian Market Optimization**:
Since Bolna serves businesses across India, Sarvam's focus on Indian languages and accents ensures better customer experience for regional market deployments.
* **Code-Switching Support**:
Sarvam handles mixed language conversations common in India, where speakers switch between English and regional languages within the same conversation.
## 4. List of Sarvam models supported on Bolna AI
| Model | Description |
| ------------ | -------------------------------------------------------------------------------------------------------------------- |
| saarika:v2.5 | Speech-to-text transcription in original language |
| saaras:v2.5 | Speech-to-English translation with automatic language detection |
| saaras:v3 | Speech-to-text transcription in original language (configured for STT transcription) |
| saaras:v4 | Latest Saaras model for speech-to-text transcription in original language, with automatic language detection support |
## 5. Supported Languages
All Sarvam transcriber models support the following 11 languages:
* **English (India)** - en-IN
* **Hindi** - hi-IN
* **Bengali** - bn-IN
* **Tamil** - ta-IN
* **Telugu** - te-IN
* **Gujarati** - gu-IN
* **Kannada** - kn-IN
* **Malayalam** - ml-IN
* **Marathi** - mr-IN
* **Punjabi** - pa-IN
* **Odia** - od-IN
**Model Differences:**
* **Saarika v2.5**: Transcribes speech to text in the original spoken language
* **Saaras v2.5**: Translates speech directly to English text with automatic language detection
* **Saaras v3**: Configured for direct transcription in the original spoken language
* **Saaras v4**: Latest Saaras model, transcribes directly in the original spoken language and can auto-detect the spoken language
Note: All models excel at code-mixed speech where speakers seamlessly switch between English and any of the supported Indian languages within the same conversation.
## Conclusion
Sarvam's STT capabilities empower Bolna AI to deliver highly accurate, real-time speech-to-text transcription for Indian languages, making voice interactions seamless for regional markets. By integrating Sarvam's specialized ASR technology, Bolna enhances its ability to process diverse Indian accents, handle code-switching scenarios, and understand complex multilingual conversations, thereby improving the overall performance and reliability of its voice AI solutions for the Indian market.
For related integrations:
* You can also connect your own Sarvam account and use it with [Bolna AI](https://platform.bolna.ai/auth/sarvam)
# Soniox Transcriber (Speech to Text)
Source: https://www.bolna.ai/docs/providers/transcriber/soniox
Integrate Soniox real-time STT with your Bolna Voice AI agents for multilingual transcription with native code-switching and low-latency turn detection.
## What is Soniox STT?
[Soniox](https://soniox.com/) Speech-to-Text is a real-time automatic speech recognition (ASR) platform built around a single multilingual model. Instead of running a separate recognizer per language, one Soniox model transcribes whatever is spoken — including mid-sentence switches between languages (for example Hinglish) — in a single streaming connection.
Bolna uses Soniox's real-time `stt-rt-v5` model, which combines high accuracy across 60+ languages, per-token language identification, and semantic endpoint detection for natural turn-taking.
## Why choose Soniox for voice AI transcription?
* **Native multilingual, one connection**: A single model handles all supported languages and code-switches between them automatically. There is no per-language switching — the agent simply understands the caller, even when they mix languages.
* **Code-switching (Hinglish and more)**: Soniox is built for real-world speech where callers move between English and a regional language within the same sentence, which is common across Indian markets.
* **Semantic endpoint detection**: Soniox detects when a speaker has actually finished their turn (rather than waiting on a fixed silence timer) and signals it immediately, so Bolna can respond sooner without cutting people off.
* **Per-token language identification**: Each transcribed token carries its detected language, giving downstream logic an accurate, real-time view of what the caller is speaking.
## How Bolna uses Soniox for STT
Bolna connects to Soniox over a single streaming WebSocket and biases it using **language hints**:
* **Multilingual (auto-detect)**: Select the multilingual option and Bolna hints the supported set, letting Soniox detect and code-switch on its own — ideal for callers who mix English and a regional language.
* **Single language**: Select a specific language (for example Hindi) and Bolna hints that language so Soniox does its best for it throughout the call, while still handling the occasional English word naturally.
Both telephony (8 kHz) and web calls (16 kHz) are supported, and interim results stream continuously so barge-in stays responsive.
## Which Soniox models are supported on Bolna AI?
| Model | Description |
| ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `Soniox v5` (`stt-rt-v5`) | Real-time multilingual model with code-switching, language identification, and semantic endpoint detection |
## Supported languages
Soniox on Bolna supports multilingual auto-detect plus the following languages:
* **English** — `en`
* **English (India)** — `en-IN`
* **Hindi** — `hi`
* **Bengali** — `bn`
* **Tamil** — `ta`
* **Telugu** — `te`
* **Gujarati** — `gu`
* **Kannada** — `kn`
* **Malayalam** — `ml`
* **Marathi** — `mr`
* **Punjabi** — `pa`
For callers who naturally mix English with a regional language, select the **multilingual** option rather than a single language — Soniox identifies and code-switches in one stream, so you do not need to pre-configure a language.
## Next steps
Ready to use Soniox for your voice AI agent? Open the **Audio** tab in the [Bolna Playground](/docs/agent-setup/audio-tab), select `Soniox v5` as your transcriber, and choose multilingual or a specific language.
For related integrations:
* You can connect your own Soniox account by adding your `SONIOX` key in [provider settings](/docs/providers)
* Compare with [Sarvam](/docs/providers/transcriber/sarvam) for Indian-language transcription
* Learn about [multilingual support](/docs/customizations/multilingual-languages-support) for global agents
# AWS Polly Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/aws-polly
Learn how to integrate and use AWS Polly TTS with Bolna Voice AI agents including Amazon's neural, generative and standard models.
## What is AWS Polly TTS?
[AWS Polly](https://aws.amazon.com/polly/) is a cloud-based text-to-speech (TTS) service powered by Amazon Web Services (AWS). It uses deep learning technologies to convert text into natural-sounding speech, making it ideal for applications requiring high-quality voice synthesis.
AWS Polly supports a wide range of languages and voices, offering both **standard TTS** and **neural TTS (NTTS)**, which enhances the realism of speech output. Designed for real-time and batch processing, AWS Polly enables applications to deliver engaging voice experiences across various industries, including customer service, e-learning, and automated assistants.
## Why choose AWS Polly for voice synthesis?
AWS Polly offers several advanced features that make it a powerful choice for AI-driven voice applications:
**Natural-Sounding Speech**: Utilizes neural TTS (NTTS) to enhance realism, reducing robotic-sounding speech.
**Multiple Languages and Voices**: Supports a wide range of languages and accents, allowing for global reach.
**Real-Time Speech Synthesis**: Generates speech quickly with low latency, making it suitable for interactive applications.
**Neural and Standard TTS Options**: Offers high-quality neural TTS as well as cost-effective standard TTS for scalable deployment.
## How does Bolna integrate with AWS Polly TTS?
Bolna AI integrates AWS Polly’s TTS capabilities to deliver high-quality, real-time speech synthesis for its voice AI agents. Here’s how Bolna leverages AWS Polly:
**Generating Lifelike Speech for Voice AI Agents**:
Bolna AI uses AWS Polly to convert AI-generated text responses into human-like speech, ensuring a more natural interaction experience for users.
**Low-Latency Voice Synthesis for Real-Time Conversations**:
With AWS Polly’s low-latency capabilities, Bolna AI ensures real-time speech generation, allowing its voice agents to respond without noticeable delays.
**Multilingual and Accent Customization**:
AWS Polly’s extensive language and voice options allow Bolna AI to cater to a global audience by providing speech output in multiple languages and accents.
**Scalable and Cost-Effective Deployment**:
As a cloud-based service, AWS Polly allows Bolna AI to scale its voice synthesis needs based on demand while maintaining cost efficiency.
## What AWS Polly TTS models are supported?
Bolna supports the following AWS Polly TTS models:
| Model |
| ---------- |
| neural |
| generative |
| standard |
## Next steps
Ready to configure AWS Polly voices for your voice AI agent? Start by [setting up your synthesizer in the Playground](/docs/agent-setup/engine-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [ElevenLabs voices](/docs/providers/voice/elevenlabs) for alternative synthesis
* Explore [Azure TTS](/docs/providers/voice/azure) for Microsoft ecosystem integration
* Review [Deepgram voices](/docs/providers/voice/deepgram) for low-latency options
* Configure [multilingual support](/docs/customizations/multilingual-languages-support) for global reach
AWS Polly's TTS capabilities enhance Bolna AI's ability to deliver realistic, engaging, and highly responsive voice interactions. AI.
# Azure Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/azure
Integrate Microsoft Azure Text-to-Speech with Bolna to create natural, expressive Voice AI agents. Supports neural voices and multilingual output.
## What is Azure TTS?
Azure Text-to-Speech (TTS) is a cloud-based speech synthesis service offered by Microsoft as part of its Azure Cognitive Services. It uses advanced deep learning models to generate realistic and natural-sounding speech from text. Designed for enterprise-grade applications, Azure TTS enables businesses to create interactive voice experiences, enhance accessibility, and automate customer interactions with high-fidelity voice output.
Azure TTS provides **neural voice synthesis**, offering near-human pronunciation, tone, and emotion control. This technology is widely used in virtual assistants, automated call centers, media narration, and real-time conversational AI applications.
## Why choose Azure for voice synthesis?
Azure Text-to-Speech stands out with the following capabilities:
**Neural TTS for Human-Like Speech**: Uses deep neural networks to create speech that closely mimics human intonation and expressiveness.
**Extensive Language & Voice Support**: Supports over 140 languages and multiple voice options, making it a powerful tool for global reach.
**Real-Time & Batch Processing**: Enables both live interaction and bulk conversion of text to speech.
**AI-Driven Emotion Infusion**: Adjusts emotional expression in speech (e.g., happy, neutral, sad) to improve engagement.
**Latency-Optimized Speech Processing**: Ensures minimal lag, making it suitable for real-time conversational AI applications.
## How does Bolna integrate with Azure TTS?
Bolna AI integrates Azure Text-to-Speech to deliver high-quality, human-like speech output for its AI-driven voice agents. Azure TTS enhances Bolna’s ability to conduct seamless, engaging, and contextually aware voice interactions. Here’s how Bolna leverages this technology:
**Lifelike Speech for Interactive AI Conversations**:
Azure’s Neural TTS allows Bolna AI to generate speech that mirrors human conversation patterns, improving user experience and making voice AI interactions more natural.
**Multi-Language and Multimodal Conversational AI**:
Since Bolna serves a global user base, Azure’s extensive language and accent library helps deliver culturally relevant and clear speech output tailored to different regions.
**Adaptive Speech Based on User Interaction**:
Azure TTS enables Bolna AI to modify speech output dynamically based on conversational context. For instance, the AI can adjust intonation when emphasizing key details in recruitment interviews or customer support interactions.
**Emotionally Intelligent Voice AI**:
By leveraging Azure’s emotion-infused speech synthesis, Bolna AI ensures that the voice agent sounds empathetic, enthusiastic, or neutral based on the conversation’s nature. This is especially useful in customer service and human resource automation.
**Enhanced Pronunciation for Industry-Specific Terms**:
Azure’s custom lexicons and SSML-based pronunciation adjustments help Bolna AI deliver precise pronunciation for technical terms, job roles, and company names, ensuring clarity in voice interactions.
**Real-Time Speech Output for Seamless Conversations**:
Azure’s low-latency synthesis ensures that Bolna AI voice agents can provide instant responses, making them highly effective in real-time support scenarios such as call handling, interview assistance, and virtual customer service.
## Next steps
Ready to configure Azure voices for your voice AI agent? Start by [setting up your synthesizer in the Playground](/docs/agent-setup/engine-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Combine with [Azure Speech-to-Text](/docs/providers/transcriber/azure) for complete Azure integration
* Compare with [ElevenLabs voices](/docs/providers/voice/elevenlabs) for alternative synthesis
* Explore [Azure OpenAI](/docs/providers/llm-model/azure-openai) for enterprise LLM deployment
* Configure [multilingual support](/docs/customizations/multilingual-languages-support) for global reach
* You can also connect your own Azure account and use it with [Bolna AI](https://platform.bolna.ai/auth/azure)
Azure TTS plays a crucial role in enhancing Bolna AI's voice-driven experiences, offering superior speech quality, multilingual support, real-time processing, and brand customization.ide.
# Cartesia Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/cartesia
Enable Cartesia voices in Bolna Voice AI agents for expressive, customizable AI voices using their latest voice models for multilingual Indian voices.
## What is Cartesia text-to-speech API?
[Cartesia](https://cartesia.ai/) is a state-of-the-art text-to-speech (TTS) API that generates high-fidelity, natural-sounding speech for AI voice applications. Cartesia uses advanced neural network models to replicate human speech patterns, delivering expressive and realistic audio output that enhances user engagement in conversational AI systems.
Cartesia TTS API is optimized for real-time voice synthesis with ultra-low latency, making it ideal for AI voice assistants, virtual customer support agents, conversational AI chatbots, and automated business communication systems. The platform offers multilingual voice support, customizable voice characteristics, and high-quality prosody that adapts to different use cases including customer service automation, sales outreach, appointment scheduling, and interactive voice response (IVR) systems.
## Why use Cartesia TTS for AI voice agents?
Cartesia text-to-speech API offers powerful capabilities that make it an excellent choice for building conversational AI applications and voice automation systems:
**Ultra-low latency voice synthesis**: Cartesia delivers real-time speech generation with minimal delay, ensuring natural conversation flow in AI voice assistants and customer support bots. This low-latency performance is critical for interactive applications where response time directly impacts user experience.
**Natural-sounding neural voices**: Powered by advanced deep learning models, Cartesia produces human-like speech with natural prosody, intonation, and emotional expression. The neural TTS technology creates voices that sound authentic and engaging, improving user trust and satisfaction in AI interactions.
**Multilingual and accent support**: Cartesia supports multiple languages and regional accents, enabling businesses to deploy AI voice agents for global audiences. This multilingual capability is essential for international customer support, sales automation, and localized voice experiences.
**Customizable voice characteristics**: Businesses can fine-tune voice parameters to match their brand identity and use case requirements. Adjust speaking rate, pitch, and emotional tone to create distinct voice personas for different AI agent roles.
**Scalable API infrastructure**: Cartesia's cloud-based TTS API scales automatically to handle high-volume voice synthesis requests, making it suitable for enterprise-grade conversational AI deployments and large-scale voice automation campaigns.
**Sonic model family**: Cartesia's Sonic models, including Sonic 3.5 and the Sonic 3.6 beta, deliver state-of-the-art voice quality with improved naturalness and expressiveness for demanding voice AI applications.
## How to integrate Cartesia TTS with Bolna voice AI agents
Bolna provides seamless integration with Cartesia's text-to-speech API, enabling you to build sophisticated AI voice agents with natural-sounding speech synthesis. The integration supports real-time voice generation for various conversational AI use cases.
### Use cases for Cartesia voice synthesis in Bolna
**AI customer support automation**: Deploy Cartesia-powered voice agents that handle customer inquiries with empathetic, professional speech. The natural voice quality helps build trust and improves customer satisfaction in automated support interactions.
**Sales and lead qualification bots**: Create AI sales agents with persuasive, engaging voices that can conduct outbound calls, qualify leads, and schedule appointments. Cartesia's expressive speech synthesis makes automated sales conversations feel more human and authentic.
**Appointment scheduling and reminders**: Build voice AI systems that handle appointment booking, confirmations, and reminders with clear, friendly speech. The low-latency synthesis ensures smooth, real-time conversations.
**Healthcare voice assistants**: Develop HIPAA-compliant voice agents for patient intake, appointment scheduling, and health information delivery. Cartesia's natural voices create comfortable, trustworthy interactions in healthcare settings.
**E-commerce and order management**: Implement AI voice agents that assist with product inquiries, order tracking, and customer service. The multilingual support enables global e-commerce voice automation.
**Survey and feedback collection**: Automate survey calls and feedback collection with conversational AI agents that use natural speech to improve response rates and data quality.
### Cartesia voice configuration in Bolna
Bolna supports flexible configuration of Cartesia TTS parameters including voice selection, speaking rate, and language settings. You can configure Cartesia voices through the Bolna Playground interface or programmatically via the API for custom voice AI agent deployments.
## Supported Cartesia TTS models
Bolna supports the following Cartesia text-to-speech models for AI voice synthesis:
| Model | Description |
| --------------- | ---------------------------------------------------------------------------- |
| `sonic-3` | Stable Sonic 3 release. 42 languages |
| `sonic-3.5` | Stable Sonic 3.5 release, recommended for production agents. 42 languages |
| `sonic-preview` | Sonic 3.6 beta, shown as **Sonic 3.6 (Beta)** in the dashboard. 42 languages |
All three models work with every Cartesia voice available in Bolna.
Sonic 3.6 is in beta. Its output may change as Cartesia iterates on the model, so use `sonic-3.5` for production agents that need stable output.
## Getting started with Cartesia TTS integration
Ready to build AI voice agents with Cartesia text-to-speech? You can configure Cartesia voices through the [Bolna Playground](/docs/agent-setup/engine-tab) for quick testing or use the [Bolna API](/docs/api-reference/introduction) for programmatic integration in production applications.
To connect your own Cartesia API account, visit the [Cartesia integration page](https://platform.bolna.ai/auth/cartesia) in your Bolna dashboard.
### Compare voice synthesis providers
Explore alternative TTS providers to find the best fit for your AI voice agent requirements:
* [ElevenLabs TTS](/docs/providers/voice/elevenlabs) - Premium voice cloning and expressive synthesis
* [Deepgram TTS](/docs/providers/voice/deepgram) - Ultra-low latency voice generation
* [AWS Polly](/docs/providers/voice/aws-polly) - Cost-effective cloud-based speech synthesis
* [Azure TTS](/docs/providers/voice/azure) - Enterprise-grade multilingual voices
### Related documentation
* [Configure multilingual support](/docs/customizations/multilingual-languages-support) for global voice AI deployments
* [Voice AI agent configuration](/docs/agent-setup/engine-tab) in the Bolna Playground
* [API reference](/docs/api-reference/introduction) for programmatic voice agent creation
Cartesia TTS integration enables Bolna to deliver natural, expressive, and low-latency voice synthesis for conversational AI applications across customer support, sales automation, healthcare, and more.
# Deepgram Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/deepgram
Integrate and use your Bolna Voice AI agents with high-quality neural voices from Deepgram for natural, human-like conversational experiences.
## What is Deepgram TTS?
[Deepgram](https://deepgram.com/) Text-to-Speech (TTS) is an AI-driven speech synthesis technology designed to generate highly realistic, human-like voices. Built using deep learning models, Deepgram TTS offers natural-sounding speech output with expressive intonations, making it suitable for applications that require high-quality voice interactions.
Deepgram TTS is optimized for real-time processing and supports multiple languages, accents, and emotions, allowing businesses to deliver personalized and engaging voice experiences. Compared to traditional TTS solutions, Deepgram leverages end-to-end neural speech synthesis, reducing latency and improving the naturalness of generated speech.
## Why choose Deepgram for voice synthesis?
Deepgram TTS provides several advanced features that enhance voice AI applications:
**Human-Like Speech Output**: Produces clear, natural, and expressive speech that closely mimics human intonation and pacing.
**Real-Time Speech Generation**: Optimized for low-latency responses, ensuring a seamless conversational flow.
**Multilingual and Accent Support**: Provides high-quality speech synthesis in multiple languages, allowing for global reach.
**Noise Reduction & Clarity Enhancement**: Ensures crisp and intelligible speech output even in challenging audio environments.
## How does Bolna integrate with Deepgram TTS?
Bolna AI integrates Deepgram’s TTS technology to power its voice AI agents, enabling them to deliver lifelike speech responses during conversations. Here’s how Bolna leverages Deepgram TTS:
**Generating High-Quality Speech for AI Conversations**:
Bolna AI utilizes Deepgram TTS to convert AI-generated text responses into natural-sounding speech. This enables voice agents to interact seamlessly with users, improving engagement and usability.
**Real-Time Voice Synthesis for Smooth Interactions**:
With Deepgram’s low-latency processing, Bolna AI ensures real-time speech synthesis, eliminating delays and making voice interactions feel more natural and responsive.
**Multilingual and Accent Adaptation for Global Users**:
Bolna AI serves customers across different regions, requiring multilingual voice capabilities. Deepgram’s support for multiple languages and accents allows Bolna to offer voice AI solutions tailored to diverse user bases.
**Emotionally Expressive Speech for Personalized Interactions**:
Bolna AI leverages Deepgram’s emotion control feature to adjust the tone and expressiveness of speech output. This ensures that AI responses sound more engaging and contextually appropriate, whether for customer support, recruitment, or e-commerce applications.
**Handling Complex Pronunciations and Technical Terms**:
Deepgram TTS helps Bolna AI correctly pronounce names, technical jargon, and industry-specific terminology, ensuring clarity and accuracy in conversations.
## What Deepgram TTS models are supported?
Bolna supports the following Deepgram TTS models:
| Model |
| ------ |
| aura |
| aura-2 |
## Next steps
Ready to configure Deepgram voices for your voice AI agent? Start by [setting up your synthesizer in the Playground](/docs/agent-setup/engine-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [ElevenLabs voices](/docs/providers/voice/elevenlabs) for alternative synthesis
* Combine with [Deepgram transcriber](/docs/providers/transcriber/deepgram) for complete Deepgram integration
* Explore [Azure TTS](/docs/providers/voice/azure) for enterprise deployment
* Configure [multilingual support](/docs/customizations/multilingual-languages-support) for global reach
* You can also connect your own Deepgram account and use it with [Bolna AI](https://platform.bolna.ai/auth/deepgram)
Deepgram's advanced TTS technology enhances Bolna AI's ability to deliver realistic, engaging, and context-aware speech output in voice-driven applications.ive.
# ElevenLabs Voice Synthesis for Bolna Agents
Source: https://www.bolna.ai/docs/providers/voice/elevenlabs
Configure ElevenLabs text-to-speech in Bolna voice agents, including Turbo v2.5, Flash v2.5 and Eleven v3. Covers models, voices, streaming settings, voice cloning, and latency tuning.
[ElevenLabs](https://elevenlabs.io/) is Bolna's default voice synthesizer. The `eleven_turbo_v2_5` model delivers natural-sounding English speech with the lowest latency of any ElevenLabs model.
***
## Quick config
```json theme={"system"}
"synthesizer": {
"provider": "elevenlabs",
"provider_config": {
"voice": "Nila",
"voice_id": "V9LCAAi4tTlqe9JadbCo",
"model": "eleven_turbo_v2_5"
},
"stream": true,
"buffer_size": 250,
"audio_format": "wav"
}
```
To use your own ElevenLabs account (for voice cloning or custom voices), connect it at [platform.bolna.ai/auth/elevenlabs](https://platform.bolna.ai/auth/elevenlabs).
***
## Supported models
| Model | Best for |
| -------------------------- | -------------------------------------- |
| `eleven_turbo_v2_5` | Low-latency English (recommended) |
| `eleven_flash_v2_5` | Fastest option; slightly lower quality |
| `eleven_v3_conversational` | Most expressive; 74 languages |
`eleven_turbo_v2_5` is the standard choice for production agents. Use `eleven_flash_v2_5` when you need the absolute lowest time-to-first-audio.
`eleven_v3_conversational` is ElevenLabs' most expressive model and supports 74 languages. It ignores `speed`, `style` and `similarity_boost`, and accepts only three `temperature` values (see below).
***
## Key settings
| Setting | Type | Default | Description |
| -------------- | ------- | ------- | ----------------------------------------------------------------------------------------- |
| `voice` | string | — | Display name of the voice |
| `voice_id` | string | — | ElevenLabs voice ID (stable; use this, not the name) |
| `model` | string | — | ElevenLabs model (`eleven_turbo_v2_5`, `eleven_flash_v2_5` or `eleven_v3_conversational`) |
| `stream` | bool | `true` | Enable streaming; always `true` for real-time calls |
| `buffer_size` | integer | `250` | Characters to buffer before sending first audio chunk |
| `audio_format` | string | `wav` | Output format — match your telephony provider |
### Eleven v3 settings
`eleven_v3_conversational` takes a narrower set of voice settings than the Turbo and Flash models:
| Setting | Behaviour on v3 |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `temperature` | Maps to stability, which v3 treats as three presets: `0.0` creative, `0.5` natural, `1.0` robust. Other values are rounded to the nearest preset. |
| `speed` | Ignored |
| `style` | Ignored |
| `similarity_boost` | Ignored |
### buffer\_size guidance
`buffer_size` controls the trade-off between first-word latency and audio smoothness:
* **100–150** — fastest first word; can sound choppy if ElevenLabs response is slow
* **250** — balanced default; works well for most agents
* **400+** — smoothest speech; higher latency to first word
***
## Choosing a voice
ElevenLabs voices are identified by a `voice_id`. The `voice` name field is for reference only — Bolna uses `voice_id` to select the voice.
Browse voices in the [ElevenLabs Voice Library](https://elevenlabs.io/voice-library). Copy the voice ID from the URL or the voice details panel.
**Example voices:**
| Voice | voice\_id | Accent |
| ------ | ---------------------- | ---------------- |
| Nila | `V9LCAAi4tTlqe9JadbCo` | Neutral American |
| Rachel | `21m00Tcm4TlvDq8ikWAM` | Neutral American |
| Adam | `pNInz6obpgDQGcFmaJgB` | Neutral American |
For a custom or cloned voice, use the voice\_id from your ElevenLabs account. See [Clone Voices](/docs/clone-voices) and [Import Voices](/docs/import-voices).
***
## audio\_format by telephony provider
| Telephony | audio\_format |
| ---------- | ---------------------- |
| Plivo | `wav` |
| Exotel | `wav` |
| Twilio | `mp3` or `wav` |
| Custom SIP | match codec negotiated |
***
## FAQ
Use `eleven_turbo_v2_5` for most production agents. It has the better quality/latency balance. Use `eleven_flash_v2_5` only if your primary constraint is time-to-first-audio and you've measured that Turbo is too slow. Use `eleven_v3_conversational` when expressiveness is the priority; it is the most expressive of the three, and Turbo remains the lower-latency option.
`eleven_v3_conversational` ignores `speed`, `style` and `similarity_boost`; the model does not act on them. Only `temperature` (stability) has an effect, and it accepts three values: `0.0`, `0.5` and `1.0`. Anything else is rounded to the nearest of those. Use Turbo or Flash if you need speed control.
In the ElevenLabs dashboard, open any voice and look at the URL — the ID is the path component after `/voice/`. Alternatively, list voices via the ElevenLabs API. Always store the `voice_id`, not just the name; names can change.
Yes. Clone your voice in ElevenLabs, connect your ElevenLabs account to Bolna, then set `voice_id` to your cloned voice's ID. See [Clone Voices](/docs/clone-voices).
Increase `buffer_size` to 350–400. Choppy audio usually means the first audio chunk starts before ElevenLabs has generated enough audio to stream smoothly.
***
## Related
* [Audio Tab](/docs/agent-setup/audio-tab) — configure synthesizer in the dashboard
* [Clone Voices](/docs/clone-voices) — create a custom voice
* [Import Voices](/docs/import-voices) — use existing ElevenLabs voices
* [Cartesia](/docs/providers/voice/cartesia) — alternative low-latency synthesizer
* [Latency](/docs/concepts/latency) — how synthesis affects response time
# Maya Voice Synthesis for Bolna Agents
Source: https://www.bolna.ai/docs/providers/voice/maya
Configure Maya Research Maya 2 Native text-to-speech in Bolna voice agents. Covers voices, supported languages, mid-call language switching, and telephony audio.
[Maya Research](https://www.mayaresearch.ai/) is a text-to-speech provider built for Indian languages. The `Maya 2 Native` model streams speech over a persistent WebSocket, with two voices — **Ananya** and **Arjun** — each covering all eleven supported languages.
***
## Quick config
```json theme={"system"}
"synthesizer": {
"provider": "maya",
"provider_config": {
"voice": "Ananya",
"voice_id": "Ananya",
"model": "Maya 2 Native",
"language": "en"
},
"stream": true,
"buffer_size": 400
}
```
***
## Supported voices
Maya has two voices. Both speak every supported language — voice and language are chosen independently.
| Voice | Gender |
| -------- | ------ |
| `Ananya` | Female |
| `Arjun` | Male |
Voice matching is case-sensitive on Maya's side — `ananya` is rejected. Bolna normalizes casing for you, so `voice: "ananya"` still resolves to `Ananya`.
***
## Supported languages
| `language` | Language |
| ---------- | --------------------------------------- |
| `hi` | Hindi |
| `bn` | Bengali |
| `gu` | Gujarati |
| `kn` | Kannada |
| `ml` | Malayalam |
| `mr` | Marathi |
| `or` | Odia |
| `pa` | Punjabi |
| `ta` | Tamil |
| `te` | Telugu |
| `en` | Indian English |
| `auto` | Maya detects the language per utterance |
Region-qualified ASR codes like `hi-IN` are trimmed down to the primary subtag (`hi`) automatically. This is also how Bolna switches Maya's language mid-call — a fresh config frame goes out over the same WebSocket, so the call never reconnects.
***
## Key settings
| Setting | Type | Default | Description |
| ------------- | ------- | --------------- | ------------------------------------------------------------------------------- |
| `voice` | string | `Ananya` | `Ananya` or `Arjun` |
| `voice_id` | string | — | Accepted alongside `voice` so configs shaped like other providers still resolve |
| `model` | string | `Maya 2 Native` | Maya's TTS model |
| `language` | string | `en` | One of the codes above; `auto` lets Maya detect it per utterance |
| `stream` | bool | `false` | Enable streaming over the persistent WebSocket |
| `buffer_size` | integer | `400` | Characters buffered before the first chunk is sent |
***
## How streaming works
A call runs on a single persistent WebSocket connection. Sentence segmentation happens on Maya's side, so LLM output is forwarded to Maya as it arrives — Bolna does no client-side chunking of the text.
Maya only closes out a turn on a `flush`, so every text fragment is sent as non-final. If the LLM's final piece of text for a turn is empty, Bolna sends a single whitespace character before the flush — otherwise Maya never emits an end-of-turn event and the turn does not close.
On interruption, Bolna sends a `clear` frame and drops any audio frames that keep arriving until Maya confirms with `cancelled`.
***
## Audio output
Maya streams audio at 24 kHz throughout. Bolna handles the conversion depending on where the audio is going:
* **Telephony** — downsampled to 8 kHz and mu-law encoded
* **Web** — left at Maya's native 24 kHz, no resampling
Handoff and prewarm clips are generated with a one-shot HTTP call rather than the WebSocket. On telephony configs, this HTTP response is converted straight to mu-law in-process, skipping the usual transcode step.
***
## FAQ
Both voices cover all eleven supported languages, so the choice is purely about which voice fits your agent's persona — `Ananya` (female) or `Arjun` (male).
Yes. Set `language` to the code you need, or use `auto` to let Maya detect it per utterance. Bolna sends language switches as a config update over the existing WebSocket, so the call never reconnects.
No. Codes like `hi-IN` are automatically reduced to the primary subtag (`hi`) that Maya expects.
Yes. Bolna downsamples and mu-law encodes Maya's audio for telephony, and leaves it at native 24 kHz for web.
***
## Related
* [Audio Tab](/docs/agent-setup/audio-tab) — configure synthesizer in the dashboard
* [Sarvam](/docs/providers/voice/sarvam) — alternative Indian-language synthesizer
* [ElevenLabs](/docs/providers/voice/elevenlabs) — Bolna's default English synthesizer
* [Multilingual support](/docs/customizations/multilingual-languages-support) — configuring language switching
* [Latency](/docs/concepts/latency) — how synthesis affects response time
# Rime Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/rime
Integrate Rime TTS with Bolna Voice AI agents for ultra-fast, expressive speech synthesis with sub-200ms latency and diverse conversational voice options.
## What is Rime TTS?
[Rime](https://www.rime.ai/) TTS is an advanced AI-powered speech synthesis platform designed to deliver **ultra-fast, highly expressive, and natural-sounding voices** for conversational AI applications. Rime provides speech synthesis technologies that perfectly balance quality, customizability, and speed for building conversational applications.
Rime TTS is specifically optimized for **real-time conversational AI**, offering **sub-200 millisecond speech synthesis speeds** with their flagship models. With a focus on **emotional expressiveness, demographic diversity, and lightning-fast processing**, Rime TTS enables enterprises to create **engaging, responsive, and human-like voice interactions** across various industries and use cases.
## Why choose Rime for voice synthesis?
Rime TTS provides several cutting-edge features that enhance conversational AI applications:
**Ultra-Fast Speech Synthesis**: Delivers sub-200 millisecond synthesis speeds, with Mist v2 achieving \~70ms latency for real-time applications.
**Highly Expressive Speech Output**: Arcana model pushes the boundary of naturalness and emotional depth in synthesized speech with fine-grained prosody control.
**Multilingual and Demographic Diversity**: Supports multiple languages (English, Spanish, with more coming soon) and offers voices across many different demographic categories including age ranges, accents, and cultural backgrounds.
**Wide Range of Voice Options**: Features flagship voices like luna, celeste, orion, ursa, astra, esther, estelle, and andromeda across different speaking styles and demographics.
**Genre-Specific Optimization**: Provides specialized models for General, Conversational, Narration, and IVR use cases.
**Advanced Pronunciation Control**: Offers sophisticated control over speech performance using linguistically-aware markup and contextual nuances.
**Real-Time Processing Capabilities**: Engineered specifically for interactive applications requiring instant voice responses.
## How does Bolna integrate with Rime TTS?
Bolna AI leverages Rime's cutting-edge TTS technology to create ultra-responsive, engaging, and lifelike voice responses for its AI-powered conversational agents. Here's how Bolna AI integrates Rime TTS:
**Ultra-Fast Voice Output for Real-Time Conversations**:
Bolna AI utilizes Rime's industry-leading synthesis speeds to ensure that its AI-driven voice agents deliver instantaneous responses during live interactions. With sub-200ms latency, Bolna eliminates unnatural delays and creates seamless conversational flow that feels natural and responsive.
**Highly Expressive Speech for Enhanced User Engagement**:
Bolna AI takes advantage of Rime's Arcana model to produce emotionally nuanced and expressive speech output. This enables AI agents to adjust their tone and emotional delivery based on conversation context, creating more engaging and human-like interactions.
**Diverse Voice Demographics for Global Accessibility**:
To serve diverse customer bases, Bolna AI utilizes Rime's wide range of voice demographics and accents, ensuring clear communication across different user populations. This demographic diversity helps businesses create more inclusive and accessible voice AI experiences.
**Multilingual Support for International Applications**:
Bolna AI leverages Rime's multilingual capabilities (English, Spanish, with expanding language support) to provide voice AI solutions that can serve global markets with native-sounding speech in multiple languages.
**Genre-Optimized Speech for Specific Use Cases**:
Bolna AI integrates Rime's genre-specific optimizations to deliver contextually appropriate speech output. For example:
* **Customer Support Agents**: Use conversational-optimized voices that sound empathetic and professional during support interactions.
* **Recruitment AI Assistants**: Employ general-purpose voices with neutral yet engaging tones for job-related communications.
* **E-commerce AI Representatives**: Utilize expressive voices that can adapt tone to enhance user engagement and sales conversations.
* **IVR Systems**: Deploy IVR-optimized voices for clear, professional automated phone system interactions.
**Advanced Prosody Control for Brand Customization**:
For businesses looking to create distinctive voice experiences, Bolna AI integrates Rime's advanced prosody and pronunciation controls, enabling fine-tuned speech output that aligns with specific brand personalities and communication styles.
## What Rime TTS models are supported?
Bolna supports the following Rime TTS models:
| Model |
| ------ |
| arcana |
| mistv2 |
## Next steps
Ready to configure ultra-fast Rime voices for your voice AI agent? Start by [setting up your synthesizer in the Playground](/docs/agent-setup/engine-tab) or explore our [API documentation](/docs/api-reference/introduction) for programmatic integration.
For related integrations:
* Compare with [ElevenLabs voices](/docs/providers/voice/elevenlabs) for alternative expressive synthesis
* Explore [Cartesia voices](/docs/providers/voice/cartesia) for another fast TTS option
* Review [Deepgram voices](/docs/providers/voice/deepgram) for low-latency alternatives
* Configure [multilingual support](/docs/customizations/multilingual-languages-support) for global reach
* You can also connect your own Rime account and use it with [Bolna AI](https://platform.bolna.ai/auth/rime)
By integrating Rime TTS, Bolna AI significantly enhances its conversational AI capabilities, delivering ultra-fast, expressive, and demographically diverse voice output.
# Sarvam Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/sarvam
Integrate and use your Bolna Voice AI agents with high-quality neural voices from Sarvam for natural, human-like conversational experiences.
## 1. What is Sarvam TTS?
[Sarvam](https://www.sarvam.ai/) TTS is a high-performance text-to-speech service developed by Sarvam AI, designed specifically for Indian languages. It delivers natural and expressive voice synthesis optimized for conversational use cases such as virtual assistants, IVRs, and customer support bots. Built using advanced generative AI techniques, Sarvam TTS offers real-time streaming capabilities and supports deployment at scale across multilingual environments.
## 2. Key Features of Sarvam TTS
Sarvam TTS provides several advanced features that enhance Bolna Voice AI applications:
**Multilingual Support**: Specially optimized for Indian languages such as Hindi, Telugu, Tamil, Kannada, and more.
**Natural-Sounding Voices**: Trained on diverse datasets to produce lifelike speech with proper intonation and pronunciation.
**Low Latency Streaming**: Designed for real-time use cases, ensuring smooth conversational flow in interactive systems.
**Custom Voice Options**: Ability to fine-tune or adapt voices for enterprise-specific needs.
## 3. How Bolna Uses Sarvam for TTS
Bolna Voice AI integrates Sarvam TTS to power Indian-language voice agents across recruitment, sales, and support workflows. The TTS system is used to generate real-time voice prompts, questions, and responses in native languages, ensuring better engagement and understanding, especially in Tier 2/3 regions.
**Real-Time Speech for Seamless Conversations**:
Sarvam’s low-latency streaming capabilities enable Bolna agents to synthesize speech in real time. This ensures a smooth, uninterrupted flow of conversation, making interactions feel natural and responsive for users.
**Multilingual & Accent-Aware Voice Support**:
Bolna uses Sarvam to serve candidates and customers in Hindi, Telugu, Tamil, and other Indian languages. The multilingual support allows each voice agent to adapt to the preferred language and accent of the user, improving comprehension and engagement—especially in Tier 2/3 regions.
**Handling Complex Pronunciations and Technical Terms**:
From candidate names to role-specific jargon, Sarvam TTS enables accurate pronunciation of complex or technical terms. This ensures that Bolna’s agents sound professional and easy to understand across varied use cases.
## 4. List of Sarvam TTS models supported on Bolna AI
| Model |
| ----------- |
| `bulbul:v3` |
| `bulbul:v2` |
| `bulbul:v1` |
## Conclusion
Sarvam TTS brings localized voice synthesis to the forefront of conversational AI in India. By integrating Sarvam, Bolna ensures its voice agents are not only intelligent but also relatable and linguistically inclusive. This helps improve candidate experience, increase response rates, and expand accessibility across diverse demographics.
For related integrations:
* You can also connect your own Sarvam account and use it with [Bolna AI](https://platform.bolna.ai/auth/sarvam)
# Smallest Text to Speech with Bolna Voice AI agents
Source: https://www.bolna.ai/docs/providers/voice/smallest
Integrate and use Smallest voices with Bolna Voice AI agents for lightweight and efficient text-to-speech solutions.
## 1. What is Smallest TTS?
[Smallest AI](https://smallest.ai/) TTS is an ultra-lightweight, high-efficiency speech synthesis engine designed for low-resource environments and edge computing applications. Unlike traditional cloud-based TTS solutions, Smallest AI focuses on delivering **fast, memory-efficient, and locally deployable speech synthesis** without sacrificing voice quality. It is ideal for AI-driven systems that require **real-time voice synthesis** on resource-constrained devices, such as mobile applications, IoT devices, and offline virtual assistants.
## 2. Key Features of Smallest TTS
Smallest AI TTS offers several unique features that make it an attractive option for AI-driven voice interactions:
**Lightweight and Efficient**: Optimized for low-power devices, embedded systems, and mobile applications, ensuring smooth performance on minimal hardware.
**Low-Latency, Real-Time Speech Generation**: Unlike cloud-based TTS solutions, Smallest AI offers instant voice synthesis with near-zero delay.
**Offline and On-Device Processing**: Supports fully offline speech generation without requiring an internet connection.
**Neural Compression for Compact Model Size**: Uses advanced compression techniques to reduce the model footprint while maintaining high-quality speech output.
**Multilingual Support with Minimal Resource Consumption**: Provides high-quality voice synthesis across multiple languages without requiring large storage or compute resources.
## 3. How Bolna Uses Smallest for TTS
Bolna AI integrates Smallest AI’s ultra-efficient speech synthesis technology to enhance its real-time conversational AI experience, particularly in low-resource and privacy-sensitive environments. Here’s how Bolna leverages Smallest AI TTS:
**Lightning-Fast Voice Responses for Instant AI Interactions**:
With Smallest AI’s low-latency TTS, Bolna ensures that its voice agents respond instantly, making interactions feel seamless, natural, and fluid.
**Efficient Multilingual Speech Processing with Minimal Compute**:
Bolna AI utilizes Smallest AI’s multilingual synthesis to generate speech without the overhead of large AI models, making it scalable for voice automation across multiple regions and languages.
**Customizable Voices for Enterprise Branding**:
Smallest AI supports lightweight, trainable voice models, allowing Bolna AI to provide custom-branded voices for businesses, ensuring a unique and recognizable AI-driven voice identity.
## 4. List of Smallest models supported on Bolna AI
| Model |
| ------------ |
| lightning-v2 |
## Conclusion
Smallest AI TTS enhances Bolna AI’s ability to deliver **ultra-fast voice interactions**. By integrating **Smallest AI’s lightweight and highly efficient speech synthesis**, Bolna ensures seamless **real-time AI conversations with low-latency responses**. This makes Bolna’s AI voice agents highly scalable for industries requiring **compact, high-performance voice AI solutions in customer service, healthcare and enterprise automation**.
# API Quickstart
Source: https://www.bolna.ai/docs/quickstarts/api
Make your first Voice AI call with the Bolna API — verify your key, get an agent, place a call, and fetch the transcript in about five minutes.
Go from an API key to a real phone call (with a transcript and recording) in four steps. Every request below uses the production base URL `https://api.bolna.ai` and Bearer authentication.
Don't have a key yet? Follow [Generate an API key](/docs/api-reference/introduction) first, then come back here. Telephone calls consume wallet credits, so keep a test number handy.
## Prerequisites
* A Bolna API key (`Authorization: Bearer `)
* A recipient phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format, e.g. `+919876543210`
* `curl`, or Python 3, or Node 18+
Set your key as an environment variable so it's not pasted into every command:
```bash theme={"system"}
export BOLNA_API_KEY="bn-xxxxxxxxxxxxxxxx"
```
A quick read-only call confirms the key works and shows your wallet balance and concurrency limit before you spend any credits.
```bash curl theme={"system"}
curl https://api.bolna.ai/user/me \
-H "Authorization: Bearer $BOLNA_API_KEY"
```
```python Python theme={"system"}
import os, urllib.request, json
key = os.environ["BOLNA_API_KEY"]
req = urllib.request.Request(
"https://api.bolna.ai/user/me",
headers={"Authorization": f"Bearer {key}"},
)
print(json.load(urllib.request.urlopen(req)))
```
```javascript Node theme={"system"}
const res = await fetch("https://api.bolna.ai/user/me", {
headers: { Authorization: `Bearer ${process.env.BOLNA_API_KEY}` },
});
console.log(await res.json());
```
A successful response returns your account details:
```json theme={"system"}
{
"id": "…",
"name": "Bruce Wayne",
"email": "bruce@example.com",
"wallet": 42.42,
"concurrency": { "max": 10, "current": 0 }
}
```
A `401 Access denied` means the key is wrong or missing the `Bearer ` prefix.
You need an `agent_id` to make a call. Pick one path:
Create an agent once in the [dashboard](https://platform.bolna.ai) (Auto Build is quickest), open it, and copy the agent ID from the URL or the agent settings. Then:
```bash theme={"system"}
export BOLNA_AGENT_ID="your-agent-id"
```
This is the most reliable way to finish the quickstart, because the full agent configuration is large.
Create a minimal English conversation agent programmatically. This body is intentionally complete so it works on default providers — adjust providers, voice, and language as needed.
```bash curl theme={"system"}
curl https://api.bolna.ai/v2/agent \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_config": {
"agent_name": "Quickstart Agent",
"agent_welcome_message": "Hi! This is a quick test call from Bolna. How is your day going?",
"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 friendly assistant making a short test call. Keep every reply under two sentences. Greet the person, ask how their day is going, thank them, then end the call politely." }
}
}'
```
```json Response theme={"system"}
// HTTP 201 Created
{ "agent_id": "123e4567-e89b-12d3-a456-426655440000", "state": "created" }
```
Save the returned `agent_id` for the next step.
Pass your `agent_id` and the recipient's number. Omit `from_phone_number` to use Bolna's default number, or set it to one of your purchased numbers.
```bash curl theme={"system"}
curl https://api.bolna.ai/call \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "'"$BOLNA_AGENT_ID"'",
"recipient_phone_number": "+919876543210"
}'
```
```python Python theme={"system"}
import os, urllib.request, json
body = json.dumps({
"agent_id": os.environ["BOLNA_AGENT_ID"],
"recipient_phone_number": "+919876543210",
}).encode()
req = urllib.request.Request(
"https://api.bolna.ai/call",
data=body,
headers={"Authorization": f"Bearer {os.environ['BOLNA_API_KEY']}",
"Content-Type": "application/json"},
)
print(json.load(urllib.request.urlopen(req)))
```
```javascript Node theme={"system"}
const res = await fetch("https://api.bolna.ai/call", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BOLNA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
agent_id: process.env.BOLNA_AGENT_ID,
recipient_phone_number: "+919876543210",
}),
});
console.log(await res.json());
```
The response returns an `execution_id` you'll use to track the call:
```json theme={"system"}
{ "message": "done", "status": "queued", "execution_id": "123e4567-e89b-12d3-a456-426614174000" }
```
Your phone should ring within a few seconds.
Poll the execution until it finishes. Bolna fires a `call-disconnected` event the instant the line drops, then a final `completed` event a few seconds later once duration, cost, recording, and the AI call summary are finalized — so **wait for `completed`** (or a hard-failure status like `no-answer`, `busy`, `failed`) rather than stopping at `call-disconnected`, or you'll read a half-populated payload with `conversation_duration: 0`. The completed execution includes the full transcript, recording URL, duration, cost breakdown, and `extracted_data`.
```bash curl theme={"system"}
curl https://api.bolna.ai/executions/EXECUTION_ID \
-H "Authorization: Bearer $BOLNA_API_KEY"
```
```python Python theme={"system"}
import os, time, urllib.request, json
key = os.environ["BOLNA_API_KEY"]
exec_id = "EXECUTION_ID"
final = {"completed","no-answer","busy","failed","canceled","stopped","error","balance-low"}
while True:
req = urllib.request.Request(
f"https://api.bolna.ai/executions/{exec_id}",
headers={"Authorization": f"Bearer {key}"},
)
data = json.load(urllib.request.urlopen(req))
print("status:", data["status"])
if data["status"] in final: # wait for 'completed', not 'call-disconnected'
print(data.get("transcript"))
break
time.sleep(5)
```
```javascript Node theme={"system"}
const key = process.env.BOLNA_API_KEY;
const execId = "EXECUTION_ID";
const final = new Set(["completed","no-answer","busy","failed","canceled","stopped","error","balance-low"]);
while (true) {
const res = await fetch(`https://api.bolna.ai/executions/${execId}`, {
headers: { Authorization: `Bearer ${key}` },
});
const data = await res.json();
console.log("status:", data.status);
if (final.has(data.status)) { console.log(data.transcript); break; } // not call-disconnected
await new Promise(r => setTimeout(r, 5000));
}
```
```json Completed execution (truncated) theme={"system"}
{
"id": "b7140255-af33-4608-8e97-04dd944b8e48",
"agent_id": "5bc97541-e320-4d95-a3a5-242cfe45621d",
"status": "completed",
"conversation_duration": 16,
"total_cost": 3.23,
"transcript": "assistant: Hi! How is your day going?\nuser: …",
"user_number": "+919876543210",
"agent_number": "+918035739222",
"extracted_data": { "General": { "Call Summary": { "subjective": "…", "confidence_label": "High" } } },
"telephony_data": {
"duration": 16,
"recording_url": "https://api.bolna.ai/recordings/call/b7140255-af33-4608-8e97-04dd944b8e48",
"call_type": "outbound",
"provider": "plivo",
"hangup_by": "Plivo",
"hangup_reason": "inactivity_timeout",
"to_number_carrier": "Bharat Sanchar Nigam Ltd (BSNL)"
},
"cost_breakdown": { "platform": 2, "network": 1, "transcriber": 0.23, "llm": 0, "synthesizer": 0 },
"latency_data": { "time_to_first_audio": 189.69 }
}
```
For production, don't poll — register a [webhook](/docs/guides/post-call/polling-call-status-webhooks) to receive the execution payload automatically when the call ends.
## Alternative: receive results via webhook
Polling is fine for a quickstart, but in production you don't want to hammer the API. Instead, give your agent a `webhook_url` and Bolna will **POST the execution payload to your server** as the call progresses — same JSON shape as Step 4.
Your endpoint must be publicly reachable over HTTPS and return `200` quickly. For local testing, run a small receiver and expose it with a tunnel:
```bash theme={"system"}
python3 bolna_webhook_server.py # listens on :8080, prints every payload
ngrok http 8080 # gives you https://.ngrok.app
```
Bolna sends webhooks from a fixed IP — **whitelist `13.203.39.153`** on your server or firewall so events aren't dropped.
Set `webhook_url` inside `agent_config` when creating (or updating) the agent. With the test harness:
```bash theme={"system"}
python3 bolna_quickstart_test.py --to "+919876543210" \
--webhook-url "https://.ngrok.app/webhook"
```
Or set it in the dashboard under the [Extractions Tab](/docs/agent-setup/analytics-tab) — "Push all execution data to webhook".
Make the call as in Step 3. Your endpoint receives a POST each time the status changes (`queued → in-progress → completed/call-disconnected`), with the full transcript on the final event.
Bolna sends **several POSTs per call** as the status changes. Two land near the end: `call-disconnected` fires the instant the line drops (with `conversation_duration: 0`, no recording, no summary), then `completed` arrives a few seconds later with the finalized duration, cost, `recording_url`, and `extracted_data`. **Treat `completed` as "call is done"** — along with hard-failure statuses (`no-answer`, `busy`, `failed`). The same URL may also receive in-progress / pre-call webhooks; tell them apart by `status`. See [Webhooks](/docs/guides/post-call/polling-call-status-webhooks).
## Run the whole flow as one script
The complete, dependency-free Python script runs all four steps end to end:
```bash theme={"system"}
export BOLNA_API_KEY="bn-xxxx"
# optional: export BOLNA_AGENT_ID="..." to reuse a dashboard agent
python3 bolna_quickstart_test.py --to "+919876543210"
```
Add `--dry-run` to print the exact request bodies without making any network calls.
## Next steps
Pass `user_data` variables like `{customer_name}` into the call body.
Upload a CSV and run a batch campaign instead of single calls.
Get the execution payload pushed to your server when a call ends.
Every field you can set when creating an agent.
# Batch Calling Quickstart
Source: https://www.bolna.ai/docs/quickstarts/batch
Call a list of people in one campaign — upload a CSV of recipients with per-row variables, schedule the batch, and fetch every call's result.
The [API Quickstart](/docs/quickstarts/api) makes one call. This guide scales that to a **campaign**: upload a CSV of recipients (each with their own variables), schedule the batch, and pull back per-call results. It reuses the agent and execution concepts from the outbound quickstart, so start there if you haven't.
You'll need an `agent_id` (see the [API Quickstart](/docs/quickstarts/api)) and enough wallet balance for the number of rows in your CSV.
## Prerequisites
* `export BOLNA_API_KEY="bn-xxxx"` and `export BOLNA_AGENT_ID="your-agent-id"`
* A CSV with a **`contact_number`** column (required). Any other columns become `{variable}` values your prompt and welcome message can use.
Reference CSV columns in the [Agent Tab](/docs/agent-setup/agent-tab) with `{column_name}` — e.g. a `customer_name` column lets your welcome message say "Hi ".
## The CSV
```csv batch.csv theme={"system"}
contact_number,customer_name,appointment_day
+919876543210,Asha,Friday
+919812345678,Ravi,Monday
```
Only `contact_number` is mandatory; `customer_name` and `appointment_day` are example variables.
Upload the CSV with your `agent_id` as `multipart/form-data`.
```bash curl theme={"system"}
curl https://api.bolna.ai/batches \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-F "agent_id=$BOLNA_AGENT_ID" \
-F "file=@batch.csv"
```
```python Python theme={"system"}
import os, requests # pip install requests, or see the stdlib script below
r = requests.post(
"https://api.bolna.ai/batches",
headers={"Authorization": f"Bearer {os.environ['BOLNA_API_KEY']}"},
data={"agent_id": os.environ["BOLNA_AGENT_ID"]},
files={"file": ("batch.csv", open("batch.csv", "rb"), "text/csv")},
)
print(r.status_code, r.json())
```
```json Response theme={"system"}
// HTTP 201 Created
{ "batch_id": "abcdefghijklmnopqrstuvwxyz012345", "state": "created" }
```
Save the `batch_id`.
A created batch doesn't call anyone until it's scheduled. Pass `scheduled_at` as an **ISO 8601 timestamp with a numeric UTC offset** (e.g. `+00:00`). Two API rules that aren't obvious:
* The time must be **at least 2 minutes in the future**, or you get a `400`.
* Use a numeric offset like `+00:00` — the `Z` suffix is **rejected** with a `500`.
* Bolna **rounds the start up to the next 10-minute mark**, so a `12:02` request runs at `12:10`.
```bash curl theme={"system"}
curl https://api.bolna.ai/batches/BATCH_ID/schedule \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-F "scheduled_at=2026-06-23T18:30:00+00:00"
```
```python Python theme={"system"}
import os, requests
from datetime import datetime, timezone, timedelta
# isoformat() emits the +00:00 offset the API expects; min 2 minutes out
when = (datetime.now(timezone.utc) + timedelta(minutes=3)).replace(microsecond=0).isoformat()
r = requests.post(
f"https://api.bolna.ai/batches/{os.environ['BATCH_ID']}/schedule",
headers={"Authorization": f"Bearer {os.environ['BOLNA_API_KEY']}"},
data={"scheduled_at": when},
)
print(r.status_code, r.json())
```
```json Response theme={"system"}
{ "message": "success", "state": "scheduled at 2026-06-23T07:00:00+00:00" }
```
Outbound time-of-day restrictions still apply per recipient timezone. If a scheduled time falls outside the allowed window, calls are pushed to the next allowed slot. See [Calling Guardrails](/docs/guides/outbound/calling-guardrails).
Poll the batch for its status, then list per-call executions once it's running or done.
```bash status theme={"system"}
curl https://api.bolna.ai/batches/BATCH_ID \
-H "Authorization: Bearer $BOLNA_API_KEY"
```
```bash executions theme={"system"}
curl https://api.bolna.ai/batches/BATCH_ID/executions \
-H "Authorization: Bearer $BOLNA_API_KEY"
```
Each execution in the list is a standard [execution object](/docs/api-reference/executions/get_execution) — `status`, `transcript`, `total_cost`, `telephony_data`, `extracted_data`, etc. — one per row in your CSV. The batch object tracks overall progress; `status` moves `created → scheduled → running → completed`.
```json GET /batches/{batch_id} theme={"system"}
{
"batch_id": "c4e37bb6…",
"status": "running",
"scheduled_at": "2026-06-23T07:00:00+00:00",
"valid_contacts": 1,
"total_contacts": 1,
"file_name": "batch.csv",
"execution_status": { "completed": 1 }
}
```
```json GET /batches/{batch_id}/executions (bare array) theme={"system"}
[
{
"id": "1ae3e573-…",
"status": "completed",
"user_number": "+919876543210",
"conversation_duration": 18.0,
"total_cost": 3.26,
"transcript": "assistant: Hi! …",
"context_details": {
"recipient_data": { "customer_name": "Asha", "appointment_day": "Friday" }
},
"telephony_data": { "recording_url": "https://api.bolna.ai/recordings/call/1ae3e573-…" }
}
]
```
The execution's `context_details.recipient_data` echoes back the CSV columns for that row — confirming your `{variables}` reached the call. Per-call `status` starts at `prepared` before the call is placed, then becomes `completed` (or `no-answer`, `busy`, `failed`).
## Run the whole flow as one script
The dependency-free `bolna_batch_test.py` script does all of the above — builds a sample CSV (or takes your own), creates the batch, schedules it, polls, and prints per-call results:
```bash theme={"system"}
export BOLNA_API_KEY="bn-xxxx"
export BOLNA_AGENT_ID="your-agent-id"
python3 bolna_batch_test.py --dry-run --to "+919876543210" --name "Asha" # inspect first
python3 bolna_batch_test.py --to "+919876543210" --name "Asha" # real campaign
python3 bolna_batch_test.py --csv my-recipients.csv # your own list
```
## Managing batches
| Action | Endpoint |
| ----------------------------- | ------------------------------------ |
| Stop a running batch | `POST /batches/{batch_id}/stop` |
| Get one batch | `GET /batches/{batch_id}` |
| List a batch's calls | `GET /batches/{batch_id}/executions` |
| List all batches for an agent | `GET /batches/{agent_id}/all` |
| Delete a batch | `DELETE /batches/{batch_id}` |
## Next steps
Use CSV columns as `{variables}` in your prompt and welcome message.
Get each call's payload pushed to you instead of polling.
Auto-capture lead quality, outcomes, and more from every call.
The outbound quickstart this builds on.
# Inbound Quickstart
Source: https://www.bolna.ai/docs/quickstarts/inbound
Point a phone number at a Bolna agent so it answers incoming calls — list your numbers, link an agent, and test the call in a few minutes.
The [API Quickstart](/docs/quickstarts/api) covers *outbound* calls. This guide does the mirror image: make an agent **answer** calls. You'll link one of your phone numbers to an agent so every inbound call is picked up automatically.
You need a phone number on your account first. Buy one from the [dashboard](https://platform.bolna.ai) or via `POST /phone-numbers/buy`, or bring your own through [SIP trunking](/docs/sip-trunking/introduction). Indian numbers also require [compliance](/docs/compliance-application/introduction).
## Prerequisites
* A Bolna API key (`export BOLNA_API_KEY="bn-xxxx"`)
* An `agent_id` to answer calls (create one via the [API Quickstart](/docs/quickstarts/api) or the dashboard)
* At least one phone number on your account
For inbound, give the agent an *inbound-appropriate* welcome message — e.g. "Thanks for calling Acme, how can I help?" — rather than an outbound opener.
The link call needs the number's `id`, not the number itself. List your numbers:
```bash curl theme={"system"}
curl https://api.bolna.ai/phone-numbers/all \
-H "Authorization: Bearer $BOLNA_API_KEY"
```
```python Python theme={"system"}
import os, urllib.request, json
req = urllib.request.Request(
"https://api.bolna.ai/phone-numbers/all",
headers={"Authorization": f"Bearer {os.environ['BOLNA_API_KEY']}"},
)
for n in json.load(urllib.request.urlopen(req)):
print(n["phone_number"], n["id"], n["telephony_provider"])
```
```json Response (array) theme={"system"}
[
{
"id": "3c90c3cc0d444b5088888dd25736052a",
"phone_number": "+19876543210",
"telephony_provider": "twilio",
"agent_id": null
}
]
```
Copy the `id` of the number you want to use.
Associate your agent with the phone number. After this, inbound calls to that number are answered by the agent.
```bash curl theme={"system"}
curl https://api.bolna.ai/inbound/setup \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "YOUR_AGENT_ID",
"phone_number_id": "3c90c3cc0d444b5088888dd25736052a"
}'
```
```python Python theme={"system"}
import os, urllib.request, json
body = json.dumps({
"agent_id": os.environ["BOLNA_AGENT_ID"],
"phone_number_id": "3c90c3cc0d444b5088888dd25736052a",
}).encode()
req = urllib.request.Request(
"https://api.bolna.ai/inbound/setup",
data=body,
headers={"Authorization": f"Bearer {os.environ['BOLNA_API_KEY']}",
"Content-Type": "application/json"},
)
print(json.load(urllib.request.urlopen(req)))
```
```json Response theme={"system"}
{
"url": "https://api.bolna.ai/inbound_call?agent_id=…&user_id=…",
"phone_number": "+19876543210",
"id": "3c90c3cc0d444b5088888dd25736052a"
}
```
Dial the number from any phone — your agent answers with its welcome message and starts the conversation. After the call, retrieve the transcript exactly like outbound: poll [`GET /executions/{id}`](/docs/api-reference/executions/get_execution) or use a [webhook](/docs/guides/post-call/polling-call-status-webhooks).
## Optional: IVR routing
For Plivo numbers you can add an `ivr_config` to the same `POST /inbound/setup` request to play a menu and route callers to different agents (by department, language, etc.). See [IVR for Inbound Calls](/docs/guides/inbound/ivr-inbound-calls).
## Unlink a number
To stop an agent from answering a number, call [`POST /inbound/unlink`](/docs/api-reference/inbound/unlink) with the phone number ID.
## Run the setup as a script
The dependency-free helper script automates listing numbers and linking the agent:
```bash theme={"system"}
export BOLNA_API_KEY="bn-xxxx"
export BOLNA_AGENT_ID="your-agent-id"
python3 bolna_inbound_setup.py # auto-pick your first number
python3 bolna_inbound_setup.py --list # just list numbers
python3 bolna_inbound_setup.py --dry-run
```
## Next steps
Match incoming numbers to your CRM and preload customer data.
Spam prevention, caller matching, and call limits.
Route callers to different agents with a keypad menu.
Use your existing carrier numbers for inbound.
# Web Call SDK
Source: https://www.bolna.ai/docs/sdks/web-call
Drop live, spoken conversations with a Bolna voice agent into any web page. One class, six events, no telephony expertise required.
`@bolna/web-call` · **v3.0.0** · Source: [github.com/bolna-ai/web-call](https://github.com/bolna-ai/web-call)
In beta and available for any account on request. Reach out on [Slack](https://join.slack.com/t/bolnabuilders/shared_invite/zt-42zi57jyd-3yt1XDWq3kWBLj1puqq2fQ) or email [support@bolna.dev](mailto:support@bolna.dev) to have it enabled.
## Overview
The Web Call SDK connects a browser tab directly to a Bolna voice agent for a live, two-way conversation. You render your own UI, and the SDK handles everything else: asking for mic access, connecting the call, and cleaning up when it ends.
You get a small state machine, six events, and a handful of methods. No telephony or real-time-audio background required.
```mermaid theme={"system"}
sequenceDiagram
participant Browser as Browser (SDK)
participant Agent as Bolna Voice AI (your agent)
Browser->>Agent: 1. start()
Note over Browser: Handles mic access, and audio quality
Agent-->>Browser: 2. live, two-way audio
```
## Install
```bash npm theme={"system"}
npm install @bolna/web-call
```
```javascript import theme={"system"}
import { BolnaWebCall } from "@bolna/web-call";
```
**CDN / plain `
```
## Set up your backend
The browser side of this SDK never sees your Bolna API key (the `bn-…` key). Anyone reading your page source could lift a key that's exposed client-side and place calls on your account, so the SDK is built so that key never has a reason to be there.
Instead, the browser requests a **short-lived, single-use call session** from your own backend: a set of connection credentials that expire in roughly 120 seconds and are consumed the moment the first call uses them.
```mermaid theme={"system"}
sequenceDiagram
participant Browser
participant Backend as Your backend
participant Bolna as Bolna mint endpoint
Browser->>Backend: POST /api/bolna-session
Backend->>Bolna: mint session (your bn- key)
Bolna-->>Backend: session credentials
Backend-->>Browser: ephemeral session (~120s TTL, TURN creds)
```
Your backend route is a thin proxy. It calls Bolna's session-mint endpoint with your key server-side, then returns the JSON unchanged:
```javascript Node/Express theme={"system"}
// put YOUR auth in front of this route
app.use(express.json());
app.post("/api/bolna-session", async (req, res) => {
// illustrative URL: swap in your actual Bolna session-mint endpoint
const r = await fetch("https://api.bolna.ai/v1/web-call/session", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BOLNA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
agent_id: process.env.BOLNA_AGENT_ID,
user_data: req.body.user_data, // forwarded from the browser's userData
}),
});
res.status(r.status).json(await r.json());
});
```
In `sessionUrl` mode, the SDK POSTs `{ "user_data": {...} }` to this route automatically whenever you set `userData`. Your route must forward it to Bolna's mint endpoint, like above — if it doesn't, `userData` is silently dropped and never reaches the agent.
**Why there's no `apiKey` option:** the SDK deliberately can't take a Bolna API key. A minted session expires in about 2 minutes, and its credential is consumed by the first call, so leaking one buys an attacker almost nothing.
## Quickstart
Once your backend exposes a session-minting route, the browser side comes down to three steps: create the call, listen for the events you care about, and start it from a click handler.
```javascript theme={"system"}
import { BolnaWebCall } from "@bolna/web-call";
const call = new BolnaWebCall({ sessionUrl: "/api/bolna-session" });
call.on("call-start", () => console.log("agent connected"));
call.on("call-end", ({ reason }) => console.log("ended:", reason));
call.on("error", (e) => console.error(e.code, e.message));
// must run from a user gesture (click handler): browsers block autoplay otherwise
button.onclick = () => call.start();
```
## Passing user data
Just like telephony's [`/call`](/docs/api-reference/calls/make) endpoint, you can pass per-call `userData` that gets substituted into the agent's prompt and welcome message — a `{name}` or `{order_id}` in your prompt becomes the caller's actual name or order number for that call.
Set it once in the constructor to apply it to every call from that instance, or pass it to `start()` to set or override it for a single call:
```javascript theme={"system"}
// applies to every call from this instance
const call = new BolnaWebCall({
sessionUrl: "/api/bolna-session",
userData: { name: "Asha", order_id: "ORD-4521" },
});
// or set/override it for just this call
call.start({ userData: { name: "Asha", order_id: "ORD-4521" } });
```
**How `userData` reaches the agent depends on your session source:**
* **`sessionUrl`** — the SDK POSTs `{ "user_data": {...} }` to your session endpoint automatically. Your backend route must forward that field to Bolna's mint endpoint unchanged (see the note under [Set up your backend](#set-up-your-backend)) or the variables are silently dropped.
* **`getSession` / `session`** — the SDK has no request of its own to inject `userData` into. You own the mint call, so you must include `user_data` in your own mint POST yourself:
```javascript theme={"system"}
const call = new BolnaWebCall({
getSession: async () => {
const r = await fetch("/api/bolna-session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_data: { name: "Asha", order_id: "ORD-4521" } }),
});
return r.json();
},
});
```
There's no error or warning if you skip this — the call just connects without the variables substituted.
`userData` is a JSON object, capped at 50 KB. A mint request over that limit is rejected with a 400. It's stored on the call record and shown in call history, so don't put secrets in it.
## Starter templates
Two complete, copy-pasteable starting points. Pick whichever matches your stack.
**Next.js (App Router).** Works out of the box on Vercel. Set `BOLNA_API_KEY` and `BOLNA_AGENT_ID` as environment variables and deploy.
```javascript app/api/bolna-session/route.js theme={"system"}
export async function POST(req) {
const { user_data } = await req.json().catch(() => ({}));
// illustrative URL: swap in your actual Bolna session-mint endpoint
const r = await fetch("https://api.bolna.ai/v1/web-call/session", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BOLNA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ agent_id: process.env.BOLNA_AGENT_ID, user_data }),
});
return new Response(await r.text(), {
status: r.status,
headers: { "Content-Type": "application/json" },
});
}
```
```jsx app/components/BolnaCallButton.jsx theme={"system"}
"use client";
import { useState } from "react";
import { BolnaWebCall } from "@bolna/web-call";
// pass userData to fill {name}/{order_id}-style variables in the agent's prompt
export default function BolnaCallButton({ userData }) {
const [state, setState] = useState("idle");
const startCall = () => {
const call = new BolnaWebCall({ sessionUrl: "/api/bolna-session", userData });
call.on("state-change", setState);
call.on("call-end", () => setState("idle"));
call.on("error", (e) => console.error(e.code, e.message));
call.start();
};
return (
);
}
```
```jsx usage theme={"system"}
```
**Plain HTML + Node (no build step, no framework).** Two files, no `package.json` needed. Run `BOLNA_API_KEY=bn-… BOLNA_AGENT_ID=… node server.mjs`, then open `index.html`.
```javascript server.mjs theme={"system"}
// the .mjs extension runs as ESM with zero setup, even with no package.json
import http from "node:http";
http.createServer(async (req, res) => {
if (req.method !== "POST" || req.url !== "/bolna-session") return res.writeHead(404).end();
const chunks = [];
for await (const chunk of req) chunks.push(chunk);
const { user_data } = JSON.parse(Buffer.concat(chunks).toString() || "{}");
// illustrative URL: swap in your actual Bolna session-mint endpoint
const r = await fetch("https://api.bolna.ai/v1/web-call/session", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BOLNA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ agent_id: process.env.BOLNA_AGENT_ID, user_data }),
});
res.writeHead(r.status, { "Content-Type": "application/json" }).end(await r.text());
}).listen(8787, () => console.log("session endpoint on http://localhost:8787/bolna-session"));
```
```html index.html theme={"system"}
```
## API reference
**`new BolnaWebCall(options)`.** Provide **exactly one** session source. The constructor throws if you pass zero or more than one.
| Option | Type | Use when |
| ------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `sessionUrl` | `string` | You have a backend route (POST, body is `{}` or `{ user_data }` when `userData` is set) returning the mint JSON. This is the standard setup. |
| `getSession` | `() => Promise` | You need custom fetch logic: extra auth headers, retries, a framework's HTTP client. |
| `session` | `Session` | You already have a freshly-minted session in hand. It expires in \~120s and is single-use. |
Optional, on top of one of the three above:
| Option | Default | Purpose |
| -------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userData` | none | Per-call variables substituted into the agent's prompt and welcome message, identical to telephony's `user_data`. See [Passing user data](#passing-user-data). |
| `audio` | AEC / NS / AGC on | `MediaTrackConstraints` for the microphone. |
| `iceTransportPolicy` | `"all"` | `"relay"` forces TURN. Useful for testing on known-restrictive networks. |
| `audioElement` | hidden element created for you | Play the agent's audio through an `