# Documentation (/docs)
> Build powerful AI voice agents with OmniDimension. Guides, API reference, and integration recipes for the entire platform.
## Build [#build]
## Connect [#connect]
## Reference [#reference]
# API reference (/docs/api-reference)
> REST + Python SDK reference for the OmniDimension platform with an interactive try-it-out playground.
The OmniDimension API lets you create agents, dispatch calls, manage
phone numbers, and pull call analytics from your own systems. Auth is a
single Bearer API key on every request.
Open any endpoint below and you will find a live playground. Paste
your API key under **Authorization**, fill in the request, and hit
**▶ Run** to see the real response without leaving the docs. Your
key is held in this browser session only — it's wiped on reload.
**Base URL** ·
**Auth** `Authorization: Bearer `
## Endpoint groups [#endpoint-groups]
# Bulk Outbound Call Best Practices (/docs/bulk-calls/best-practices)
> Complete guide for optimizing bulk call campaigns, from agent configuration to post-call analysis.
Optimization playbook for bulk outbound call campaigns. Covers agent
configuration, conversation tuning, scheduling, retries, scaling, and
analytics.
## Agent configuration [#agent-configuration]
Essential settings for optimal agent performance in bulk outbound campaigns.
### Welcome message [#welcome-message]
* Keep it short and concise. e.g., "Hello, am I speaking with Aman?"
* Add personalization using variables (e.g., `[name]`, `[company]`)
* State purpose clearly after user acknowledges the call
* Test different variations for optimal response rates
### Prompting best practices [#prompting-best-practices]
* Start with simple prompts → test gradually → add scenarios and conditions
* Use one-shot and few-shot prompting for LLM efficiency. Example: "You are a sales agent. When user says they're busy, respond: I understand you're busy. Would 2 minutes next Tuesday work better?"
* For multi-lingual campaigns, include language-specific prompting guidelines. Example: "If user responds in Spanish, continue conversation in Spanish with appropriate cultural context"
* Add fallback instructions for unexpected user responses. Example: "If you don't understand the user's response, say: I want to make sure I understand you correctly. Could you help me clarify that?"
### TTS-friendly response generation [#tts-friendly-response-generation]
* Write dates and numbers in spoken format
* Example 1, Good: "January fifth, twenty twenty-five" | Bad: "01/05/2025"
* Example 2, Good: "twenty-five dollars" | Bad: "$25"
* Example 3, Good: "CRM (see-are-em)", "API (ay-pee-eye)", "SQL (sequel)"
### Prompting guide for KB integration [#prompting-guide-for-kb-integration]
* Define specific triggers when the Knowledge Base should be consulted
## Configurations [#configurations]
Configuration settings that impact call quality and user experience.
### Silence timeout [#silence-timeout]
* Time to wait after speech ends before generating a response
* Recommended: 300 ms (0.3 seconds) for optimal performance
* Adjust based on target demographic (e.g., older users need more time)
* Test different timeouts with pilot campaigns
### Interruption sensitivity [#interruption-sensitivity]
* Controls how quickly the assistant stops speaking when the user starts talking
* If speech doesn't reach the set threshold (ms), audio is ignored
* 150 ms (high sensitivity): very sensitive, may trigger on background speech
* 600 ms – 1s (medium): balanced, best for natural conversations
* 1000 ms – 3000 ms (low): less sensitive, may miss short replies ("yes", "no")
* Start with 600–1000 ms for most cases
* Test interruption handling in different scenarios to find optimal setting
### Noise handling [#noise-handling]
* Apply noise reducer to minimize background environmental sounds (fan, traffic, etc.)
* Does not cancel out active conversations or background talking
* Test with different ambient noise scenarios
### Language model settings [#language-model-settings]
* Choose LLM based on conversation complexity and speed needs
* Start with GPT-4o-mini for balanced performance
* Enable streaming for real-time, low-latency responses
* Set temperature: 0.2–0.4 for factual, 0.5–0.7 for natural / balanced tone
* Test different models with real conversation scenarios
* Continuously monitor trade-offs between response quality and speed
### Voice selection [#voice-selection]
* Choose voice that matches your brand personality and target audience
* Consider regional accents for local market relevance
* Test voice clarity and naturalness with sample conversations
* A/B test different voices for optimal engagement rates
* Consider gender preferences based on campaign type and audience
### Background noise simulation [#background-noise-simulation]
* Add subtle background noise for more natural feel (optional)
* Choose appropriate environment sounds (office, restaurant, etc.)
* Keep volume low to avoid distraction from main conversation (e.g., 0.30)
* Test impact on call quality and user perception
## Post-call handling [#post-call-handling]
Comprehensive data extraction and follow-up processes for maximum campaign
value.
* Save complete transcription for quality analysis and compliance
* Generate structured call summary with key points and outcomes
* Extract predefined variables relevant to campaign objectives
* Example 1, lead qualification: hot lead, warm lead, cold lead, not qualified
* Example 2, intent level: high interest, moderate interest, low interest, not interested
* Add Google Sheet post-call for data analysis and reporting
## Bulk call guidelines [#bulk-call-guidelines]
Strategic approach for successful bulk campaign execution.
### Campaign management [#campaign-management]
* Use descriptive, date-stamped campaign names (e.g., `Q3_Product_Launch_East_Coast_2024`)
* Include context columns matching agent variables (name, company, industry, etc.)
* Configure timezone-aware scheduling for optimal call timing
### Call rescheduling and retry [#call-rescheduling-and-retry]
Optimizing follow-up strategies for maximum coverage and compliance.
#### Rescheduling configuration [#rescheduling-configuration]
* Update timezone handling for accurate scheduling across regions
* Add specific prompts for handling rescheduling requests naturally
* Example: if customer requests rescheduling, ask for the new date and time to call back
#### Retry strategy [#retry-strategy]
* Configure maximum retry attempts per number (typically 2–3 times)
* Space retries appropriately: 24–48 hours between attempts
## How to go live with bulk calls [#how-to-go-live-with-bulk-calls]
Strategic approach for successful bulk campaign execution.
### Pilot internal testing [#pilot-internal-testing]
* Start with 5–10 internal test calls using sample numbers
* Test different conversation scenarios and edge cases
* Verify agent responses to common objections and questions
* Check technical functionality: call quality, data extraction, integrations
* Document issues and optimize before real user testing
### Small batch rollout [#small-batch-rollout]
* Dispatch initial batch of \~200 calls to real prospects
* Monitor calls in real-time during initial hours
* Track key metrics: pickup rate, conversation length, completion rate, success rate, etc.
* Collect immediate feedback from answered calls
* Pause campaign if major issues are detected
* Analyze results before proceeding to larger volumes
* Optimize based on real-world performance data
### Scaling approach [#scaling-approach]
* Scale gradually: 200 → 500 → 1000 → larger volumes
* Wait for performance stabilization before each scaling step
* Monitor system performance and call quality at each scale
## Analysis and optimization [#analysis-and-optimization]
Data-driven approach to continuous campaign improvement.
### Measure key metrics [#measure-key-metrics]
* **Pickup Rate**: track by time of day, day of week, lead source, geography
* **Conversation Duration**: average length, completion rate, early hang-ups
* **Interaction Count**: back-and-forth exchanges indicating engagement level
* **Conversion Rate**: percentage achieving primary campaign objective
* **Lead Quality Score**: hot / warm / cold lead distribution from calls
* **Agent Performance**: response accuracy, objection handling, flow adherence
* **Technical Metrics**: call quality, connection success, system performance
### Diagnose issues [#diagnose-issues]
Common scenarios and their specific optimization strategies.
#### Scenario A: Low pickup rate (\< 20%) [#scenario-a-low-pickup-rate--20]
* Analyze lead quality: source, age, verification status
* Optimize call timing: test different hours, days of week, seasonal patterns
* Implement local number presence for better pickup rates
* Analyze geographic and demographic pickup patterns
#### Scenario B: Good pickup (> 30%) but low interactions (\< 3 exchanges) [#scenario-b-good-pickup--30-but-low-interactions--3-exchanges]
* Simplify opening conversation flow and reduce complexity
* Shorten bot questions and responses for better engagement
* Clarify value proposition in opening line within first 10 seconds
* Reduce cognitive load with simpler language and concepts
* Test different conversation pacing and natural pauses
* Improve interruption handling and conversation recovery
* A/B test different opening scripts and value propositions
#### Scenario C: High pickup and interactions but low conversion (\< 10%) [#scenario-c-high-pickup-and-interactions-but-low-conversion--10]
* Analyze conversation quality issues in detail
* **Objection handling**: review common objections and response effectiveness
* **Interruption management**: ensure natural conversation flow recovery
* **Clarification requests**: improve agent's ability to understand and respond
* **Value communication**: strengthen benefit articulation and relevance
* **Call-to-action clarity**: make next steps obvious and compelling
* **Trust building**: enhance credibility indicators and social proof
* **Closing techniques**: improve commitment and follow-through processes
### Optimize conversation design [#optimize-conversation-design]
* Adjust prompts based on actual conversation patterns and outcomes
* Improve objection handling with real examples from call analysis
* Enhance agent training data with successful conversation examples
* Test new conversation flows with A/B testing methodology
### Iterate and scale [#iterate-and-scale]
* Run new test batch with updated conversation flow and configuration
* Compare performance metrics against baseline from previous iterations
* Continue optimization cycles until metrics stabilize at acceptable levels
# Dynamic Campaign Guide (/docs/bulk-calls/dynamic)
> Create a Dynamic Campaign that accepts contacts in real time via a webhook API. Ideal for CRM integrations and continuous outreach.
A Dynamic Campaign is a special type of bulk call campaign where contacts
are added in real time through an API webhook, instead of being uploaded all
at once via a CSV file.
* Stays alive indefinitely; never auto-completes when the queue empties
* Accepts new contacts at any time via a simple HTTP POST webhook
* Transitions to **Waiting** status when the queue is empty, then resumes automatically when a new contact arrives
* Perfect for CRM integrations, real-time lead pipelines, or always-on outreach campaigns
* Supports the same scheduling, auto-retry, and call-rescheduling features as regular campaigns
## Prerequisites [#prerequisites]
Before creating a Dynamic Campaign, make sure the following are in place.
* A phone number in your dashboard. [Buy one directly from the Number Shop](/docs/dashboard-guides/numbers-shop) or import your own (Twilio, etc.)
* An AI agent configured and attached to that phone number
* An API key for authenticating webhook requests. Find it in the sidebar under **Account & Billing → API**
* The external system (CRM, automation platform, etc.) that will send contacts to the webhook
## Creating a Dynamic Campaign [#creating-a-dynamic-campaign]
### Campaign details and phone number [#campaign-details-and-phone-number]
Start the campaign creation wizard. Enter a campaign name and select the
phone number with the attached agent.
* Navigate to **Bulk Call** from the dashboard sidebar
* Click **Create New Campaign**
* Enter a descriptive campaign name (e.g., "Real-Time Lead Outreach")
* Select your phone number from the dropdown. The attached agent will be shown automatically
* Click **Next** to continue
### Enable dynamic mode [#enable-dynamic-mode]
On the contact upload step, switch from CSV upload to Dynamic Campaign mode.
* You will see two options: **Upload CSV File** and **Dynamic Campaign (Add contacts via API/Webhooks)**
* Select **Dynamic Campaign**
* No CSV file is required. Contacts will be added later through the webhook
* Optionally configure **Call Conditions** to automatically filter which contacts get called
* Click **Next** to continue
### Scheduling and retry settings [#scheduling-and-retry-settings]
Configure when the campaign runs and set up auto-retry for failed calls.
* Choose **Start Immediately** or **Schedule for Later** with a specific date, time, and timezone
* Enable **Daily Hard Stop** to pause calling outside of business hours
* Enable **Daily Auto Start** to automatically resume calls each morning
* Turn on Auto Retry and set a retry limit (up to 6 attempts) for failed calls
* Enable Call Rescheduling to let the AI handle "call me back later" requests automatically
* Click **Next** to review
### Review and create [#review-and-create]
Review all campaign settings before launching the Dynamic Campaign.
* Confirm the campaign name, phone number, and agent
* Verify the campaign type is shown as **Dynamic Campaign**
* Check scheduling and retry configuration
* Click **Create Campaign**. The campaign will start and wait for contacts via webhook
## Campaign status flow [#campaign-status-flow]
After creation, a Dynamic Campaign cycles through these statuses
automatically.
* **In Progress**: actively making calls from the queue
* **Waiting**: queue is empty; campaign is idle but alive, ready to resume when a contact arrives
* **Auto Paused**: outside operating hours (if daily hard stop is configured)
* **Paused**: manually paused by the user
* A Dynamic Campaign will never move to **Completed**; it stays alive indefinitely
## Adding contacts via webhook [#adding-contacts-via-webhook]
Once the campaign is created, use the webhook API to push contacts from any
external system.
* Find the Campaign ID on the campaign detail page
* Send a POST request to the webhook endpoint with the contact's phone number
* Include `custom_variables` to pass context to the AI agent (e.g., name, reason for call)
* Include `metadata` for your own tracking (not shared with the agent)
* The campaign will immediately start calling if it is in **Waiting** or **In Progress** status
### Webhook request format [#webhook-request-format]
* **Endpoint**: `POST /api/v1/calls/bulk_call/{campaign_id}/add_contact`
* **Header**: `Authorization: Bearer YOUR_API_KEY`
* **Body** `to_number`: The contact's phone number in E.164 format (e.g., `+15551234567`)
* **Body** `custom_variables`: Key-value pairs injected into the agent's conversation context
* **Body** `metadata`: Key-value pairs stored for tracking purposes only (hidden from agent)
### Example: cURL [#example-curl]
```bash
curl -X POST "https://backend.omnidim.io/api/v1/calls/bulk_call/123/add_contact" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to_number": "+15551234567",
"custom_variables": {
"name": "Jane Doe",
"interest": "Home Insurance"
},
"metadata": {
"crm_lead_id": "lead_9876",
"source": "website_form"
}
}'
```
### Webhook response [#webhook-response]
A successful request returns the updated campaign status and the new
contact's line ID.
* `status: "success"` confirms the contact was accepted
* `campaign_status` shows the current campaign state (e.g., `in_progress` or `waiting`)
* `line_id` is the unique ID of the new contact record in this campaign
* If the campaign is outside operating hours, the contact is queued and called when the campaign resumes
## Campaign management [#campaign-management]
You can control a Dynamic Campaign at any time from the campaign detail page.
* **Pause**: temporarily stop all outbound calls (contacts added while paused will be called on resume)
* **Resume**: restart a paused campaign
* **Cancel**: permanently end the campaign; no further contacts will be accepted
* **Update Retry Settings**: change retry limits and schedule without recreating the campaign
* **Update Reschedule Settings**: enable or disable AI-driven call rescheduling mid-campaign
## Best practices [#best-practices]
* Use meaningful `custom_variables` that match variables in your agent's welcome message or prompt
* Set daily operating hours to avoid calling contacts outside business hours
* Enable auto-retry to recover from unanswered or failed calls without manual intervention
* Use the `metadata` field to store CRM or tracking IDs so you can correlate call results with your records
* Monitor the campaign status via the dashboard or poll `/api/v1/calls/bulk_call/{id}` for real-time status
* Pause the campaign before making major agent changes to avoid inconsistent conversations mid-campaign
# Bulk calls (/docs/bulk-calls)
> Run AI-powered outbound campaigns with retry logic, dynamic queues, and best practices for production deployment.
Run AI-powered outbound calling campaigns at scale. Choose between
CSV-uploaded campaigns or webhook-driven Dynamic Campaigns for real-time
contact delivery.
# Bulk Call Campaign Guide (/docs/bulk-calls/overview)
> Complete step-by-step guide to create and manage AI-powered bulk call campaigns to reach multiple contacts efficiently.
A complete walkthrough of creating, managing, and analyzing AI-powered bulk
call campaigns from the OmniDimension dashboard.
## Prerequisites [#prerequisites]
Before creating a bulk call campaign, you need to set up your phone number
and deploy an AI agent.
* Navigate to the **Phone Numbers** section from your dashboard
* Import a phone number (e.g., Twilio, Exotel)
* Ensure your agent is properly configured with context, instructions, and integrations
* Attach the agent to your imported phone number
* Test your agent with a single call before running bulk campaigns
### Deploy an agent with a phone number [#deploy-an-agent-with-a-phone-number]
### Agent successfully attached [#agent-successfully-attached]
## Creating a bulk call campaign [#creating-a-bulk-call-campaign]
The bulk call creation process is divided into 4 steps. Navigate to the
**Bulk Call** section from your dashboard and click **Create New Campaign**
to begin.
### Campaign details and phone number selection [#campaign-details-and-phone-number-selection]
Set up your campaign name and choose the phone number with attached agent
for making calls.
* Enter a campaign name. Use descriptive names for easy tracking (e.g., "Q4 Product Launch Outreach")
* Select a phone number from the dropdown
* Review the agent details displayed automatically, including integrations and post-call actions
* Verify the agent configuration is correct for your campaign goals
* Click **Next** to proceed to Step 2
### Upload contact list and CSV configuration [#upload-contact-list-and-csv-configuration]
Upload your contact list in CSV format and configure call conditions.
* Click **Upload CSV File** and select your contact list
* The system will automatically detect columns and validate the format
* Review the preview of your uploaded data
* Set optional call conditions to filter which contacts to call
* If missing variables are detected, download the template and add required data
#### CSV format guidelines [#csv-format-guidelines]
* Required column: `phone_number` (with country code, e.g., 1, 91)
* Optional columns: `name`, `company`, `reason_for_call`, etc.
* Column names should match variables in your agent's context or welcome message
* Additional columns are automatically passed as context to the AI agent
* Maximum file size: 10 MB
* Supported format: `.csv` files only
* Download the provided template and add the required data columns to ensure optimal agent performance
### Campaign settings and scheduling [#campaign-settings-and-scheduling]
Configure when to start your campaign and set up advanced features like
auto-retry and call rescheduling.
* Choose when to start: **Start Immediately** or **Schedule for Later**
* If scheduling, set the date, time, and timezone
* Configure Auto Retry settings for failed calls
* Enable Call Rescheduling to automatically handle callback requests
* Click **Next** to proceed to Step 4
#### Configuration options [#configuration-options]
#### Auto retry settings [#auto-retry-settings]
* **Maximum Retry Attempts**: Set retry limit (1–6 attempts maximum)
* **Retry Schedule Immediately**: Retry failed calls right after the main campaign completes
* **Retry Schedule Next Day**: Automatically retry all failed calls the following day
* **Retry Schedule Scheduled Time**: Set custom days and hours delay for retry attempts
* Auto retry only triggers after the main campaign completes
* You can edit retry settings even after campaign creation
#### Call rescheduling [#call-rescheduling]
* Enable **Call Rescheduling** in campaign settings
* AI automatically detects customer requests like "call me tomorrow" or "I'm busy right now"
* Automatically schedules follow-up calls based on customer preferences
* Works by analyzing conversation for reschedule requests during the call
* Improves customer experience and conversion rates
### Review and create campaign [#review-and-create-campaign]
Final review of all campaign settings before creation.
* Review all campaign details: name, phone number, and agent configuration
* Check the number of contacts to be called
* Verify scheduling settings (immediate start or scheduled time)
* Confirm auto-retry settings and maximum retry attempts
* Check estimated cost and ensure sufficient account balance
* Click **Create Campaign** to launch or schedule your bulk call campaign
## Campaign management after creation [#campaign-management-after-creation]
Once your campaign is created, you can monitor, control, and analyze its
performance.
* **Pause Campaign**: Temporarily stop an active campaign
* **Resume Campaign**: Continue a paused campaign
* **Update Reschedule Settings**: Enable / disable call rescheduling during campaign
* **Update Auto Retry Settings**: Modify retry attempts and schedule
## Best practices for successful campaigns [#best-practices-for-successful-campaigns]
* Test with a small batch first before launching to your entire list
* Use descriptive campaign names: include date, purpose, and target audience for easy tracking
* Include relevant context columns that match your agent's variables for personalized conversations
* Set appropriate retry limits: 2–3 retry attempts are usually optimal
* Enable call rescheduling to improve success rates and brand reputation
* Check progress regularly and adjust settings based on real-time performance
* Use campaign analytics to improve future campaigns and agent performance
See [Bulk outbound best practices](/docs/bulk-calls/best-practices) for the
full optimization playbook.
# Configure your agent (/docs/dashboard-guides/configure-your-agent)
> Configure the conversational flow for your agent. Sections, instructions, welcome message, and best practices.
The Conversational Flow section allows you to create structured instructions
for your agent, defining how it should handle different parts of a
conversation and what actions it should take.
### Key benefits [#key-benefits]
* Guide your agent through complex conversation scenarios
* Ensure consistent handling of specific topics
* Create a logical flow for multi-step processes
* Provide detailed instructions for specialized tasks
### Section management [#section-management]
Manage different stages of the conversation by creating, reordering, or
removing instruction sections.
* **Add sections**: Create new instruction blocks for different conversation stages
* **Reorder sections**: Drag and drop to change the sequence of instructions
* **Remove sections**: Delete unnecessary instruction blocks
### Section configuration [#section-configuration]
Customize the content and behavior of each section in the conversational flow.
* **Section title**: A descriptive name for this conversation stage
* **Instructions**: Detailed guidance for how the agent should handle this part of the conversation
### Welcome message [#welcome-message]
You can add or edit the welcome message from the conversation flow section.
The welcome message is currently static.
### Plan your conversation structure [#plan-your-conversation-structure]
Before adding sections, outline the key stages of your ideal conversation,
such as Introduction, Information gathering, Problem solving, and Conclusion.
### Create sections for each stage [#create-sections-for-each-stage]
Add a section for each conversation stage with clear, descriptive titles and
detailed instructions for the agent.
### Provide detailed instructions [#provide-detailed-instructions]
In each section, include what information to collect, how to respond to
specific questions, when to move to the next stage, and any actions to take
(e.g., scheduling or data collection).
### Test and refine [#test-and-refine]
After setting up your flow, test conversations to ensure the agent follows
instructions. Refine sections based on user interactions and add new ones as
needed.
## Best practices [#best-practices]
* Write instructions in clear, direct language
* Include example responses for complex scenarios
* Specify exactly what information to collect
* Provide fallback instructions for unexpected situations
* Keep sections focused on specific conversation stages
## Pro tips [#pro-tips]
* Start with fewer sections and add more as needed
* Use the drag-and-drop feature to optimize conversation flow
* Review conversation recordings to identify areas for improvement
* Update your flow regularly based on common user interactions
# Dashboard guides (/docs/dashboard-guides)
> No-code walkthroughs for configuring agents, numbers, knowledge base, and post-call delivery from the OmniDimension dashboard.
These guides walk through everything you can do from the OmniDimension
dashboard without writing a line of code, from building your first agent's
conversational flow to wiring up post-call delivery to Salesforce and Slack.
# Knowledge base (/docs/dashboard-guides/knowledge-base)
> Provide your agent with domain-specific knowledge using document-based references.
Knowledge Base allows your agent to access and utilize external documents and
files, enabling it to reference specific information during conversations
with users.
### Key benefits [#key-benefits]
* Provide your agent with domain-specific knowledge
* Upload documents for reference during conversations
* Ensure accurate and consistent information delivery
* Reduce the need for manual information updates
### Setup option 1: from agent configuration [#setup-option-1-from-agent-configuration]
* Go to your agent's edit page
* Select the **Knowledge Base** tab
* Upload files or select from your existing library
* Files will be automatically processed and made available to your agent
### Setup option 2: from the main dashboard [#setup-option-2-from-the-main-dashboard]
* Go to the **Files** page in your dashboard
* Upload files or select from your existing library
* Go to your agent's edit page
* Select the **Knowledge Base** tab
* Attach files for the agent
### Configuration guide: uploading files [#configuration-guide-uploading-files]
* Click the **Upload File** button in the Knowledge Base section
* Select documents from your computer (supported formats: PDF)
* Wait for processing to complete
* Newly uploaded files will appear in your file library
### Using with your agent [#using-with-your-agent]
* The agent will automatically reference these documents when answering user queries
* Information from these files will be used to provide accurate and relevant responses
* The agent will cite specific documents when providing information from them
### Pro tips [#pro-tips]
* Upload comprehensive documentation for best results
* Use descriptive filenames to easily identify content
* Organize information in clear, structured documents
* Regularly update your knowledge base with the latest information
* Attach only relevant files to each agent to maintain focus
**Video tutorial: Adding Knowledge Base.** Watch this guide on how to add
and manage knowledge base documents for your agent on
[YouTube](https://www.youtube.com/watch?v=7FJoWB4UqRg).
# Numbers Shop (/docs/dashboard-guides/numbers-shop)
> Purchase dedicated phone numbers and connect them to your Voice AI agents.
Purchase dedicated phone numbers and connect them to your Voice AI agents.
## Available regions [#available-regions]
* 🇮🇳 **India (+91)**
* 🇺🇸 **United States (+1)**
## Pricing [#pricing]
### Monthly rental [#monthly-rental]
Each number has a monthly fee shown when you browse. You pay for 30 days at
a time and it auto-renews.
### Telephony channels [#telephony-channels]
Channels determine how many calls can happen simultaneously on one number.
* 1 channel included free with every number
* Example: 3 channels = 3 concurrent calls
* Need more channels? [Contact us](https://omnidim.io/contact-us)
### Payment [#payment]
To make purchases seamless, we deduct the amount from your wallet balance.
[Top up your wallet here](https://omnidim.io/billing).
## How to purchase [#how-to-purchase]
### India (+91) [#india-91]
**Quick one-time verification.** Indian regulations require eKYC
verification before your first purchase. It takes under 2 minutes, and
after that all purchases are instant.
Go to **Numbers Shop** in your dashboard and select an Indian number.
Click **Reserve & Start KYC**. The number is held while you verify.
Complete the 6-step eKYC process. See [eKYC Verification](#ekyc-verification-india) below.
Confirm purchase.
Attach the number to your Voice AI agent from the **Phone Numbers** page.
### United States (+1) [#united-states-1]
Go to **Numbers Shop** in your dashboard and search for a US number.
Click **Purchase** and confirm.
Attach the number to your Voice AI agent from the **Phone Numbers** page.
## eKYC verification (India) [#ekyc-verification-india]
eKYC is a quick, one-time identity verification required by Indian telecom
regulations. It takes under 2 minutes to complete, and after that you can
purchase unlimited +91 numbers instantly.
### Documents required [#documents-required]
* **PAN Card**: Your 10-character PAN number
* **Aadhaar Card**: Must be linked to a mobile number for OTP
* **GST Number** (optional): Only if you're GST registered
### Verification steps [#verification-steps]
**Registration**: Enter your name, email, and phone. Verify with OTP.
**PAN verification**: Enter your PAN number and select business type.
**Aadhaar OTP**: Enter your Aadhaar. OTP will be sent to your linked mobile.
**Aadhaar verification**: Enter the OTP to verify your identity.
**GST verification**: Enter your GST number if applicable, or skip this step.
**Review and submit**: Check your details and complete the verification.
**Done in under 2 minutes.** Complete eKYC once and buy unlimited +91
numbers instantly, anytime.
## Managing your numbers [#managing-your-numbers]
After purchasing, manage your numbers from the **Phone Numbers** page.
* **Attach to agent**: Connect your number to a Voice AI agent to enable calls.
* **Renewals**: Numbers auto-renew monthly if your wallet has sufficient balance.
* **Release**: Release numbers you no longer need. They won't renew next month.
## Get started [#get-started]
Ready to get your phone numbers?
* **Browse Numbers Shop**: Find and purchase phone numbers
* **My Phone Numbers**: Manage your existing numbers
* **Top Up Wallet**: Add funds for purchases
Already have your own phone infrastructure? Use
[SIP Trunking](/docs/telephony) to connect your existing numbers to
OmniDimension.
# Post-call actions (/docs/dashboard-guides/post-call)
> Configure post-call delivery to Email, Salesforce, Slack, Webhooks, HubSpot, and WhatsApp Cloud.
After each call ends, OmniDimension allows you to deliver structured post-call
data to external destinations:
* Email
* Salesforce
* Slack
* Webhook
* HubSpot
* WhatsApp Cloud
**Video tutorial: Get Post-Call Data.** Learn how to retrieve and manage
post-call data from your Voice AI agent on
[YouTube](https://www.youtube.com/watch?v=__hZ9u6Em9w).
## How to access post-call delivery settings [#how-to-access-post-call-delivery-settings]
* Go to your Agent Dashboard on OmniDimension.
* Navigate to the **Post-Call** section.
* Under the **Delivery Method** dropdown, you will see options for Email,
Salesforce, Slack, Webhook, HubSpot, and WhatsApp Cloud.
## Email delivery [#email-delivery]
Use this method to receive an email with the full call report.
* Select **Email** from the dropdown.
* Enter the recipient email address where you'd like the report to be sent.
* Configure the include fields like summary, sentiment, variables, full conversation, etc.
## Salesforce integration [#salesforce-integration]
Push post-call data directly to a specific object in your Salesforce CRM.
* Select **Salesforce** from the dropdown.
* Choose the Salesforce integration from the dropdown. If not available you can create a new integration for Salesforce from the **Integrations** tab.
* Choose the target object: Lead, Contact, Account, Product, etc.
* It will automatically map the extracted variables to Salesforce fields.
## HubSpot integration [#hubspot-integration]
Send call summaries and variable data to HubSpot CRM records.
* Select **HubSpot** from the dropdown.
* Choose the HubSpot integration from the dropdown. If not available you can create a new integration for HubSpot from the **Integrations** tab.
* Choose the target object: Contact, Deal, Ticket, Company.
* It will automatically map the extracted variables to HubSpot fields.
## Slack integration [#slack-integration]
Post a message to a Slack channel after every call.
* Choose **Slack** as the delivery method.
* Choose the Slack integration from the dropdown. If not available you can create a new integration for Slack from the **Integrations** tab.
* Select the channel to which messages should be posted (e.g., `#sales-leads`, `#support-alerts`).
* Choose what data to include: summary, sentiment, extracted variables, full conversation, etc.
## Webhook [#webhook]
Send structured JSON data to any external system or automation tool (Make,
Zapier, n8n, etc.).
* Select **Webhook** from the delivery method dropdown.
* Paste the webhook URL of your receiving system.
* Select **Standard JSON** to send our data as-is, or select **Custom Payload** to transform it.
* If using **Custom Payload**: Click **Test Template**, write your logic, and verify with the Real-Time Playground.
### Reference: available variables [#reference-available-variables]
Use these variables in your custom payload:
* `phone_number`: Customer's phone number
* `to_number`: Agent / bot phone number
* `bot_name`: Name of your agent
* `call_status`: e.g., `"completed"`
* `call_report.summary`: AI summary of the call
* `call_report.sentiment`: `"Positive"`, `"Neutral"`, or `"Negative"`
* `call_report.extracted_variables.[key]`: Your custom extracted data (e.g., `$.call_report.extracted_variables.email`)
### Example: LeadSquared schema [#example-leadsquared-schema]
```json
[
{ "Attribute": "Phone", "Value": "phone_number" },
{ "Attribute": "Name", "Value": "call_report.extracted_variables.name" },
{ "Attribute": "Email", "Value": "call_report.extracted_variables.email" },
{ "Attribute": "Notes", "Value": "call_report.summary" }
]
```
**Pro tip: real-time testing.** Before testing your template, make sure to
add your **Extracted Variables** in the configuration. The **Test Template**
playground will automatically populate with realistic dummy data based on
your specific variable names, allowing you to verify your custom payload
logic instantly.
## WhatsApp Cloud post-call [#whatsapp-cloud-post-call]
Send a WhatsApp message to the user with the call summary or other details
using a template.
* Select **WhatsApp Cloud** as the delivery method.
* Choose an available WhatsApp Cloud number from the dropdown.
* Select one of your pre-approved WhatsApp templates.
* Map the template variables to your extracted variables (e.g., `{{1}}` = `$.call_report.extracted_variables.name`).
* Add a description for this post-call action for your reference.
## Best practices [#best-practices]
* Test each delivery method before going live using the built-in **Test Connection** feature.
* For Slack, Salesforce, and HubSpot, ensure you grant the necessary permissions during OAuth.
* Use Webhook.site or RequestBin to inspect real payloads during integration.
* Always sanitize or encrypt sensitive data when sending via webhook or email.
# Recent calls (/docs/dashboard-guides/recent-calls)
> Access, analyze, and make use of recent call logs to improve your agent's performance.
Recent Calls provides a comprehensive history of all interactions between
your agent and users, allowing you to review past conversations and analyze
performance.
### Key benefits [#key-benefits]
* Track all agent interactions in one place
* Review conversation transcripts
* Identify potential issues or improvement areas
* Monitor agent performance over time
* Access detailed call analytics
### Accessing recent calls from the agent dashboard [#accessing-recent-calls-from-the-agent-dashboard]
* Go to your agent's management page
* Select the "Recent Calls" tab
* View the chronological list of all interactions for that specific agent
### Accessing recent calls from the main dashboard [#accessing-recent-calls-from-the-main-dashboard]
* Go to the Call Logs page in your dashboard
* View the chronological list of all interactions across all your agents
### Features [#features]
* Caller phone number or identifier
* Date and time of call
* Call duration
* Call type
* Status indicators (Issues / No Issues)
* Complete conversation transcript
* Download recording
### Using recent calls [#using-recent-calls]
* Monitor your agent's performance
* Identify common user questions or issues
* Improve your agent's responses based on real conversations
* Track usage patterns over time
**Video tutorial: Review Call Analytics.** Learn how to review recordings,
transcripts, and performance metrics on
[YouTube](https://www.youtube.com/watch?v=9GeMHYBm5js).
# Agent timezone (/docs/dashboard-guides/update-timezone)
> Set and update your agent's timezone for accurate scheduling and time-based operations.
Setting the correct timezone for your agent is crucial for accurate
scheduling, appointment booking, and time-based operations. This ensures your
agent operates according to your local business hours and can schedule
meetings correctly.
### Why timezone matters [#why-timezone-matters]
* Accurate appointment scheduling with calendar integrations
* Proper business hours operation
* Correct time display in conversations
* Synchronized meeting invitations and confirmations
### Method 1: Update via Settings [#method-1-update-via-settings]
The most direct way to update your agent's timezone through the settings page.
* Navigate to your dashboard and go to the Settings page
* Find the Timezone section and choose your desired timezone from the dropdown menu
* Your agent will now operate in the selected timezone
### Method 2: Automatic timezone notification [#method-2-automatic-timezone-notification]
When you add calendar integrations, the system automatically prompts you to
update the timezone.
* Add a Google Calendar or Cal.com integration to your agent
* A notification will automatically appear asking to update timezone
* Click on the "Update Timezone" notification
* From the timezone modal, select the appropriate timezone and save it
# Voice cloning (/docs/dashboard-guides/voice-cloning)
> Clone your voice and use it with your AI agents for a personalized experience.
Voice cloning lets you create a digital replica of your own voice. Once
created, you can assign it to any of your AI agents so that they speak in
your voice during live calls. This makes your agents sound more natural and
personal, improving the listener's experience.
### Navigate to Cloned Voices [#navigate-to-cloned-voices]
From the main dashboard, open the sidebar and click on **Cloned Voices**.
This is your central hub for managing all voice clones.
### Upload your audio sample [#upload-your-audio-sample]
Click the button to create a new cloned voice. Fill in the form with a name
for your voice, select the language, and upload an audio sample of yourself
speaking. For best results, use a clear recording of at least 10 seconds with
minimal background noise.
* Give your cloned voice a recognizable name
* Select the language that matches your audio sample
* Upload an MP3, WAV, or WebM audio file (minimum 20 seconds)
### Voice created successfully [#voice-created-successfully]
Once the upload is processed, your cloned voice will appear in the list with
a **Ready** status. It is now available to assign to any of your agents.
### Use your cloned voice in an agent [#use-your-cloned-voice-in-an-agent]
Open any agent's settings and go to the Voice tab. Switch to the **Cloned
Voices** tab to see your available voice clones. Select the voice you just
created and save the agent configuration. The agent will now use your cloned
voice on all future calls.
* Open an agent and navigate to the Voice configuration tab
* Click on the **Cloned Voices** tab
* Select your cloned voice from the list
* Save the agent to apply the change
# Voices and languages (/docs/dashboard-guides/voices-and-languages)
> Build globally-aware AI agents with native-level fluency across 90+ languages and 1000+ realistic voices.
Build globally-aware AI agents. Our platform provides native-level fluency
across 90+ languages with highly emotive voice generation.
* **90+ Languages**
* **1000+ Realistic Voices**
* **Sub-200ms Latency**
## Core capabilities [#core-capabilities]
Our platform unifies state-of-the-art Speech-to-Text (STT) and Text-to-Speech
(TTS) technologies.
## Global support matrix [#global-support-matrix]
Comprehensive coverage for both understanding and speaking across 90+
locales.
### Indian languages [#indian-languages]
Hindi
Bengali
Telugu
Marathi
Tamil
Urdu
Gujarati
Kannada
Malayalam
Punjabi
Assamese
Maithili
Odia
Sanskrit
### Global languages [#global-languages]
English
Spanish
French
German
Japanese
Chinese
Portuguese
Italian
Dutch
Korean
Arabic
Turkish
Russian
Vietnamese
Indonesian
Swedish
Polish
Thai
Greek
Hebrew
Czech
Danish
Finnish
Norwegian
Romanian
Ukrainian
Hungarian
Slovak
Croatian
Bulgarian
Lithuanian
Latvian
Estonian
Slovenian
Serbian
Macedonian
Albanian
Bosnian
Montenegrin
Maltese
Icelandic
Welsh
Irish
Scots Gaelic
Basque
Catalan
Galician
Filipino
Malay
Khmer
Lao
Burmese
Nepali
Sinhala
Bengali (Bangladesh)
Tamil (Sri Lanka)
Swahili
Amharic
Zulu
Xhosa
Afrikaans
Somali
Hausa
Yoruba
Igbo
Farsi
Pashto
Kurdish
Azerbaijani
Armenian
Georgian
Kazakh
Uzbek
Turkmen
Kyrgyz
Tajik
Mongolian
\+ many more
**Seamless multi-lingual switching.** Your agent can automatically detect
the language being spoken and respond in kind, enabling a truly fluid
multi-lingual customer experience.
# Web chat widget (/docs/dashboard-guides/web-chat-widget)
> Deploy your voice AI agent as a chat widget on your website with a no-code embed script.
The Web Bot Widget allows you to deploy your OmniDimension agent on any
website as a floating chat interface. Customers can engage with your AI agent
directly from your site.
### Key benefits [#key-benefits]
* No-code deployment with a simple copy-paste script
* Customizable design: logo, colors, position, and dimensions
* Works seamlessly across all modern websites
* Live preview of widget before deployment
### How to deploy the widget [#how-to-deploy-the-widget]
* Go to your agent dashboard
* Click the **Deploy** dropdown
* Select **Web Bot Widget**
* Copy the generated embed script
* Paste this script inside the `` tag of your website's HTML page
* Save and deploy your website
* The widget will appear on your website
* Users can interact with your agent by clicking on the widget icon
### Widget configuration [#widget-configuration]
After clicking **Web Bot Widget** from the Deploy menu, you'll be taken to
the configuration screen where you can customize the widget's appearance.
* **Widget title**: Label displayed on the widget (e.g., Product Support)
* **Logo URL**: URL to a 32x32 image or SVG icon
* **Widget position**: Choose between bottom right or left
* **Widget width and height**: Adjust the size in pixels
* **Colors**: Background and text color for branding
### Preview and test [#preview-and-test]
* View the live preview panel on the right to verify widget appearance
* Use Chat or Web Call options to simulate user interaction
* Adjust any settings until you're satisfied with the layout and branding
### Deployment tips [#deployment-tips]
* Place the script at the bottom of the body tag for optimal loading
* Ensure the secret key in the script matches your agent
* Use HTTPS hosting for proper widget functionality
* Test responsiveness on mobile and desktop browsers
# Web search tool (/docs/dashboard-guides/web-search-tool)
> Enable real-time internet access for your agent using the Web Search integration.
Web Search lets your agent retrieve up-to-date information from the
internet during a call, so it can answer questions about current events,
facts, and data that may not be in its training data or knowledge base.
## Benefits [#benefits]
* Access to real-time information
* Enhanced agent responses with factual data
* Ability to answer questions about current events
## Setup [#setup]
### Open the agent's integration tab [#open-the-agents-integration-tab]
Navigate to your agent's page and locate the Web Search toggle in the
integration tab.
### Enable Web Search [#enable-web-search]
Toggle the switch to enable Web Search. Pick a search engine (OpenAI or
DuckDuckGo). The agent configuration auto-saves.
## Usage tips [#usage-tips]
* Web Search is most effective for factual queries that need up-to-date information.
* The agent automatically decides when to invoke web search based on the query.
* For time-sensitive information (news, weather, stock prices), web search returns the most accurate responses.
# Authentication (/docs/get-started/authentication)
> How to obtain an OmniDimension API key and configure it for the SDK.
To use the OmniDimension SDK, you need an API key. Generate and manage your
keys from the [API management dashboard](https://omnidim.io/api-management).
## Setting up your API key [#setting-up-your-api-key]
We recommend storing your API key as an environment variable for security:
```bash
export OMNIDIM_API_KEY="your_api_key_here"
```
```bat
set OMNIDIM_API_KEY=your_api_key_here
```
```powershell
$env:OMNIDIM_API_KEY="your_api_key_here"
```
Once the variable is set, the SDK reads it automatically:
```python
import os
from omnidimension import Client
api_key = os.environ.get('OMNIDIM_API_KEY', 'your_api_key_here')
client = Client(api_key)
```
# Quickstart (/docs/get-started/quickstart)
> Install the OmniDimension Python SDK, configure your API key, and run your first request in five minutes.
This guide takes you from a fresh Python environment to a working agent
list call in three steps. The install command is in
[step 1](#step-1).
### Install the SDK [#install-the-sdk]
Install the `omnidimension` package from PyPI.
```bash
pip install omnidimension
```
The package supports Python 3.9 and newer.
### Configure your API key [#configure-your-api-key]
Grab your key from the
[API management dashboard](https://omnidim.io/api-management),
then export it as an environment variable.
```bash
export OMNIDIM_API_KEY="your_api_key_here"
```
For Windows shells and a longer write-up of how the SDK reads this
variable, see [Authentication](/docs/get-started/authentication).
### Make your first request [#make-your-first-request]
List the agents on your account.
```python
import os
from omnidimension import Client
client = Client(os.environ['OMNIDIM_API_KEY'])
agents = client.agent.list()
print(agents)
```
If the call returns a list, your environment is set up. If it raises an
authentication error, double-check the API key in the
[Authentication](/docs/get-started/authentication) guide.
## Next steps [#next-steps]
# Healthcare appointment booking (/docs/examples/health-appointment)
> Build a voice agent for healthcare appointment scheduling, doctor availability, and clinic info.
Walk through configuring a complete appointment-booking voice agent. The
agent greets patients, identifies intent, books slots via Google
Calendar, answers FAQs from a knowledge base, and emails post-call
summaries.
### Write the prompt [#write-the-prompt]
Start the setup by writing a clear initial prompt that defines the
purpose of the bot.
> **Example prompt**: Create a voice AI agent for Sunrise Health Clinic
> to help patients book appointments, check doctor availability, and get
> basic clinic info through voice.
### Answer clarifying questions [#answer-clarifying-questions]
The platform will prompt you with clarifying questions. Answer these
precisely to help tailor the voice agent for your specific use case.
You can select from provided options or write your own custom answers if
the options don't match your needs.
### Automatic agent creation [#automatic-agent-creation]
The system uses your prompt and answers to auto-generate an initial
version of the voice assistant. This includes welcome message, basic
conversational flow, collecting user data, and variable extraction in
post-call.
### Review and customize agent details [#review-and-customize-agent-details]
* Navigate to the **Details** section of the platform
* Edit the welcome message. Ensure it is friendly and aligned with your brand voice.
* Review each step of the user journey (greeting, intent identification, slot filling, confirmation)
* Edit existing prompts or add new sections to better guide the conversation, edge cases, or FAQs
### Test the agent [#test-the-agent]
Use the platform's testing tools at the top right of the window:
* **Test With Chat** for text-based interaction
* **Test With Webcall** for voice-based testing
### Configure model and voice [#configure-model-and-voice]
In the **Configuration** tab you can edit or adjust agent configuration.
* **Model**: select the desired LLM
* **TTS**: configure text-to-speech and choose appropriate voice settings
* Adjust filler words and other behavior customization settings as needed
### Calendar integration [#calendar-integration]
Integrate with Google Calendar to enable automatic booking.
* Open the **Integrations** tab
* Click **Connect** next to Google Calendar
* Complete the OAuth flow to securely link your account
* Once connected, the calendar will be automatically attached to the agent
* The bot can check availability, book slots, and send invites
See [Google Calendar integration](/docs/integrations/google-calendar) for
the full walkthrough.
### Knowledge base [#knowledge-base]
You can add a knowledge base to your bot to provide additional
information.
* Navigate to the **Knowledge Base** section
* Upload relevant documents (for example, PDFs with clinic policies, service descriptions)
* Documents are auto-attached to the bot
* You can also set rules for when and why the knowledge base should be utilized
### Post-call actions [#post-call-actions]
Set up what happens after the call is completed.
* Go to the **Post Call** section
* Select **Email Delivery** as the post-call action
* Enter the recipient's email address
* Choose what to include: call summary, full transcript, sentiment analysis, variable extraction
### Final testing and monitoring [#final-testing-and-monitoring]
* Re-test the agent via chat and web call to confirm all functionality
* Validate booking flow, fallback responses, and knowledge base retrieval
* Navigate to the **Call Logs** section to monitor call interactions with evaluation details
# Examples (/docs/examples)
> Real-world voice agent builds you can learn from and adapt. Healthcare, real estate, support, recruiting, and more.
These are reference builds, not drop-in templates. Each one walks
through the prompt design, knowledge base setup, integrations, and
test calls behind a working agent — so you can study the moving parts,
borrow what fits, and assemble your own.
# Insurance claim status and filing (/docs/examples/insurance-claim-status)
> Build a voice agent that handles insurance claim status checks, new claim filing, and customer inquiries.
Create a complete insurance claim voice agent on OmniDimension. The
agent checks claim status, files new claims, answers policy questions
from a knowledge base, and logs every call to a Google Sheet via
Make.com.
### Configure your agent prompt [#configure-your-agent-prompt]
Start by creating your voice agent with an insurance-specific prompt, or
write a simple prompt and use the **Enhance** button to make it more
descriptive.
### Answer clarifying questions [#answer-clarifying-questions]
Complete the agent setup by answering important questions about your
insurance company, claim types, and verification procedures.
### Test your agent via web call [#test-your-agent-via-web-call]
Once your agent is configured, test it through a web call to verify its
functionality.
* Navigate to the testing interface
* Click **Test with Web Call** to initiate a test conversation
* Speak with your agent to verify proper greeting and introduction
* Test claim status requests and new claim filing scenarios
* Verify natural conversation flow and appropriate responses to policy questions
### Enhance with knowledge base PDFs [#enhance-with-knowledge-base-pdfs]
Upload relevant documents to improve your agent's knowledge about
insurance policies and claims processing.
* Navigate to the **Knowledge Base** tab
* Click **Upload PDFs**
* Drag and drop or select your insurance documents
* PDFs must be under 10MB in size
### Configure post-call settings [#configure-post-call-settings]
Set up data extraction for valuable insights from customer calls.
* Navigate to the **Post-Call** tab
* Set delivery method to **Email** and enter the recipient address
* Choose data to include: Summary, Full Conversation, Sentiment, Extracted Info
* Add extracted variables like caller name, policy number, claim number, incident date, and claim type
### Customize speech-to-text [#customize-speech-to-text]
Fine-tune the speech recognition for insurance terminology.
* Navigate to the **Models** section
* Under **Speech-to-Text Configuration**:
* Select provider (for example, Deepgram Stream)
* Adjust **Silence Timeout**
* Set **Silence Threshold**
### Customize voice and behavior [#customize-voice-and-behavior]
Personalize your agent's voice and interaction style to match your
insurance brand.
* Go to the **Voice** section and select a provider (for example, Eleven Labs)
* Browse, filter, and test voices to match your brand tone
* Choose a voice with a professional, friendly, or empathetic style
* Configure behavior to match your service style (Friendly and Helpful, Professional, Casual, Empathetic)
### Set up Make.com webhook integration [#set-up-makecom-webhook-integration]
Enhance your agent with webhook integration to automatically log all call
data in a spreadsheet.
* Log in to your Make.com account and create a new scenario
* Start with a webhook trigger and copy the generated URL
* Add a Google Sheets module and connect your Google account
* Map webhook data to the spreadsheet columns
* In OmniDimension, set Webhook as the delivery method and paste the URL
* Select data to include: Summary, Full Conversation, Sentiment, Extracted Info
* Test the webhook to ensure call data is recorded properly
See [Make, Zapier, n8n, GHL](/docs/integrations/zapier-make-n8n) and
[post-call actions](/docs/dashboard-guides/post-call) for the full
integration reference.
### Final testing and monitoring [#final-testing-and-monitoring]
Before deploying your agent to production, conduct thorough testing and
set up monitoring.
* Conduct thorough testing with various claim scenarios
* Validate all integrations are working properly
* Check post-call delivery to ensure data is being correctly captured
* Monitor initial calls and adjust configuration as needed
* Review call logs and analytics to identify improvement opportunities
# SaaS OmniSupport agent (/docs/examples/omnisupport-agent)
> Build a voice AI agent for SaaS support with Cal.com, Slack, and Make.com integrations.
Walk through configuring a complete inbound support voice agent for
OmniDimension itself. The agent introduces itself, answers product
questions from a scraped knowledge base, books demos via Cal.com, and
delivers post-call summaries to Slack and Make.com.
### Write the prompt [#write-the-prompt]
Start by writing a clear initial prompt that defines the purpose of the
bot.
```text
You are OmniSupport, an inbound customer support voice assistant for
OmniDimension. Speak in a friendly, polite, and professional tone.
Your main goals are to:
1. Greet the caller and introduce yourself as OmniSupport.
2. Understand the caller's intent. Whether they want to learn about the
product, explore features, or book a demo.
3. Provide brief, clear responses about OmniDimension's offerings:
AI-powered chat and voice agents, workflow automation, integrations.
4. If they request a demo, collect their name, email, and preferred time,
and confirm the booking.
5. Handle unclear queries with a helpful fallback, asking the user to
rephrase.
Always end the call with a thank you and a warm closing message.
Website URL: https://www.omnidim.io/
```
### Web scraping [#web-scraping]
Automatically scrape the website and create a knowledge base from the URL
provided in the prompt.
* The bot will automatically extract information from the website
* Create a structured knowledge base for the agent
* Attach the knowledge base to the bot for real-time information retrieval
### Cal.com integration [#calcom-integration]
Integrate Cal.com for sales or demo call booking.
* Navigate to the Integrations tab
* Click **Connect** next to Cal.com
* Complete the integration steps
* Once connected, the calendar will be automatically attached to the agent
See the [Cal.com integration](/docs/integrations/cal-com) guide for the
full walkthrough.
### Slack integration for post-call [#slack-integration-for-post-call]
Integrate Slack for post-call delivery.
* Navigate to the Integrations tab
* Click **Connect** next to Slack
* Complete the integration steps
* Navigate to the **Post-Call** tab
* Choose **Slack** as the delivery method
* Choose the channel where you want to send the message
* Configure the details to send (full conversation, summary, extracted variables, etc.)
See [Slack integration](/docs/integrations/slack) and
[post-call actions](/docs/dashboard-guides/post-call) for full details.
### Add a Make.com webhook [#add-a-makecom-webhook]
Add a Make.com webhook link and configure the scenario to update an
Airtable database.
* Create a webhook in Make.com
* Set the webhook URL in your post-call agent configuration
* Test the webhook by sending a sample payload
See [Make, Zapier, n8n, GHL](/docs/integrations/zapier-make-n8n) and
[post-call actions](/docs/dashboard-guides/post-call) for the full
configuration reference.
### Final testing and monitoring [#final-testing-and-monitoring]
* Re-test the agent via chat and web call to confirm all functionality
* Validate the booking flow, fallback responses, and knowledge base retrieval
* Navigate to the Call Logs section to monitor call interactions with evaluation details
# Real estate agent (API) (/docs/examples/real-estate)
> Build a voice agent that handles property inquiries, schedules viewings, and manages client interactions via the API.
Build an inbound real estate voice agent end to end with the
OmniDimension Python SDK. The agent presents property listings, matches
client requirements, schedules viewings, and tracks call analytics.
### Get your API key [#get-your-api-key]
Get an API key from the OmniDimension dashboard, in the API section.
### Create the real estate assistant [#create-the-real-estate-assistant]
Start by creating your voice agent with real estate-specific
configuration.
```python
from omnidimension import Client
client = Client("your_api_key_here")
real_estate_agent = client.agent.create(
name="Sarah - Premier Properties Assistant",
welcome_message="Hello! This is Sarah from Premier Properties. I'm here to help you find your dream home or assist with any property inquiries. How can I help you today?",
context_breakdown=[
{
"title": "Available Properties",
"body": """RESIDENTIAL PROPERTIES:
- 3BR Luxury Condo: $450,000 | 2,200 sq ft | Downtown
- 4BR Family Home: $650,000 | 3,500 sq ft | Suburbs
- 2BR Starter Home: $325,000 | 1,800 sq ft | City Center
RENTAL PROPERTIES:
- 2BR Apartment: $2,200/month | 1,200 sq ft | Downtown
- 3BR Townhouse: $3,500/month | 2,000 sq ft | Suburbs
- 1BR Studio: $1,500/month | 800 sq ft | City Center
COMMERCIAL PROPERTIES:
- Office Space: $25/sq ft | 5,000 sq ft | Business District
- Retail Space: $30/sq ft | 3,000 sq ft | Shopping Center
- Warehouse: $15/sq ft | 10,000 sq ft | Industrial Zone"""
},
{
"title": "Inquiry Process",
"body": "1. Greet client professionally 2. Understand property requirements 3. Match with available listings 4. Schedule viewings if interested 5. Collect contact information 6. Provide market information"
},
{
"title": "Service Areas",
"body": "We serve the entire metropolitan area including Downtown, Suburbs, and surrounding neighborhoods. Our agents specialize in residential, commercial, and rental properties."
}
],
call_type="Incoming",
voice={
"provider": "eleven_labs",
"voice_id": "EXAVITQu4vr4xnSDxMaL"
},
model={
"provider": "anthropic",
"model": "gpt-4o-mini",
"temperature": 0.6
}
)
agent_id = real_estate_agent["json"]["id"]
print(f"Real estate agent created with ID: {agent_id}")
```
**Key components:**
* `welcome_message`: professional greeting establishing expertise
* Property listings: comprehensive inventory with prices and details
* Inquiry process: step-by-step workflow for handling inquiries
* Service areas: geographic coverage information
* Voice configuration: professional, trustworthy voice
### Upload property documentation [#upload-property-documentation]
Enhance your agent's knowledge by uploading property brochures.
```python
import base64
def upload_property_documentation(agent_id, brochure_path):
"""Upload property brochure to knowledge base and attach to agent"""
# Read and encode the PDF file
with open(brochure_path, "rb") as file:
file_data = base64.b64encode(file.read()).decode('utf-8')
# Upload to knowledge base
kb_response = client.knowledge_base.create(file_data, "Property_Brochure.pdf")
file_id = kb_response["json"]["file"]["id"]
# Attach to agent
attach_response = client.knowledge_base.attach([file_id], agent_id)
print(f"Property documentation uploaded successfully. File ID: {file_id}")
return file_id
# Upload your property brochure
brochure_file_id = upload_property_documentation(agent_id, "property_brochure.pdf")
```
### Handle incoming client calls [#handle-incoming-client-calls]
Your agent is now ready to handle incoming calls. When clients call your
office number, the agent will:
* Greet clients with the welcome message
* Understand requirements (property type, budget, location)
* Present matching properties based on client preferences
* Schedule viewings for interested properties
* Collect contact information for follow-up
* Provide market information and next steps
### Monitor performance and analytics [#monitor-performance-and-analytics]
Track your real estate agent's performance.
```python
def get_real_estate_analytics(agent_id, days=7):
"""Get comprehensive analytics for real estate agent"""
# Get recent call logs
call_logs = client.call.get_call_logs(agent_id=agent_id, page_size=100)
calls_data = call_logs.get('data', [])
# Calculate metrics
total_calls = len(calls_data)
successful_calls = sum(1 for call in calls_data if call.get('status') == 'completed')
average_duration = sum(call.get('duration', 0) for call in calls_data) / total_calls if total_calls > 0 else 0
# Generate report
analytics_report = {
"period_days": days,
"total_calls": total_calls,
"successful_calls": successful_calls,
"completion_rate": f"{(successful_calls/total_calls*100):.1f}%" if total_calls > 0 else "0%",
"average_call_duration": f"{average_duration:.1f} seconds",
"recent_calls": calls_data[:5] # Last 5 calls
}
return analytics_report
# Get weekly performance report
weekly_report = get_real_estate_analytics(agent_id, days=7)
print("Real Estate Agent Performance Report")
print(f"Total Calls: {weekly_report['total_calls']}")
print(f"Successful Calls: {weekly_report['successful_calls']}")
print(f"Completion Rate: {weekly_report['completion_rate']}")
print(f"Average Call Duration: {weekly_report['average_call_duration']}")
```
### Update agent configuration [#update-agent-configuration]
Modify your agent settings as needed.
```python
def update_agent_details(agent_id, **kwargs):
"""Update agent configuration"""
response = client.agent.update(agent_id, **kwargs)
print(f"Agent updated successfully")
return response
# Update welcome message for weekend hours
update_agent_details(
agent_id,
welcome_message="Good morning! Welcome to Premier Properties. Our weekend open houses are ready! How can I help you find your dream home?"
)
# Switch back to incoming calls
update_agent_details(
agent_id,
call_type="Incoming"
)
```
### Complete setup [#complete-setup]
Here's the complete setup for a production-ready real estate agent.
```python
from omnidimension import Client
import base64
class RealEstateVoiceAgent:
def __init__(self, api_key):
self.client = Client(api_key)
self.agent_id = None
def setup_complete_real_estate_agent(self):
"""Set up a complete real estate voice agent with all features"""
# Create the main agent
agent = self.client.agent.create(
name="Premier Properties - Voice Assistant",
welcome_message="Hello! This is Sarah from Premier Properties. I'm here to help you find your dream home or assist with any property inquiries. How can I help you today?",
context_breakdown=[
{
"title": "Complete Property Listings",
"body": """
RESIDENTIAL PROPERTIES:
- 3BR Luxury Condo: $450,000 | 2,200 sq ft | Downtown | Amenities: Pool, Gym, Doorman
- 4BR Family Home: $650,000 | 3,500 sq ft | Suburbs | Features: Large Yard, 2-Car Garage
- 2BR Starter Home: $325,000 | 1,800 sq ft | City Center | Features: Renovated Kitchen, Hardwood Floors
- 5BR Executive Home: $850,000 | 4,200 sq ft | Gated Community | Features: Home Office, Pool
RENTAL PROPERTIES:
- 2BR Apartment: $2,200/month | 1,200 sq ft | Downtown | Utilities Included
- 3BR Townhouse: $3,500/month | 2,000 sq ft | Suburbs | Pet-Friendly
- 1BR Studio: $1,500/month | 800 sq ft | City Center | Furnished Option Available
- 4BR House: $4,000/month | 2,800 sq ft | Suburbs | 12-month Lease
COMMERCIAL PROPERTIES:
- Office Space: $25/sq ft | 5,000 sq ft | Business District | Class A Building
- Retail Space: $30/sq ft | 3,000 sq ft | Shopping Center | High Foot Traffic
- Warehouse: $15/sq ft | 10,000 sq ft | Industrial Zone | Loading Docks
- Restaurant Space: $35/sq ft | 2,500 sq ft | Downtown | Former Restaurant
"""
},
{
"title": "Client Service Guidelines",
"body": "Always be professional and helpful. Listen carefully to client requirements. Suggest properties that match their needs. Offer virtual tours when possible. Follow up within 24 hours of initial inquiry."
},
{
"title": "Operational Details",
"body": "Office hours: 9 AM - 7 PM weekdays, 10 AM - 5 PM weekends. Service areas: Downtown, Suburbs, and surrounding neighborhoods. Specialties: Residential, Commercial, and Rental properties. Viewing appointments: 1-hour slots."
}
],
call_type="Incoming",
voice={
"provider": "eleven_labs",
"voice_id": "EXAVITQu4vr4xnSDxMaL"
},
model={
"provider": "anthropic",
"model": "gpt-4o-mini",
"temperature": 0.6
}
)
self.agent_id = agent["json"]["id"]
print(f"Real estate agent created: {self.agent_id}")
return self.agent_id
def get_performance_summary(self):
"""Get a quick performance summary"""
if not self.agent_id:
return "No agent configured"
calls = self.client.call.get_call_logs(agent_id=self.agent_id, page_size=50)
total_calls = len(calls.get('data', []))
return {
"agent_id": self.agent_id,
"total_calls_handled": total_calls,
"status": "Active and ready for inquiries!"
}
def upload_property_brochure(self, brochure_path):
"""Upload property brochure to knowledge base"""
if not self.agent_id:
print("Please create agent first")
return None
with open(brochure_path, "rb") as file:
file_data = base64.b64encode(file.read()).decode('utf-8')
kb_response = self.client.knowledge_base.create(file_data, "Property_Brochure.pdf")
file_id = kb_response["json"]["file"]["id"]
self.client.knowledge_base.attach([file_id], self.agent_id)
print(f"Property brochure uploaded: {file_id}")
return file_id
# Initialize and deploy real estate agent
real_estate = RealEstateVoiceAgent("your_api_key_here")
agent_id = real_estate.setup_complete_real_estate_agent()
# Upload brochure if you have a PDF
# real_estate.upload_property_brochure("property_brochure.pdf")
print("\nYour real estate voice agent is now live!")
print(f"Agent ID: {agent_id}")
```
## Key features [#key-features]
### Property management [#property-management]
* Complete property listings with prices and details
* Property matching through natural conversation
* Viewing scheduling and coordination
* Property information and market updates
### Call handling [#call-handling]
* Incoming client calls for property inquiries
* Natural conversation flow
* Professional real estate service experience
* Efficient lead qualification
### Analytics and monitoring [#analytics-and-monitoring]
* Call volume tracking
* Call completion rates
* Average call duration
* Detailed call logs and history
### Knowledge base [#knowledge-base]
* Upload property brochures for enhanced knowledge
* Attach multiple documents to your agent
* Comprehensive property and market information
* Easy knowledge management
### Agent management [#agent-management]
* Update agent configuration anytime
* Modify welcome messages and context
* Real-time agent performance monitoring
* Easy property listing updates
# Recruitment screening bot (/docs/examples/recruit-bot)
> Build an outbound voice agent for initial job applicant screening calls, with bulk call campaigns.
Walk through building an outbound recruitment bot. The agent calls
candidates, runs through screening questions, captures structured data,
and pushes results to your webhook. Ships with a bulk-call workflow for
recruitment drives.
### Write the prompt [#write-the-prompt]
Start by writing a clear initial prompt that defines the purpose of your
recruitment bot. Click the **Enhance Prompt** button to refine your
prompt.
### Answer clarifying questions [#answer-clarifying-questions]
The platform will prompt you with clarifying questions about your
recruitment process. Answer these precisely to help tailor the voice
agent for your specific recruitment workflow. You can select from
provided options or write your own custom answers if the options don't
match your needs.
### Automatic agent creation [#automatic-agent-creation]
Based on your prompt and answers, the system generates an initial
version of RecruitBot. This includes greeting and availability
confirmation, screening questions, candidate data extraction, and call
summary generation.
### Review and customize agent details [#review-and-customize-agent-details]
* Navigate to the **Details** section of the platform
* Edit the welcome message to align with your company's tone and branding
* Review and refine each step of the screening process (greeting, availability check, screening questions)
* Add additional prompts or sections to handle edge cases or specific recruitment scenarios
### Test the agent [#test-the-agent]
Use the platform's testing tools in the top-right corner.
* **Test With Chat** to validate text-based conversation flows
* **Test With Web Call** to simulate real voice calls
* RecruitBot is an outgoing agent that will call candidates directly
* During testing, you'll need to provide candidate details as call context
### Configure model, STT, voice, and personality [#configure-model-stt-voice-and-personality]
Adjust your agent settings for optimal performance.
* **Model**: choose GPT-4.0 for sophisticated conversation handling
* **Speech-to-Text**: select Deepgram with the Nova 3 model and enable advanced features such as number conversion, punctuation, smart formatting
* **Text-to-Speech**: choose Eleven Labs voice (Jessica S, Husky American Female) for a professional tone
* **Personality**: set to **Professional** to maintain appropriate tone for recruitment calls
### Knowledge base [#knowledge-base]
Equip your bot with job or company-specific knowledge.
* Upload relevant documents (job descriptions, company profiles, benefits information)
* These documents help the bot answer candidate queries accurately
* Set rules for when the knowledge base should be utilized during calls
### Post-call actions [#post-call-actions]
Configure what happens after each screening call.
* Go to the **Post Call** section
* Select **Webhook Delivery** as a post-call action
* Add your webhook URL to receive call data
* Choose what to include: call summary, full transcript, and extracted candidate information (job status, location preference, notice period, salary expectations, experience)
* After the call ends, the entire payload will be sent to your webhook URL. From there you can use your own logic to process the data and take appropriate actions.
### Final testing and monitoring [#final-testing-and-monitoring]
* Perform a complete test run to validate all screening questions
* Test fallback responses and human escalation flow
* Verify TTS clarity and pacing for a natural conversation experience
* Use **Call Logs** to track conversations, review AI evaluations, and refine the bot based on real interactions
### Deployment [#deployment]
Deploy your RecruitBot to start screening candidates.
* Click the **Deploy** button in the top-right corner
* Purchase or select an existing phone number
* Attach the number to your RecruitBot by clicking **Attach Assistant**
### Set up a bulk call campaign [#set-up-a-bulk-call-campaign]
After deploying your RecruitBot, you can set up bulk call campaigns to
screen multiple candidates efficiently. See
[bulk calls](/docs/bulk-calls) for the full reference.
* Navigate to the **Bulk Call** section in the dashboard
* Create a new campaign with a descriptive name for your recruitment drive
* Select your RecruitBot's phone number from the dropdown menu
* Prepare a CSV file with candidate information including:
* Required: `phone_number` column with country code (for example, 1 for US, 91 for India)
* Optional but recommended: name, position\_applied, resume\_link, and other relevant context fields
* Upload your CSV file (max 10MB) and review the preview to ensure data is correctly formatted
* Click **Create Campaign** to schedule all calls and track results in the campaign dashboard
# Restaurant agent (API) (/docs/examples/restaurant)
> Build a voice agent that handles restaurant orders, reservations, and outbound marketing campaigns.
Build a restaurant voice agent end to end with the OmniDimension Python
SDK. The agent takes inbound orders from a menu, confirms delivery
details, and dispatches outbound promotional calls.
### Get your API key [#get-your-api-key]
Get an API key from the OmniDimension dashboard, in the API section.
### Create the restaurant assistant [#create-the-restaurant-assistant]
Start by creating your voice agent with restaurant-specific
configuration.
```python
from omnidimension import Client
client = Client("your_api_key_here")
restaurant_agent = client.agent.create(
name="Arnav - Restaurant Assistant",
welcome_message="Namaste! This is Arnav from Spice Garden Restaurant. I'd be happy to take your order for authentic North Indian cuisine. How may I help you today?",
context_breakdown=[
{
"title": "Restaurant Menu",
"body": """APPETIZERS: Vegetable Samosas ₹120 | Paneer Tikka ₹220 | Chicken Tikka ₹250 | Aloo Chaat ₹150
MAIN COURSES: Butter Chicken ₹320 | Palak Paneer ₹280 | Dal Makhani ₹240 | Chicken Curry ₹300 | Lamb Biryani ₹380
BREADS & RICE: Plain Naan ₹50 | Garlic Naan ₹70 | Butter Naan ₹60 | Basmati Rice ₹80 | Vegetable Biryani ₹220
BEVERAGES: Lassi ₹80 | Masala Chai ₹40 | Fresh Lime Soda ₹60"""
},
{
"title": "Order Process",
"body": "1. Greet customer warmly 2. Take complete order with quantities 3. Confirm items and total 4. Collect delivery address 5. Ask for payment preference 6. Provide order confirmation and estimated delivery time"
},
{
"title": "Restaurant Policies",
"body": "Delivery available within 5km radius. Minimum order ₹200. Free delivery above ₹500. Payment methods: Cash on delivery, UPI, Card. Standard delivery time: 30-45 minutes."
}
],
call_type="Incoming",
voice={
"provider": "eleven_labs",
"voice_id": "JBFqnCBsd6RMkjVDRZzb"
},
model={
"provider": "anthropic",
"model": "gpt-4o-mini",
"temperature": 0.7
}
)
agent_id = restaurant_agent["json"]["id"]
print(f"Restaurant agent created with ID: {agent_id}")
```
**Key components:**
* `welcome_message`: first impression when customers call
* Menu context: complete menu with prices in Indian Rupees
* Order process: step-by-step workflow for handling orders
* Restaurant policies: delivery rules and payment options
* Voice configuration: natural-sounding voice
### Upload menu knowledge base [#upload-menu-knowledge-base]
Enhance your agent's knowledge by uploading your restaurant's menu PDF.
```python
import base64
def upload_restaurant_menu(agent_id, menu_pdf_path):
"""Upload menu PDF to knowledge base and attach to agent"""
# Read and encode the PDF file
with open(menu_pdf_path, "rb") as file:
file_data = base64.b64encode(file.read()).decode('utf-8')
# Upload to knowledge base
kb_response = client.knowledge_base.create(file_data, "Restaurant_Menu.pdf")
file_id = kb_response["json"]["file"]["id"]
# Attach to agent
attach_response = client.knowledge_base.attach([file_id], agent_id)
print(f"Menu uploaded successfully. File ID: {file_id}")
return file_id
# Upload your restaurant menu
menu_file_id = upload_restaurant_menu(agent_id, "restaurant_menu.pdf")
```
### Handle incoming customer calls [#handle-incoming-customer-calls]
Your agent is now ready to handle incoming calls. When customers call
your restaurant number, the agent will:
* Greet customers with the welcome message
* Present menu options based on customer preferences
* Take detailed orders with quantities and special requests
* Calculate totals including taxes and delivery charges
* Collect delivery information and confirm address
* Ask for payment preference (cash, UPI, card)
* Provide confirmation with estimated delivery time
### Dispatch outbound marketing calls [#dispatch-outbound-marketing-calls]
Reach out to customers with promotional offers.
```python
def launch_marketing_campaign(agent_id, customer_list, offer_message):
"""Launch outbound marketing calls to customer list"""
# Update agent for marketing calls
marketing_message = f"Hello! This is Arnav from Spice Garden Restaurant. {offer_message} Would you like to place an order today?"
client.agent.update(
agent_id,
welcome_message=marketing_message,
call_type="Outgoing"
)
# Dispatch calls to customers
call_results = []
for customer_phone in customer_list:
try:
call_response = client.call.dispatch_call(
agent_id=agent_id,
to_number=customer_phone,
call_context="Marketing campaign - Special dinner offer"
)
call_results.append({
"phone": customer_phone,
"status": "dispatched",
"call_id": call_response.get("call_id")
})
except Exception as e:
call_results.append({
"phone": customer_phone,
"status": "failed",
"error": str(e)
})
return call_results
# Launch dinner special campaign
dinner_customers = [
"+919876543210",
"+919876543211",
"+919876543212"
]
offer_text = "We have a special 20% discount on our dinner combo meals today!"
campaign_results = launch_marketing_campaign(agent_id, dinner_customers, offer_text)
print("Marketing campaign launched:")
for result in campaign_results:
print(f"{result['phone']}: {result['status']}")
```
### Monitor performance and analytics [#monitor-performance-and-analytics]
Track your restaurant agent's performance.
```python
def get_restaurant_analytics(agent_id, days=7):
"""Get comprehensive analytics for restaurant agent"""
# Get recent call logs
call_logs = client.call.get_call_logs(agent_id=agent_id, page_size=100)
calls_data = call_logs.get('data', [])
# Calculate metrics
total_calls = len(calls_data)
successful_calls = sum(1 for call in calls_data if call.get('status') == 'completed')
average_duration = sum(call.get('duration', 0) for call in calls_data) / total_calls if total_calls > 0 else 0
# Generate report
analytics_report = {
"period_days": days,
"total_calls": total_calls,
"successful_calls": successful_calls,
"completion_rate": f"{(successful_calls/total_calls*100):.1f}%" if total_calls > 0 else "0%",
"average_call_duration": f"{average_duration:.1f} seconds",
"recent_calls": calls_data[:5] # Last 5 calls
}
return analytics_report
# Get weekly performance report
weekly_report = get_restaurant_analytics(agent_id, days=7)
print("Restaurant Agent Performance Report")
print(f"Total Calls: {weekly_report['total_calls']}")
print(f"Successful Calls: {weekly_report['successful_calls']}")
print(f"Completion Rate: {weekly_report['completion_rate']}")
print(f"Average Call Duration: {weekly_report['average_call_duration']}")
```
### Update agent configuration [#update-agent-configuration]
Modify your agent settings as needed.
```python
def update_agent_details(agent_id, **kwargs):
"""Update agent configuration"""
response = client.agent.update(agent_id, **kwargs)
print(f"Agent updated successfully")
return response
# Update welcome message for dinner hours
update_agent_details(
agent_id,
welcome_message="Good evening! Welcome to Spice Garden Restaurant. Our dinner specials are ready! How can I help you?"
)
# Switch back to incoming calls after marketing campaign
update_agent_details(
agent_id,
call_type="Incoming"
)
```
### Complete setup [#complete-setup]
Here's the complete setup for a production-ready restaurant agent.
```python
from omnidimension import Client
import base64
class RestaurantVoiceAgent:
def __init__(self, api_key):
self.client = Client(api_key)
self.agent_id = None
def setup_complete_restaurant_agent(self):
"""Set up a complete restaurant voice agent with all features"""
# Create the main agent
agent = self.client.agent.create(
name="Spice Garden - Voice Assistant",
welcome_message="Namaste! Welcome to Spice Garden Restaurant. I'm here to help you with orders, reservations, and any questions. How can I assist you today?",
context_breakdown=[
{
"title": "Full Menu & Pricing",
"body": """
APPETIZERS: Veg Samosas ₹120 | Paneer Tikka ₹220 | Chicken Tikka ₹250 | Fish Tikka ₹280 | Aloo Chaat ₹150
MAIN COURSES: Butter Chicken ₹320 | Palak Paneer ₹280 | Dal Makhani ₹240 | Chicken Curry ₹300 | Lamb Biryani ₹380 | Fish Curry ₹300
BREADS: Plain Naan ₹50 | Garlic Naan ₹70 | Butter Naan ₹60 | Roti ₹30 | Kulcha ₹60
RICE: Basmati Rice ₹80 | Veg Biryani ₹220 | Jeera Rice ₹100
BEVERAGES: Sweet Lassi ₹80 | Salted Lassi ₹80 | Masala Chai ₹40 | Fresh Lime ₹60 | Cold Coffee ₹90
DESSERTS: Gulab Jamun ₹100 | Rasmalai ₹120 | Kulfi ₹80
"""
},
{
"title": "Service Guidelines",
"body": "Always be warm and helpful. Suggest popular combinations. Inform about cooking time for special requests. Confirm orders clearly before processing. Handle complaints with empathy."
},
{
"title": "Operational Details",
"body": "Operating hours: 11 AM - 11 PM daily. Delivery radius: 5km. Minimum order: ₹200. Free delivery above ₹500. Estimated delivery: 30-45 minutes. Payment: Cash, UPI, Cards accepted."
}
],
call_type="Incoming",
voice={
"provider": "eleven_labs",
"voice_id": "JBFqnCBsd6RMkjVDRZzb"
},
model={
"provider": "anthropic",
"model": "gpt-4o-mini",
"temperature": 0.7
}
)
self.agent_id = agent["json"]["id"]
print(f"Restaurant agent created: {self.agent_id}")
return self.agent_id
def get_performance_summary(self):
"""Get a quick performance summary"""
if not self.agent_id:
return "No agent configured"
calls = self.client.call.get_call_logs(agent_id=self.agent_id, page_size=50)
total_calls = len(calls.get('data', []))
return {
"agent_id": self.agent_id,
"total_calls_handled": total_calls,
"status": "Active and ready for orders!"
}
def upload_menu_pdf(self, menu_pdf_path):
"""Upload menu PDF to knowledge base"""
if not self.agent_id:
print("Please create agent first")
return None
with open(menu_pdf_path, "rb") as file:
file_data = base64.b64encode(file.read()).decode('utf-8')
kb_response = self.client.knowledge_base.create(file_data, "Restaurant_Menu.pdf")
file_id = kb_response["json"]["file"]["id"]
self.client.knowledge_base.attach([file_id], self.agent_id)
print(f"Menu PDF uploaded: {file_id}")
return file_id
# Initialize and deploy restaurant agent
restaurant = RestaurantVoiceAgent("your_api_key_here")
agent_id = restaurant.setup_complete_restaurant_agent()
print("\nYour restaurant voice agent is now live!")
print(f"Agent ID: {agent_id}")
```
## Key features [#key-features]
### Order management [#order-management]
* Complete menu with prices and descriptions
* Order taking through natural conversation
* Menu recommendations and suggestions
* Order confirmation with customer details
### Call handling [#call-handling]
* Incoming customer calls for orders
* Outbound marketing and promotional calls
* Natural Hindi/English conversation flow
* Professional restaurant service experience
### Analytics and monitoring [#analytics-and-monitoring]
* Call volume tracking
* Call completion rates
* Average call duration
* Detailed call logs and history
### Knowledge base [#knowledge-base]
* Upload menu PDFs for enhanced knowledge
* Attach multiple documents to your agent
* Comprehensive menu and policy information
* Easy knowledge management
### Agent management [#agent-management]
* Update agent configuration anytime
* Switch between incoming and outgoing modes
* Modify welcome messages and context
* Real-time agent performance monitoring
# Travel planning and lead generation (/docs/examples/travel-planning-agent)
> Build an engaging voice agent that helps users plan trips while collecting lead information for your travel business.
Create a complete travel planning voice agent on OmniDimension. The agent
suggests destinations, answers questions from a knowledge base, pulls
real-time info via web search, and pushes leads to HubSpot via n8n.
### Configure your agent prompt [#configure-your-agent-prompt]
Start by creating your voice agent with a travel-specific prompt that
establishes the agent's role and capabilities.
### Answer clarifying questions [#answer-clarifying-questions]
Complete the agent setup by answering important questions about your
travel agency, destination specialties, and lead collection procedures.
### Enhance with knowledge base PDFs [#enhance-with-knowledge-base-pdfs]
Upload relevant travel documents to improve your agent's knowledge about
destinations, packages, and travel policies.
* Go to the **Knowledge Base** tab and click **Upload PDFs**
* Upload brochures, guides, package details, and travel requirement documents
* Include files covering destinations, pricing, FAQs, and seasonal tips
* Ensure each PDF is under 10MB in size
### Enable web search [#enable-web-search]
Activate web search to allow your agent to provide real-time information
about destinations, weather, attractions, and travel advisories.
* Navigate to the **Integrations** tab
* Toggle **Web Search** to ON
* Configure the search engine as OpenAI or DuckDuckGo
* Now your bot can provide real-time information about destinations, weather, and travel advisories
### Test your agent via web call [#test-your-agent-via-web-call]
Once your agent is configured, test it through a web call to verify its
functionality.
* Open the testing interface and click **Test with Web Call**
* Try scenarios like destination suggestions, package inquiries, and travel requirements
* Ensure lead info is captured accurately and responses feel natural
### Configure post-call settings [#configure-post-call-settings]
Set up data extraction for valuable lead information from customer calls.
* Go to the **Post-Call** tab
* Set delivery method to **Webhook** for n8n integration
* Select data to include: Summary, Full Conversation, Sentiment, Extracted Info
* Add variables to extract from each call under **Extracted Variables**
### Set up an n8n webhook for HubSpot [#set-up-an-n8n-webhook-for-hubspot]
Create an automation workflow that sends lead information directly to
HubSpot CRM.
* Log in to your n8n account and create a new workflow
* Add a Webhook node as the trigger and configure it with the **POST** method
* Copy the generated webhook URL for the OmniDimension post-call settings
* Add a HubSpot node and connect your HubSpot account
* Select **Create/Update** operation and choose **Tickets** as the resource
* Map incoming webhook data to HubSpot contact and ticket fields
* Format dates and fields as needed within the workflow
* Test the integration to verify successful data flow
### Customize voice and behavior [#customize-voice-and-behavior]
Personalize your agent's voice and interaction style to match your travel
brand's personality.
* Go to the **Voice** section and select a provider (for example, Eleven Labs)
* Browse and test voices to find an enthusiastic, friendly tone
* Filter voices by language, accent, and other traits
* Set **Behavior** to **Enthusiastic and Engaging** for travel planning
### Final testing and deployment [#final-testing-and-deployment]
Before going live, conduct thorough testing and prepare for deployment.
* Conduct testing with various travel scenarios
* Verify integrations: n8n to HubSpot, email delivery, web search
* Test lead info extraction accuracy for all the fields
# Utility bill payment agent (API) (/docs/examples/utility-bill-payment)
> Build an outbound voice agent that handles utility bill payments, sends payment reminders, and manages customer interactions.
Build an outbound payment-reminder voice agent end to end with the
OmniDimension Python SDK. The agent verifies accounts, collects
payments, and runs bulk reminder campaigns from a CSV.
### Get your API key [#get-your-api-key]
Get an API key from the OmniDimension dashboard, in the API section.
### Create the payment assistant [#create-the-payment-assistant]
Start by creating your voice agent with payment-specific configuration.
```python
from omnidimension import Client
client = Client("your_api_key_here")
payment_agent = client.agent.create(
name="BillBot - Payment Assistant",
welcome_message="Hello! This is BillBot calling about your utility bill. How can I help you today?",
context_breakdown=[
{
"title": "Payment Options",
"body": """PAYMENT METHODS:
- Online: www.pay.com
- Phone: 1-800-PAY-BILL
- Auto-pay: Available for all accounts
- Card Fee: $2.95 per transaction
PAYMENT DEADLINES:
- Bills due: 21st of each month
- Late fee: $25 after 10 days
- Disconnection: 30 days past due"""
},
{
"title": "Account Information",
"body": "1. Verify account number 2. Check current balance 3. Confirm payment method 4. Process payment 5. Send confirmation"
},
{
"title": "Payment Policies",
"body": "We accept all major credit cards, bank transfers, and cash payments. Auto-pay customers receive a 2% discount. Payment plans available for qualifying accounts."
}
],
call_type="Outgoing",
voice={
"provider": "eleven_labs",
"voice_id": "EXAVITQu4vr4xnSDxMaL"
},
model={
"provider": "anthropic",
"model": "gpt-4o-mini",
"temperature": 0.4
}
)
agent_id = payment_agent["json"]["id"]
print(f"Payment agent created with ID: {agent_id}")
```
**Key components:**
* `welcome_message`: professional greeting for payment-related calls
* Payment options: comprehensive payment methods and deadlines
* Account information: step-by-step workflow for payment processing
* Payment policies: clear guidelines for payment options
* Voice configuration: professional, trustworthy voice
### Process bulk payment reminders [#process-bulk-payment-reminders]
Send payment reminders to multiple customers from a CSV file.
```python
import csv
import json
from datetime import datetime
def send_payment_reminders(customer_file):
"""Send payment reminders to customers from CSV file"""
with open(customer_file) as f:
reader = csv.DictReader(f)
for row in reader:
context = json.dumps({
"account": row["account"],
"name": row["name"],
"balance": row["balance"],
"due_date": row["due_date"]
})
response = client.call.dispatch_call(
agent_id=agent_id,
to_number=row["phone_number"],
call_context=context
)
print(f"Reminder sent to {row['name']}: {response['json']['id']}")
# Example customer data
customers = [
["phone_number", "account", "name", "balance", "due_date"],
["+15551234567", "5001234567", "John Smith", "125.50", "2024-03-21"],
["+15551234568", "5001234568", "Mary Jones", "89.75", "2024-03-15"]
]
# Save customer data
with open("customers.csv", "w") as f:
writer = csv.writer(f)
writer.writerows(customers)
# Send reminders
send_payment_reminders("customers.csv")
```
### Handle payment calls [#handle-payment-calls]
Your agent is now ready to handle payment-related calls. When customers
receive a call, the agent will:
* Greet customers with the welcome message
* Verify account information for security
* Present payment options based on customer preferences
* Process payments through the preferred method
* Send confirmation with payment details
* Schedule follow-up if needed
### Monitor performance and analytics [#monitor-performance-and-analytics]
Track your payment agent's performance.
```python
def get_payment_analytics(agent_id, days=7):
"""Get comprehensive analytics for payment agent"""
# Get recent call logs
call_logs = client.call.get_call_logs(agent_id=agent_id, page_size=100)
calls_data = call_logs.get('data', [])
# Calculate metrics
total_calls = len(calls_data)
successful_calls = sum(1 for call in calls_data if call.get('status') == 'completed')
average_duration = sum(call.get('duration', 0) for call in calls_data) / total_calls if total_calls > 0 else 0
# Generate report
analytics_report = {
"period_days": days,
"total_calls": total_calls,
"successful_calls": successful_calls,
"completion_rate": f"{(successful_calls/total_calls*100):.1f}%" if total_calls > 0 else "0%",
"average_call_duration": f"{average_duration:.1f} seconds",
"recent_calls": calls_data[:5] # Last 5 calls
}
return analytics_report
# Get weekly performance report
weekly_report = get_payment_analytics(agent_id, days=7)
print("Payment Agent Performance Report")
print(f"Total Calls: {weekly_report['total_calls']}")
print(f"Successful Calls: {weekly_report['successful_calls']}")
print(f"Completion Rate: {weekly_report['completion_rate']}")
print(f"Average Call Duration: {weekly_report['average_call_duration']}")
```
### Update agent configuration [#update-agent-configuration]
Modify your agent settings as needed.
```python
def update_agent_details(agent_id, **kwargs):
"""Update agent configuration"""
response = client.agent.update(agent_id, **kwargs)
print(f"Agent updated successfully")
return response
# Update welcome message for payment deadline
update_agent_details(
agent_id,
welcome_message="Hello! This is BillBot. Your utility bill payment is due in 3 days. Would you like to make a payment now?"
)
# Switch back to outgoing calls
update_agent_details(
agent_id,
call_type="Outgoing"
)
```
### Complete setup [#complete-setup]
Here's the complete setup for a production-ready payment agent.
```python
from omnidimension import Client
import base64
import csv
import json
class UtilityBillPaymentAgent:
def __init__(self, api_key):
self.client = Client(api_key)
self.agent_id = None
def setup_complete_payment_agent(self):
"""Set up a complete utility bill payment voice agent with all features"""
# Create the main agent
agent = self.client.agent.create(
name="BillBot - Utility Payment Assistant",
welcome_message="Hello! This is BillBot from City Utilities. I'm calling about your utility bill. How can I assist you today?",
context_breakdown=[
{
"title": "Complete Payment Options",
"body": """
PAYMENT METHODS:
- Online: www.cityutilities.com/pay
- Phone: 1-800-PAY-BILL (1-800-729-2455)
- Auto-pay: Available for all accounts with 2% discount
- Mobile App: Available on iOS and Android
- Mail: P.O. Box 12345, City, State 67890
- In-person: 123 Main Street, City, State 67890
PAYMENT DEADLINES:
- Bills due: 21st of each month
- Grace period: 5 days
- Late fee: $25 after 10 days
- Disconnection warning: 20 days past due
- Disconnection: 30 days past due
- Reconnection fee: $50
"""
},
{
"title": "Customer Service Guidelines",
"body": "Always be professional and helpful. Listen carefully to customer concerns. Offer payment plans when appropriate. Verify identity before discussing account details. Provide clear payment instructions."
},
{
"title": "Operational Details",
"body": "Call center hours: 8 AM - 8 PM weekdays, 9 AM - 5 PM weekends. Payment processing time: Immediate for online/phone, 1-2 business days for mail. Auto-pay enrollment available during call. Payment plans require supervisor approval for balances over $500."
}
],
call_type="Outgoing",
voice={
"provider": "eleven_labs",
"voice_id": "EXAVITQu4vr4xnSDxMaL"
},
model={
"provider": "anthropic",
"model": "gpt-4o-mini",
"temperature": 0.4
}
)
self.agent_id = agent["json"]["id"]
print(f"Payment agent created: {self.agent_id}")
return self.agent_id
def get_performance_summary(self):
"""Get a quick performance summary"""
if not self.agent_id:
return "No agent configured"
calls = self.client.call.get_call_logs(agent_id=self.agent_id, page_size=50)
total_calls = len(calls.get('data', []))
return {
"agent_id": self.agent_id,
"total_calls_handled": total_calls,
"status": "Active and ready for payment processing!"
}
def send_bulk_payment_reminders(self, customer_file):
"""Send payment reminders to customers from CSV file"""
if not self.agent_id:
print("Please create agent first")
return None
results = []
with open(customer_file) as f:
reader = csv.DictReader(f)
for row in reader:
context = json.dumps({
"account": row["account"],
"name": row["name"],
"balance": row["balance"],
"due_date": row["due_date"]
})
try:
response = self.client.call.dispatch_call(
agent_id=self.agent_id,
to_number=row["phone_number"],
call_context=context
)
results.append({
"name": row["name"],
"status": "success",
"call_id": response["json"]["id"]
})
except Exception as e:
results.append({
"name": row["name"],
"status": "failed",
"error": str(e)
})
return results
# Initialize and deploy payment agent
payment_agent = UtilityBillPaymentAgent("your_api_key_here")
agent_id = payment_agent.setup_complete_payment_agent()
print("\nYour utility bill payment voice agent is now live!")
print(f"Agent ID: {agent_id}")
```
## Key features [#key-features]
### Payment management [#payment-management]
* Multiple payment methods and options
* Automated payment reminders
* Payment processing through conversation
* Payment confirmation and receipts
### Call handling [#call-handling]
* Outbound payment reminder calls
* Natural conversation flow
* Professional payment service experience
* Secure account verification
### Analytics and monitoring [#analytics-and-monitoring]
* Call volume tracking
* Call completion rates
* Average call duration
* Detailed call logs and history
### Agent management [#agent-management]
* Update agent configuration anytime
* Modify welcome messages and context
* Real-time agent performance monitoring
* Easy payment option updates
# Cal.com (/docs/integrations/cal-com)
> Integrate Cal.com with your voice AI agent for seamless meeting scheduling.
Cal.com integration allows your agent to access your calendar and
schedule meetings on your behalf, creating a seamless scheduling
experience for your clients.
## Key benefits [#key-benefits]
* Automated meeting scheduling
* Calendar availability checking
* Streamlined appointment booking process
## Setup option 1: from the main dashboard [#setup-option-1-from-the-main-dashboard]
### Open the integrations page [#open-the-integrations-page]
Go to the Integrations page in your dashboard and select the **All
Integrations** tab.
### Connect Cal.com [#connect-calcom]
Find the Cal.com card and click **Connect**, then configure your
integration (see configuration details below).
### Attach to your agent [#attach-to-your-agent]
Go to your agent's edit page, open the **Integrations** tab, and attach
the integration from the dropdown.
## Setup option 2: from agent configuration [#setup-option-2-from-agent-configuration]
### Open the agent's integrations tab [#open-the-agents-integrations-tab]
Go to your agent's edit page and select the **Integrations** tab.
### Connect Cal.com [#connect-calcom-1]
Under **Connect New Integrations**, find Cal.com and click **Connect**.
Configure your integration. The integration will automatically attach to
your agent.
## Setup option 3: from the chat interface [#setup-option-3-from-the-chat-interface]
### Ask in chat [#ask-in-chat]
Use natural language like "Connect my Cal.com calendar" or "Set up
Cal.com integration". A connection widget will automatically appear.
### Add the integration [#add-the-integration]
Click **Add integration** to navigate to the integration tab. Under
**Connect New Integrations**, find Cal.com and click **Connect**.
Configure your integration.
## Configuration guide [#configuration-guide]
Enter the following information in the modal during setup:
* **Integration Name**: choose a descriptive name (for example, "My Work Calendar")
* **API Key**: your Cal.com API key
* **Event Type ID**: the ID of the event type for scheduling
* **Timezone**: select your preferred timezone
## Using with your agent [#using-with-your-agent]
* Check your calendar availability
* Schedule meetings with clients
* Manage appointment bookings
## Finding your Cal.com API key [#finding-your-calcom-api-key]
* Log in to your Cal.com account
* Navigate to **Settings → Developer → API Keys**
* Create a new API key with appropriate permissions
* Copy the generated key
## Finding your event type ID [#finding-your-event-type-id]
* In Cal.com, go to **Event Types**
* Select the event type you want to use
* The ID is visible in the URL. For example, `https://app.cal.com/event-types/123456`. The `123456` part is your event type ID.
# Custom API (/docs/integrations/custom-api)
> Connect your agent to any external service using custom API integration.
Custom API integration connects your agent to external services through
REST APIs, allowing it to fetch data or perform actions using third-party
services.
## Key benefits [#key-benefits]
* Access external data sources in real-time
* Connect to your own backend services
* Integrate with virtually any REST API endpoint
* Extend your agent's capabilities with custom functionality
## Setup option 1: from the main dashboard [#setup-option-1-from-the-main-dashboard]
### Open the integrations page [#open-the-integrations-page]
Go to the Integrations page in your dashboard and select the **All
Integrations** tab.
### Connect a Custom API [#connect-a-custom-api]
Find the Custom API card and click **Connect**. Configure your API (see
configuration details below) and test it in the **Test** tab.
### Attach to your agent [#attach-to-your-agent]
Go to your agent's edit page, open the **Integrations** tab, and attach
the integration from the dropdown.
## Setup option 2: from agent configuration [#setup-option-2-from-agent-configuration]
### Open the agent's integrations tab [#open-the-agents-integrations-tab]
Go to your agent's edit page and select the **Integrations** tab.
### Connect a Custom API [#connect-a-custom-api-1]
Under **Connect New Integrations**, find Custom API and click
**Connect**. Configure and test your API. The integration will
automatically attach to your agent.
## Setup option 3: from the chat interface [#setup-option-3-from-the-chat-interface]
### Ask in chat [#ask-in-chat]
Use natural language like "Connect my CRM api" or "Connect my Airtable
api". A connection widget will automatically appear.
### Add the integration [#add-the-integration]
Click **Add integration** to navigate to the integration tab. Under
**Connect New Integrations**, find Custom API Integration and click
**Connect**. Configure your integration.
## Configuration guide: basic settings [#configuration-guide-basic-settings]
* **Integration Name**: choose a descriptive name (for example, "Weather API")
* **Description**: explain the API's purpose and usage. This is important for LLM tool calling.
* **URL**: full endpoint URL (for example, `https://api.example.com/data`)
* **Method**: select HTTP method (GET, POST, PUT, DELETE)
## Configuration guide: headers [#configuration-guide-headers]
* Authorization tokens
* `Content-Type` specifications
* API keys
* Custom headers
## Configuration guide: parameters [#configuration-guide-parameters]
Specify both query parameters (GET) and body parameters (POST or PUT).
* **Name**: parameter identifier
* **Description**: purpose of this parameter
* **Required**: toggle between optional and required
* **Data Type**: select from dropdown
* **AI Generated**: toggle whether the AI should dynamically generate values
## Testing your integration [#testing-your-integration]
### Open the test tab [#open-the-test-tab]
Navigate to the **Test** tab.
### Run a test [#run-a-test]
Enter test values for all parameters and click **Test API** to verify the
connection.
### Save the integration [#save-the-integration]
After successful testing, click **Save Integration**.
## Using with your agent [#using-with-your-agent]
* Once connected, your agent will automatically use this API when appropriate
* Usage is determined based on the API description you provide
## Example: Airtable [#example-airtable]
Example of using Airtable with custom API integration.
## Example: Supabase user authentication [#example-supabase-user-authentication]
Walk through creating a complete Supabase authentication integration step
by step.
### Add integration name and description [#add-integration-name-and-description]
Make sure descriptions are clear and concise. The AI uses them to
understand the integration and decide when to call it.
### Configure URL, method, and parameters [#configure-url-method-and-parameters]
Set the API URL and HTTP method, then add the query parameters needed
for the request. Enable **AI Generated** on the query parameters so the
agent can derive the values from the conversation.
### Test and save [#test-and-save]
Click next to move to the test step, run a sample request, and save the
integration once the response is correct.
## Other example use cases [#other-example-use-cases]
* **CRM integration**: retrieve customer data from Salesforce or HubSpot
* **Inventory management**: check product availability in real time
* **User verification**: authenticate users against internal databases
* **Weather data**: fetch current weather for location-based services
* **Booking systems**: check availability and make reservations
## Pro tips [#pro-tips]
* Provide detailed descriptions for AI-generated parameters
* Use specific examples in your descriptions
* Test thoroughly before deploying to production
# Google Calendar (/docs/integrations/google-calendar)
> Integrate Google Calendar with your agent to schedule and manage meetings automatically.
Google Calendar integration allows your agent to check calendar
availability and book appointments automatically using OAuth-based secure
access.
## Key benefits [#key-benefits]
* Automated appointment scheduling
* Real-time calendar availability sync
* Avoid scheduling conflicts
* Customize meeting names, duration, and working hours
## Setup option 1: from the main dashboard [#setup-option-1-from-the-main-dashboard]
### Open the integrations page [#open-the-integrations-page]
Go to the Integrations page in your dashboard and select the **All
Integrations** tab.
### Connect Google Calendar [#connect-google-calendar]
Find the Google Calendar card and click **Connect**. Authorize access
through Google OAuth login. Once authenticated, your Google Calendar will
connect automatically.
## Setup option 2: from agent configuration [#setup-option-2-from-agent-configuration]
### Open the agent's integrations tab [#open-the-agents-integrations-tab]
Go to your agent's edit page and select the **Integrations** tab.
### Connect Google Calendar [#connect-google-calendar-1]
Find **Google Calendar** under **Connect New Integrations** and click
**Connect**. Follow the OAuth login process. Once verified, the
integration will auto-attach to your agent.
## Configuration modal [#configuration-modal]
After connecting, you can customize your calendar settings via the
configuration modal.
* **Integration Name**: a label to identify this integration
* **Description**: purpose of the integration
* **Default Meeting Name**: title used for all scheduled events
* **Default Meeting Duration**: choose between 15, 30, 60 minutes, etc.
* **Business Hours**: set your availability window (start and end time)
## Using with your agent [#using-with-your-agent]
* The agent will automatically fetch available time slots and suggest appointments
* Events will only be scheduled within the defined business hours
* Meeting invites will be auto-created in your Google Calendar
* The user receives a confirmation and calendar link instantly
## Best practices [#best-practices]
* Use descriptive integration names to manage multiple calendars
* Update business hours as your availability changes
* Test the calendar booking flow using simulated queries
* Ensure you have granted correct permissions during OAuth login
# HubSpot (/docs/integrations/hubspot)
> Integrate HubSpot with your voice AI agent to automatically manage contacts, deals, and more.
The HubSpot integration enables your voice AI agent to sync post-call data
into your CRM. You can automatically create and update contacts, deals,
and tickets based on extracted variables from the conversation.
## Key benefits [#key-benefits]
* One-click OAuth integration
* Automatic syncing of leads and deals post-call
* Streamlined contact and CRM record creation
## Setup option 1: from the main dashboard [#setup-option-1-from-the-main-dashboard]
### Open the integrations page [#open-the-integrations-page]
Go to the Integrations page in your dashboard and select the **All
Integrations** tab.
### Connect HubSpot [#connect-hubspot]
Find the HubSpot card and click **Connect**. Enter your integration name
and description, then click **Connect with HubSpot**.
### Authorize via OAuth [#authorize-via-oauth]
An OAuth popup will appear. Log in to your HubSpot account and grant
access.
### Attach to your agent [#attach-to-your-agent]
Go to your agent's edit page, open the **Integrations** tab, and attach
the HubSpot integration from the dropdown.
## Setup option 2: from agent configuration [#setup-option-2-from-agent-configuration]
### Open the agent's integrations tab [#open-the-agents-integrations-tab]
Navigate to your agent's edit page and select the **Integrations** tab.
### Connect a new HubSpot integration [#connect-a-new-hubspot-integration]
Click **Connect New Integration** and choose **HubSpot**. Enter a
meaningful integration name and purpose, then click **Connect with
HubSpot** and complete OAuth login. The integration will automatically
attach to the agent.
## Using with your agent [#using-with-your-agent]
* Your agent will automatically push call summary and extracted data to HubSpot
* Based on the call flow, it can create new contacts or update existing ones
* You can map variables like name, email, phone, intent, and deal size
## Tips for effective integration [#tips-for-effective-integration]
* Use clear and consistent naming for integrations
* Ensure your HubSpot user has access to create and update contacts and deals
* Map only relevant variables to avoid clutter
* Test with a sample call to verify record creation in HubSpot
# Integrations (/docs/integrations)
> Connect OmniDimension to anything. Custom API turns any REST endpoint into an agent action, plus prebuilt connectors for the platforms you already use.
If your tool has an API, your agent can use it. Custom API is the
universal escape hatch: any REST endpoint
becomes an action your agent can call mid-conversation. The
prebuilt connectors below are shortcuts for platforms we see most often,
but they're not the limit. 🔌
## Universal connector [#universal-connector]
## Automation platforms [#automation-platforms]
Already running flows in Zapier, Make, n8n, or GHL? Plug OmniDimension
into them with webhooks and REST.
## Prebuilt connectors [#prebuilt-connectors]
One-click OAuth and prefilled field mappings — use these when your CRM
or scheduling tool is on the list.
Almost everything modern exposes a REST API. Use
[Custom API](/docs/integrations/custom-api) and you're connected — no
waiting for us to ship a dedicated connector.
# Salesforce (/docs/integrations/salesforce)
> Connect your Salesforce CRM with your voice AI agent to manage contacts, leads, and opportunities.
The Salesforce integration allows your agent to access and update records
in your CRM automatically. After each call, OmniDimension can push
post-call data to Salesforce objects like Leads, Contacts, or
Opportunities.
## Key benefits [#key-benefits]
* Automatically update CRM records after a call
* Streamline lead management workflows
* Create or update contacts, accounts, and opportunities based on extracted variables
## Setup option 1: from the main dashboard [#setup-option-1-from-the-main-dashboard]
### Open the integrations page [#open-the-integrations-page]
Go to the Integrations page in your dashboard and select the **All
Integrations** tab.
### Connect Salesforce [#connect-salesforce]
Find the Salesforce card and click **Connect**. Enter your Salesforce
instance details and credentials, then save the integration and test the
connection.
### Attach to your agent [#attach-to-your-agent]
Go to your agent's edit page, open the **Integrations** tab, and attach
the Salesforce integration from the dropdown.
## Setup option 2: from agent configuration [#setup-option-2-from-agent-configuration]
### Open the agent's integrations tab [#open-the-agents-integrations-tab]
Go to your agent's edit page and open the **Integrations** tab.
### Connect Salesforce [#connect-salesforce-1]
Choose **Salesforce** from the **Connect New Integration** section and
click the connect button. Enter your integration name, description, and
instance URL.
### Provide credentials [#provide-credentials]
Provide your Salesforce username and password, then enter your client ID
and client secret from the connected Salesforce app.
### Select objects and save [#select-objects-and-save]
Select the Salesforce objects you want to connect to (for example, Lead,
Contact, Opportunity). Click **Save** to finish setup and attach the
integration to the agent.
## Configuration fields [#configuration-fields]
* **Integration Name**: choose a recognizable name
* **Description**: purpose or details about this integration
* **Instance URL**: your Salesforce domain URL (for example, `https://yourcompany.my.salesforce.com`)
* **Username and Password**: your Salesforce login credentials
* **Client ID and Client Secret**: from your connected Salesforce app
* **Connected Objects**: select the Salesforce objects (Leads, Contacts, Opportunities, etc.) you wish to sync
## Using with your agent [#using-with-your-agent]
* Extracted data from user calls will be sent to Salesforce automatically
* Mapped variables are updated in the selected objects
* Conversation history, intent, and sentiment can also be logged
## Tips for a successful integration [#tips-for-a-successful-integration]
* Use a dedicated Salesforce integration user account
* Ensure the connected app has API access enabled
* Map only the necessary fields to avoid data clutter
* Test the connection thoroughly using sample calls
# Slack (/docs/integrations/slack)
> Send automated messages and notifications from your voice AI agent into your Slack workspace.
Slack integration lets your agent send real-time messages and
notifications directly to your Slack workspace. Use it to alert your
team, log events, or notify users within specific channels.
## Key benefits [#key-benefits]
* Send real-time alerts and updates to Slack
* Keep your team informed about user activity
* Trigger notifications based on agent interactions
## Setup option 1: from the main dashboard [#setup-option-1-from-the-main-dashboard]
### Open the integrations page [#open-the-integrations-page]
Go to the Integrations page in your dashboard and select the **All
Integrations** tab.
### Connect Slack [#connect-slack]
Find the Slack card and click **Connect**. Configure the integration name
and description, then complete the OAuth authorization.
### Attach to your agent [#attach-to-your-agent]
Go to your agent's edit page, open the **Integrations** tab, and attach
the integration from the dropdown.
## Setup option 2: from agent configuration [#setup-option-2-from-agent-configuration]
### Open the agent's integrations tab [#open-the-agents-integrations-tab]
Navigate to your agent's edit page and find the **Integrations** tab.
### Connect with Slack [#connect-with-slack]
Find **Slack** under the **Connect New Integrations** section and click
**Connect with Slack**. A modal will appear where you can enter the
integration name and description. Click **Connect with Slack** to
authorize via OAuth and finalize the integration.
## Using with your agent [#using-with-your-agent]
* Trigger Slack messages when a specific user action occurs
* Send call summaries or event-based alerts
* Notify team members in specific Slack channels
## Best practices [#best-practices]
* Name the integration clearly to identify its purpose
* Use dedicated Slack channels for different agents or event types
* Keep descriptions concise but meaningful for your team
* Test the Slack integration by simulating a user event
# Make, Zapier, n8n, GHL (/docs/integrations/zapier-make-n8n)
> Integrate Make, Zapier, n8n, and GHL with your OmniDimension agent for powerful automation.
There are two ways you can integrate OmniDimension with automation
platforms like Make, Zapier, n8n, and GHL.
* **Webhook method**: send data from OmniDimension to Make, Zapier, n8n, or GHL once the call is completed.
* **API method**: trigger OmniDimension actions from Make, Zapier, n8n, or GHL.
## Webhook method: send post-call data to Make, Zapier, n8n, GHL [#webhook-method-send-post-call-data-to-make-zapier-n8n-ghl]
### Open the agent's post-call tab [#open-the-agents-post-call-tab]
Navigate to your agent's page in the OmniDimension dashboard and go to
the **Post-Call** tab.
### Set the delivery method to webhook [#set-the-delivery-method-to-webhook]
Set the delivery method to **Webhook** and paste the webhook URL from
Make (HTTP module), Zapier (Webhook trigger), or n8n (Webhook node).
### Test the connection [#test-the-connection]
Click **Test Connection** to verify and inspect the payload from your
automation platform.
### Sample webhook payload [#sample-webhook-payload]
```json
{
"call_id": 24877,
"bot_id": 551,
"bot_name": "Your Bot Name",
"phone_number": "+1234567890",
"call_date": "2025-05-22 05:02:54",
"user_email": "user@example.com",
"call_report": {
"summary": "Brief overview of the conversation...",
"sentiment": "Positive",
"extracted_variables": {
"name": "Ravi",
"appointment_type": "Dental Checkup"
},
"full_conversation": "Full transcript here...",
"interactions": [
{
"sequence": 1,
"user_query": false,
"bot_response": "Hello, how can I help you?",
"time": "2025-05-22 05:02:42"
},
{
"sequence": 2,
"user_query": "I want a dental appointment",
"bot_response": "Sure, I can help with that.",
"time": "2025-05-22 05:02:45"
}
]
}
}
```
### Example: add call logs to an Airtable database using Make.com [#example-add-call-logs-to-an-airtable-database-using-makecom]
* Create a webhook in Make.com
* Set the webhook URL in your post-call agent configuration following the guide above
* Test the webhook by sending a sample payload
* For other platforms: Webhook node for n8n, Webhook trigger for Zapier, Workflow Actions Webhook for GHL
## API method: call OmniDimension actions from Make, Zapier, n8n, GHL [#api-method-call-omnidimension-actions-from-make-zapier-n8n-ghl]
* Use OmniDimension's REST APIs to trigger actions like creating an agent, dispatching calls, or updating the knowledge base
* Use HTTP modules and nodes in your automation tool to make requests to OmniDimension API endpoints
* Ensure your API key is set correctly in request headers
### Common OmniDimension API endpoints [#common-omnidimension-api-endpoints]
* `POST /api/v1/agents` — create a new agent
* `POST /api/v1/calls/dispatch` — trigger an outbound call
* `POST /api/v1/knowledge_base/create` — add knowledge entries
* `GET /api/v1/calls/logs/:id` — retrieve a conversation log
### Example: call dispatch using Make.com [#example-call-dispatch-using-makecom]
### Add an HTTP module [#add-an-http-module]
Create a new HTTP module in Make.com and set the HTTP method to **POST**.
### Configure the request [#configure-the-request]
Paste the OmniDimension API endpoint for call dispatch. Add the API key
in the `Authorization` header. Set the request body to include
`agent_id`, `phone_number`, and `call_context`.
### Save and test [#save-and-test]
Save the module. For other platforms: HTTP Request node for n8n,
Workflow Actions Webhook for GHL, Webhook trigger for Zapier.
## Tips and best practices [#tips-and-best-practices]
* Always test webhooks with tools like webhook.site or RequestBin
* Use conditional logic in workflows based on extracted variables
* Handle failures and retries in automation tools for reliability
# Client SDKs (/docs/sdks)
> Official OmniDimension SDKs for calling the API from your stack.
Use a Client SDK to call the OmniDimension API from your application
without hand-rolling HTTP requests. Each SDK wraps the same REST API
documented in the [API reference](/docs/api-reference) with idiomatic
classes, methods, and error types.
## Available SDKs [#available-sdks]
More languages are on the way. If you'd like to see one prioritized,
[let us know](https://omnidim.io/contact-us).
# Python SDK (/docs/sdks/python)
> The omnidimension Python package. Install with pip and start calling the API.
The `Client` class is the main entry point for the OmniDimension Python
SDK. It handles authentication, request management, and provides access
to every API domain.
## Installation [#installation]
Install the SDK from PyPI:
```bash
pip install omnidimension
```
Package details and version history live at
[pypi.org/project/omnidimension](https://pypi.org/project/omnidimension/).
## Initialization [#initialization]
Initialize the Client with your API key:
```python
import os
from omnidimension import Client
api_key = os.environ.get('OMNIDIM_API_KEY', 'your_api_key_here')
client = Client(api_key)
```
## Client structure [#client-structure]
```python
client.agent # Agent operations
client.call # Call operations
client.knowledge_base # Knowledge base operations
client.phone_number # Phone number operations
```
## Error handling [#error-handling]
The SDK provides an `APIError` class for API-specific errors:
```python
import os
from omnidimension import Client, APIError
api_key = os.environ.get('OMNIDIM_API_KEY', 'your_api_key_here')
client = Client(api_key)
try:
response = client.agent.list()
print(response)
except APIError as e:
print(f"API Error ({e.status_code}): {e.message}")
except Exception as e:
print(f"Unexpected error: {str(e)}")
```
## Client parameters [#client-parameters]
# Import Exotel Phone Numbers (/docs/telephony/exotel-import)
> Seamlessly integrate your Exotel phone numbers with OmniDimension and set up intelligent call flows for your AI agents.
This guide walks through importing Exotel phone numbers into OmniDimension so
your AI agents can handle incoming calls. You'll set up the necessary call
flows in Exotel and import them into OmniDimension for seamless integration.
## What you'll need [#what-youll-need]
Before you can import an Exotel phone number, you need to complete these
steps in your Exotel account:
* Create an account on [exotel.com](https://exotel.com)
* Complete KYC (Know Your Customer) verification by submitting required documents
* Purchase an Exophone number from your Exotel dashboard
* Create a call flow for your Exophone number (covered in step 4)
* Attach the call flow to your phone number
## Required credentials from Exotel [#required-credentials-from-exotel]
After completing the prerequisites, you'll need to collect these credentials
from your Exotel dashboard. You can find these in the **API Credentials**
section:
* **Exotel API Key**: Your authentication key for API access
* **Exotel API Token**: Your secure access token
* **Exotel Subdomain**: Your account's subdomain (e.g., `yourcompany.exotel.com`)
* **Exotel Account SID**: Your unique account identifier
* **Exotel Phone Number**: The phone number you want to import
* **Exotel App ID**: The call flow ID (you'll get this after creating your call flow)
## Setting up the call flow in Exotel [#setting-up-the-call-flow-in-exotel]
This is the most important part of the process. You'll create a call flow in
Exotel that connects to OmniDimension. Follow these steps carefully.
### Access App Builder [#access-app-builder]
In your Exotel dashboard, go to the side menu and click on **App Builder**.
### Create new app [#create-new-app]
Click on **Create New App** to start building your call flow.
### Add Voicebot applet for "Call Comes" [#add-voicebot-applet-for-call-comes]
On the **Call Comes** block, drag a **Voicebot** applet from the right
sidebar. In the URL field, enter `wss://live.omnidim.io/media_exotel_community`
and turn recording **ON**.
### Add second Passthru applet [#add-second-passthru-applet]
On the voicebot applet's next section, drag another **Passthru** applet. In
the URL field, enter `https://live.omnidim.io/should_end_the_call`.
### Add Hangup on 200 response [#add-hangup-on-200-response]
In the 200 response of the second passthru applet, drag a **Hangup** applet
to end the call when needed.
### Add Connect on 302 response [#add-connect-on-302-response]
In the 302 response of the second passthru applet, drag a **Connect** applet
for call transfers.
### Configure Connect applet [#configure-connect-applet]
In the connect applet, select **Primary URL** and enter
`https://live.omnidim.io/call_transfer`.
### Add Passthru for call end [#add-passthru-for-call-end]
For the **After the call conversation ends** option, add a passthru applet
with URL `https://live.omnidim.io/should_end_the_call?omni_status=call_end`.
### Add Passthru for no answer [#add-passthru-for-no-answer]
For the **If nobody answers** option, add a passthru applet with URL
`https://live.omnidim.io/should_end_the_call?omni_status=nobody_ans`.
### Add Passthru for no dial [#add-passthru-for-no-dial]
For the **We didn't dial anyone** option, add a passthru applet with URL
`https://live.omnidim.io/should_end_the_call?omni_status=didnt_dial_anyone`.
### Add Hangup applets [#add-hangup-applets]
On all the passthru applets you just created, add a **Hangup** applet in
both 200 and 302 responses to ensure calls end properly.
### Save your call flow [#save-your-call-flow]
Click **Save** to save your call flow configuration and close the flow
builder. Make sure to note down the App ID (call flow ID) as you'll need it
for the import process.
### Attach call flow with your Exophone number [#attach-call-flow-with-your-exophone-number]
Go to **Exophone**, buy a number, and attach the call flow you just created.
Make sure to note down the phone number as you'll need it for the import
process.
## Important notes about call flow setup [#important-notes-about-call-flow-setup]
* The Voicebot applet will only be visible after you complete KYC verification
* If you don't see the Voicebot applet after KYC, contact Exotel support
* Make sure all URLs are entered exactly as shown (no extra spaces or characters)
* Test your call flow in Exotel before importing to OmniDimension
* Save your App ID (call flow ID); you'll need it for the import process
## Import to OmniDimension [#import-to-omnidimension]
Now that your call flow is set up in Exotel, import your phone number into
OmniDimension.
### Navigate to Phone Numbers [#navigate-to-phone-numbers]
In your OmniDimension dashboard, go to the **Phone Numbers** section from the
main navigation menu.
### Click "Import Exotel Phone Number" [#click-import-exotel-phone-number]
Look for the **Import Exotel Phone Number** button and click on it to open
the import form.
### Fill in the import form [#fill-in-the-import-form]
Enter all the credentials you collected from your Exotel dashboard in the
form fields:
* Exotel API Key
* Exotel API Token
* Exotel Subdomain
* Exotel Account SID
* Exotel Phone Number
* Exotel App ID (your call flow ID)
### Complete the import [#complete-the-import]
Click the **Import** button to complete the process. Your Exotel phone
number will now appear in your OmniDimension dashboard and be ready for use
with your AI agents.
## Understanding the call flow [#understanding-the-call-flow]
Here's how your call flow works after setup. When someone calls your Exotel
number:
* The call first goes to OmniDimension's `call_coming` endpoint
* OmniDimension then connects to your AI agent through the voicebot
* Your AI agent handles the conversation
* When the call should end, it goes to the `should_end_the_call` endpoint
* If a transfer is needed, it goes to the `call_transfer` endpoint
* All calls eventually end with a hangup action
## What happens after import [#what-happens-after-import]
Once your phone number is successfully imported, you can:
* Use the phone number with any of your AI agents
* Receive incoming calls that are automatically handled by your agents
* Monitor call logs and performance in your dashboard
## Next steps [#next-steps]
* Configure your AI agents to handle calls effectively
* Attach the Exotel phone number to your agent
* Test your setup by making a test call to your number
## Troubleshooting common issues [#troubleshooting-common-issues]
* **Voicebot applet not visible**: Make sure you've completed KYC verification. If still not visible, contact Exotel support.
* **Import fails**: Double-check all credentials are correct and your call flow is properly configured.
* **Calls not connecting**: Verify your call flow URLs are correct and your OmniDimension account is active.
* **Call hangup on connect**: Make sure all URLs are entered exactly as shown with no extra spaces.
* **KYC issues**: Contact Exotel support if you're having trouble with the verification process.
## Getting help [#getting-help]
* [Exotel Documentation](https://developer.exotel.com/applet#voicebot)
* [OmniDimension Discord](https://discord.gg/kdjzykMTHJ)
* [OmniDimension Support](mailto:support@omnidim.io)
# Telephony (/docs/telephony)
> Bring your own phone numbers to OmniDimension. Any SIP-enabled carrier works, with fast-path guides for the most common ones.
OmniDimension speaks **SIP** — the standard protocol every modern carrier
supports. If your provider can hand out SIP trunk credentials, you can
plug it in. The pages below are quick-start guides for the carriers we
see most often, but they are not the limit of what we support.
SIP trunking is provider-agnostic. Start from the [SIP Trunking
guide](/docs/telephony/sip) — paste your credentials, and you're live.
Any SIP carrier works the same way.
## Set up SIP [#set-up-sip]
## Carrier-specific quick starts [#carrier-specific-quick-starts]
Use these if your carrier is on the list — they skip the lookup steps and
go straight to the fields you need.
## Other paths [#other-paths]
# RingCentral SIP Configuration (/docs/telephony/sip-ringcentral)
> Complete guide to configure your RingCentral SIP trunking, including SIP credentials and optional outbound proxy.
RingCentral's SIP trunking allows you to connect your existing phone numbers
to OmniDimension AI agents. This guide covers the complete setup process
including SIP credentials and optional outbound proxy configuration.
## Prerequisites [#prerequisites]
### What you'll need [#what-youll-need]
* Phone number with SIP capability
* SIP trunking enabled on your account
### Configuration features [#configuration-features]
* Optional outbound proxy support
* IP whitelisting available
## Step-by-step configuration [#step-by-step-configuration]
### Enable SIP trunking [#enable-sip-trunking]
First, you need to enable SIP trunking in your RingCentral account.
1. Go to the [RingCentral Admin Portal](https://service.ringcentral.com)
2. Sign in with your admin credentials
3. Navigate to **Phone System → SIP Trunking**
4. Enable SIP trunking for your account if not already enabled
### Get your SIP configuration [#get-your-sip-configuration]
Configure your SIP trunk in RingCentral and copy the configuration details.
1. Go to **Phone System → Phones & Devices**
2. Click **Set up manually using SIP**
3. Configure your SIP credentials and settings
4. If using outbound proxy, choose the one closest to your region (e.g., `sip60.ringcentral.com:5090` for US)
5. Copy your complete SIP configuration details (host, username, password, etc.)
### Import to OmniDimension [#import-to-omnidimension]
Now import your RingCentral number to OmniDimension.
1. Go to **Phone Numbers** on the OmniDimension dashboard
2. Click **Import from SIP Trunk**
3. Select **RingCentral** as your provider
4. Enter your SIP credentials (host, username, password, outbound proxy if needed)
5. Test the connection and import
For comprehensive setup instructions, refer to RingCentral's official
[SIP Settings Guide](https://support.ringcentral.com/article-v2/Manual-Provisioning-How-get-SIP-Settings.html?brand=RC_US\&product=RingEX\&language=en_US).
# Twilio SIP Configuration (/docs/telephony/sip-twilio)
> Complete guide to configure your Twilio Elastic SIP Trunking with credential lists or IP ACL authentication.
Twilio's Elastic SIP Trunking allows you to connect your existing phone
numbers to OmniDimension AI agents. This guide covers both credential-based
and IP whitelisting authentication methods.
## Prerequisites [#prerequisites]
### What you'll need [#what-youll-need]
* Active Twilio account
* Elastic SIP Trunking enabled
* Phone numbers associated with your trunk
### Authentication options [#authentication-options]
* Custom SIP credentials (recommended)
* IP Access Control Lists (ACL)
* Both methods supported
## Step-by-step configuration [#step-by-step-configuration]
### Create your Elastic SIP Trunk [#create-your-elastic-sip-trunk]
First, you need to create an Elastic SIP Trunk in your Twilio Console.
1. Go to the [Twilio Console](https://www.twilio.com/en-us/sip-trunking) and navigate to **Elastic SIP Trunking → Manage → Trunks**
2. Click **Create New Trunk**
3. Enter a friendly name for your trunk (e.g., "OmniDimension Trunk")
4. Configure your trunk settings and save
### Configure termination settings [#configure-termination-settings]
Configure how your trunk authenticates with OmniDimension. You have two
options:
#### Option 1: Credential Lists (recommended) [#option-1-credential-lists-recommended]
Works without IP whitelisting.
1. Go to **Credential Lists** in your trunk
2. Create a new credential list
3. Add username / password pairs
4. Assign to your trunk
#### Option 2: IP ACL [#option-2-ip-acl]
Requires IP whitelisting.
1. Enable **Access Control List**
2. Create IP ACL
3. Add OmniDimension IPs (contact us for the specific IP addresses)
4. Assign to your trunk
### Associate phone numbers [#associate-phone-numbers]
Link your Twilio phone numbers to the SIP trunk.
1. Go to **Phone Numbers → Manage → Active numbers**
2. Select the number you want to use
3. In the Voice section, set **Configure with** to **SIP Trunk**
4. Select your newly created trunk
5. Save the configuration
### Import to OmniDimension [#import-to-omnidimension]
Now import your Twilio number to OmniDimension.
1. Go to **Phone Numbers** on the OmniDimension dashboard
2. Click **Import from SIP Trunk**
3. Select **Twilio** as your provider
4. Enter your SIP credentials
5. Test the connection and import
For comprehensive setup instructions, refer to Twilio's official
[Elastic SIP Trunking Setup Guide](https://www.twilio.com/en-us/blog/elastic-sip-trunking-step-by-step-setup).
# Vonage SIP Setup (/docs/telephony/sip-vonage)
> Complete guide to configure your Vonage SIP trunking with UserKey and Secret authentication.
Vonage's SIP trunking allows you to connect your existing phone numbers to
OmniDimension AI agents. This guide covers the complete setup process
including UserKey and Secret authentication.
## Prerequisites [#prerequisites]
### What you'll need [#what-youll-need]
* SIP trunking enabled on your account
* Phone number with SIP capability
### Authentication method [#authentication-method]
* UserKey and Secret authentication
* IP whitelisting available
## Step-by-step configuration [#step-by-step-configuration]
### Get your SIP credentials [#get-your-sip-credentials]
Access your Vonage SIP configuration to get the credentials you'll need.
1. Go to the [Vonage Admin Portal](https://admin.vonage.com) and navigate to **Phone System → SIP Trunking**
2. Find your **UserKey** (username) and **Secret** (password)
3. Note your SIP host (choose the appropriate regional host for your location)
### Import to OmniDimension [#import-to-omnidimension]
Now import your Vonage number to OmniDimension.
1. Go to **Phone Numbers** on the OmniDimension dashboard
2. Click **Import from SIP Trunk**
3. Select **Vonage** as your provider
4. Enter your SIP credentials
5. Test the connection and import
For comprehensive setup instructions, refer to Vonage's official
[SIP Trunking Guide](https://www.vonage.com/communications-apis/sip-trunking/).
# SIP Trunking (/docs/telephony/sip)
> Connect your existing phone numbers to OmniDimension using SIP trunking.
SIP (Session Initiation Protocol) trunking allows you to use your existing
phone numbers with your OmniDimension AI agents. This guide will help you
configure your telephony provider to work with our platform.
### What you'll need [#what-youll-need]
* A SIP-enabled phone number from a supported provider
* SIP trunking credentials from your provider
* Access to your provider's configuration panel
## Supported providers [#supported-providers]
We can support any SIP provider by
default — most carriers work the moment you paste credentials, and the
rest take a quick manual configuration.
This list grows often as we add more carriers to the
fully supported column. 📡
### Fully supported [#fully-supported]
These providers work by default with username / password authentication.
* Twilio
* Vonage
* RingCentral
### Manual setup required [#manual-setup-required]
Contact support for manual configuration.
* Other SIP providers
* Custom configurations
Send us your provider's SIP credential page (a screenshot is fine) and
the team will add it manually, usually within **1–2 business days**.
* Email: [support@omnidim.io](mailto:support@omnidim.io)
* Discord: [join the OmniDimension community](https://discord.gg/kdjzykMTHJ)
Once it's live in the dropdown, future numbers from the same carrier
import in one click for everyone.
## Getting started [#getting-started]
It's easier than you think. Just a few clicks and you're done.
### Start from your Phone Numbers page [#start-from-your-phone-numbers-page]
Look for the **Import from SIP Trunk** button.
### Tell us about your provider [#tell-us-about-your-provider]
Select your SIP provider from the dropdown and enter your credentials.
### Configuration complete [#configuration-complete]
For supported providers, configuration is completed automatically. Your SIP
trunk will be operational instantly.
## Provider configuration [#provider-configuration]
Detailed configuration guides for each supported SIP provider.
### Other providers [#other-providers]
For providers not listed above or custom configurations:
* Try username / password authentication first
* If that fails, contact support for IP whitelisting instructions
* Our team can manually configure unsupported providers
## Common issues and solutions [#common-issues-and-solutions]
### Import failed [#import-failed]
Don't worry, this happens sometimes. Here's what to check:
* Double-check your SIP credentials and ensure your provider allows outbound calls
* Check your account balance / credits and verify your plan includes SIP trunking features
### Calls not working [#calls-not-working]
If your number imported but calls aren't connecting or dispatching:
* Verify your SIP trunk settings and ensure your plan supports outbound calls to your target regions
* Review call logs in your provider's dashboard and contact them if SIP trunking isn't enabled
### Need manual setup? [#need-manual-setup]
For providers not in our supported list:
* Try importing with **Other / Unknown** first, then contact our support team if that doesn't work
* We'll manually configure your provider and get back to you once it's ready
## FAQs [#faqs]
SIP calls use your provider's rates. You'll only pay for OmniDimension usage.
Yes, you can import numbers from different SIP providers. Each number will
use its respective provider's configuration.
For supported providers (Twilio, RingCentral, Vonage), no additional
configuration is needed. For others, our team will handle the setup.
Currently, you'll need to delete and re-import the number to change SIP
settings. We're working on in-place editing.
For providers requiring manual configuration, setup typically takes 1–2
business days. You'll receive an email confirmation when it's ready.
Try selecting **Other / Unknown** from the provider dropdown first. If that
doesn't work, contact us with your provider details and we'll configure it
for you.
Yes. See the
[Import SIP Trunk API reference](/docs/api-reference/phone-numbers) for the
full endpoint reference and code examples.
# Tutorials (/docs/tutorials)
> Video walkthroughs for building, configuring, and integrating OmniDimension voice agents.
Step-by-step video guides to help you build, configure, and scale your AI
voice agents with OmniDimension. Each walkthrough covers a single
workflow end to end.
## Getting started [#getting-started]
## Configuration [#configuration]
## Integrations [#integrations]
## Analytics [#analytics]
## Bulk operations [#bulk-operations]
# WhatsApp Integration (/docs/whatsapp)
> Connect your WhatsApp Business account to send and receive messages, automate responses with bots, and manage campaigns.
Connect your WhatsApp Business account to send and receive messages,
automate responses with bots, and manage campaigns.
## Connecting Phone WhatsApp [#connecting-phone-whatsapp]
Follow these steps to connect your existing WhatsApp number using QR code
authentication.
### Initiate connection [#initiate-connection]
Go to the **WhatsApp** tab in the sidebar. You will see two options: Phone
WhatsApp and Cloud WhatsApp. Click on the **Phone WhatsApp** card to start
the connection process.
### Scan QR code [#scan-qr-code]
A QR code will be displayed on the screen. To scan it:
1. Open **WhatsApp** on your mobile phone
2. Go to **Settings** (or Menu on Android)
3. Select **Linked Devices**
4. Tap on **Link a Device** and point your camera at the screen
The QR code is valid for only **15 seconds**. If it expires, you will need
to regenerate it.
### Attach a bot [#attach-a-bot]
Once the WhatsApp connection is successful, your number will appear in the
list. You can now attach a bot to this number.
* Locate your connected number card
* Click on the **Select Agent** dropdown or **Attach Assistant** button
* Choose an available bot from your account
### Automated responses [#automated-responses]
With the bot attached, any incoming message to this number will be
automatically processed. The bot will respond based on its configuration and
the user's query.
## Connecting WhatsApp Cloud [#connecting-whatsapp-cloud]
Follow these steps to connect your WhatsApp Cloud API account using your
Meta developer credentials.
### Initiate Cloud connection [#initiate-cloud-connection]
Go to the **WhatsApp** tab and select **WhatsApp Cloud**. Click on the
**Connect Cloud API** card to open the configuration modal.
### Provide credentials [#provide-credentials]
A form will appear asking for your WhatsApp Business API credentials. You
need to provide:
* **WhatsApp Business Account ID**
* **User Access Token** (System User Token recommended)
* **App ID**
* **Business Manager ID**
You can find these details in your
[Meta App Dashboard](https://developers.facebook.com/apps/) under
**WhatsApp → API Setup**.
### Fetch numbers [#fetch-numbers]
Once you submit valid credentials, the system will automatically authenticate
with Meta and fetch all **verified phone numbers** associated with your
WhatsApp Business Account.
This process may take a few seconds. Using an invalid token or account ID
will result in an error.
### Attach a bot [#attach-a-bot-1]
After the numbers are fetched and displayed in your list:
1. Find the number you wish to use
2. Click **Attach Assistant**
3. Select the AI agent you want to handle conversations for this number
# Bulk call actions (/docs/api-reference/bulk-calls/bulkCallActions)
> Pause, resume, or reschedule a running campaign.
**PUT** `/calls/bulk_call/{bulk_call_id}`
Pause, resume, or reschedule a running campaign.
```yaml
operationId: bulkCallActions
parameters:
- name: bulk_call_id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- action
properties:
action:
type: string
enum:
- pause
- resume
- reschedule
description: What to do with the campaign.
new_scheduled_datetime:
type: string
description: New start time for `reschedule`. Format `YYYY-MM-DD HH:MM:SS`.
example: '2026-12-25 10:00:00'
new_timezone:
type: string
description: IANA timezone for `reschedule`.
example: America/New_York
responses:
'200':
description: |
Action applied. `current_status` reflects the new campaign
state. `scheduled_datetime` and `timezone` echo back only on
`reschedule`.
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
current_status:
type: string
scheduled_datetime:
type: string
timezone:
type: string
example:
status: success
message: Bulk call paused successfully
current_status: paused
```
**Python SDK**
```python
# Pause a bulk call
response = client.bulk_call.bulk_call_actions(
bulk_call_id=123,
action="pause"
)
print(response)
# Resume a bulk call
response = client.bulk_call.bulk_call_actions(
bulk_call_id=123,
action="resume"
)
print(response)
# Reschedule a bulk call
response = client.bulk_call.bulk_call_actions(
bulk_call_id=123,
action="reschedule",
new_scheduled_datetime="2024-12-26 14:00:00",
new_timezone="America/Los_Angeles"
)
print(response)
```
**curl**
```bash
curl -X PUT "https://backend.omnidim.io/api/v1/calls/bulk_call/{bulk_call_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Cancel bulk call (/docs/api-reference/bulk-calls/cancelBulkCall)
> Cancel a bulk-call campaign.
**DELETE** `/calls/bulk_call/{bulk_call_id}`
Cancel a bulk-call campaign.
```yaml
operationId: cancelBulkCall
parameters:
- name: bulk_call_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Campaign cancelled.
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
current_status:
type: string
example:
status: success
message: Bulk call cancelled successfully
current_status: cancelled
```
**Python SDK**
```python
# Cancel a bulk call
response = client.bulk_call.cancel_bulk_call(bulk_call_id=123)
print(response)
```
**curl**
```bash
curl -X DELETE "https://backend.omnidim.io/api/v1/calls/bulk_call/{bulk_call_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Create bulk call (/docs/api-reference/bulk-calls/createBulkCall)
> Create a new bulk-call campaign. Supports immediate, scheduled, and auto-retry modes.
**POST** `/calls/bulk_call/create`
Create a new bulk-call campaign. Supports immediate, scheduled, and auto-retry modes.
```yaml
operationId: createBulkCall
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
- contact_list
- phone_number_id
properties:
name:
type: string
description: Name of the bulk call campaign.
example: Customer Follow-up Campaign
phone_number_id:
type: string
description: Your phone number id to use for making calls.
contact_list:
type: array
minItems: 1
description: |
Array of contact objects. Each row needs `phone_number`.
Any other key you add on the row (e.g. `customer_name`,
`account_id`, `priority`) is passed to the agent as a
context variable for that specific call, so the agent
can reference it during the conversation.
items:
type: object
required:
- phone_number
properties:
phone_number:
type: string
description: Phone number in international format (e.g., +15551234567).
example: '+15551234567'
additionalProperties: true
example:
- phone_number: '+15551234567'
customer_name: John Doe
account_id: ACC-12345
- phone_number: '+15559876543'
customer_name: Jane Smith
account_id: ACC-67890
priority: high
is_scheduled:
type: boolean
default: false
description: Whether the campaign should be scheduled for future execution.
scheduled_datetime:
type: string
description: >-
Scheduled execution time in format `YYYY-MM-DD HH:MM:SS` (required if `is_scheduled`
is true).
example: '2026-12-25 10:00:00'
timezone:
type: string
default: UTC
description: Timezone for scheduled execution.
example: America/New_York
concurrent_call_limit:
type: integer
default: 1
minimum: 1
description: Maximum number of concurrent calls allowed.
enabled_reschedule_call:
type: boolean
default: false
description: >-
Enable automatic call rescheduling. When enabled the system can reschedule unreachable
calls.
retry_config:
type: object
description: Auto-retry configuration object containing retry settings.
properties:
auto_retry:
type: boolean
default: false
auto_retry_schedule:
type: string
enum:
- immediately
- next_day
- scheduled_time
description: When to retry failed calls.
retry_schedule_days:
type: integer
default: 0
minimum: 0
description: Days to wait before a scheduled retry.
retry_schedule_hours:
type: integer
default: 0
minimum: 0
description: Hours to wait before a scheduled retry.
retry_limit:
type: integer
default: 0
minimum: 0
maximum: 5
description: Maximum number of retry attempts (0–5).
responses:
'200':
description: |
Bulk call campaign created. `current_status` is `scheduled`
for `is_scheduled: true`, otherwise `pending` (the
campaign starts dispatching to your concurrency limit
immediately after creation).
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
id:
type: integer
description: New campaign ID.
is_scheduled:
type: boolean
current_status:
type: string
example:
status: success
message: Bulk call created successfully
id: 314
is_scheduled: false
current_status: pending
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
response = client.bulk_call.create_bulk_call({
"name": "Customer Follow-up Campaign",
"contact_list": [
{
"phone_number": "+15551234567",
"customer_name": "John Doe", # optional context key
"account_id": "ACC-12345", # optional context key
},
{
"phone_number": "+15559876543",
"customer_name": "Jane Smith", # optional context key
"account_id": "ACC-67890", # optional context key
},
],
"phone_number_id": "1", # required
"is_scheduled": False, # optional
"retry_config": { # optional
"auto_retry": True,
"auto_retry_schedule": "next_day",
"retry_limit": 2,
},
"enabled_reschedule_call": True, # optional
})
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/calls/bulk_call/create" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Fetch bulk calls (/docs/api-reference/bulk-calls/fetchBulkCalls)
> List bulk-call campaigns with pagination and optional status filter.
**GET** `/calls/bulk_call`
List bulk-call campaigns with pagination and optional status filter.
```yaml
operationId: fetchBulkCalls
parameters:
- name: pageno
in: query
schema:
type: integer
default: 1
- name: pagesize
in: query
schema:
type: integer
default: 10
maximum: 150
description: Items per page (max 150 — sending more returns 500).
- name: status
in: query
schema:
type: string
description: Filter by status (e.g. completed).
responses:
'200':
description: Paginated list of bulk calls.
content:
application/json:
schema:
type: object
properties:
status:
type: string
enum:
- success
- error
records:
type: array
items:
type: object
description: A bulk-call campaign.
properties:
id:
type: integer
example: 11880
name:
type: string
campaign_type:
type: string
example: ai_agent
user_id:
type: integer
user_name:
type: string
bot_id:
type: integer
bot_name:
type: string
twilio_number:
type: string
status:
type: string
example: completed
is_scheduled:
type: boolean
scheduled_datetime:
oneOf:
- type: string
- type: 'null'
recording_file_name:
oneOf:
- type: string
- type: 'null'
failed_reason:
oneOf:
- type: string
- type: boolean
concurrent_call_limit:
type: integer
email_report_recipients:
oneOf:
- type: string
- type: boolean
total_calls:
type: integer
completed_calls:
type: integer
total_calls_made:
type: integer
total_calls_to_dispatch:
type: integer
total_pending_calls:
type: integer
total_not_reachable_calls:
type: integer
total_call_transfer_count:
type: integer
create_date:
type: string
example:
status: success
records:
- id: 314
name: test
campaign_type: ai_agent
user_id: 1234
user_name: Demo User
twilio_number: '+15551234567'
bot_id: 6337
bot_name: Customer Support Agent
recording_file_name: null
status: completed
failed_reason: false
is_scheduled: false
scheduled_datetime: null
create_date: 04/22/2026 22:10:22
concurrent_call_limit: 1
email_report_recipients: ''
total_calls: 1
completed_calls: 1
total_calls_made: 1
total_calls_to_dispatch: 1
total_pending_calls: 0
total_not_reachable_calls: 1
total_call_transfer_count: 0
total_records: 31
```
**Python SDK**
```python
# Fetch all bulk calls with pagination
response = client.bulk_call.fetch_bulk_calls(page=1, page_size=10)
print(response)
# Filter bulk calls by status
response = client.bulk_call.fetch_bulk_calls(page=1, page_size=10, status="completed")
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/calls/bulk_call" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Bulk call details (/docs/api-reference/bulk-calls/getBulkCall)
> Get detailed information about a bulk-call campaign.
**GET** `/calls/bulk_call/{bulk_call_id}`
Get detailed information about a bulk-call campaign.
```yaml
operationId: getBulkCall
parameters:
- name: bulk_call_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Bulk call details.
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
details:
type: object
description: >-
A bulk-call campaign with configuration, execution stats, and the active number
pool.
properties:
id:
type: integer
description: Campaign ID.
name:
type: string
description: Campaign name.
campaign_type:
type: string
description: Campaign type. Typically `ai_agent` for agent-driven campaigns.
user_id:
type: integer
description: ID of the user who owns the campaign.
user_name:
type: string
description: Display name of the owning user.
bot_id:
type: integer
description: ID of the agent that handles calls for this campaign.
bot_name:
type: string
description: Name of the agent.
twilio_number:
type: string
description: Outbound number used for the campaign (E.164 format).
status:
type: string
description: >-
Current campaign status (e.g. `draft`, `scheduled`, `in_progress`, `paused`,
`completed`, `cancelled`).
is_scheduled:
type: boolean
description: True when the campaign is scheduled to start at a future time.
is_dynamic:
type: boolean
description: True for dynamic campaigns that source contacts via webhook.
scheduled_datetime:
oneOf:
- type: string
- type: 'null'
description: >-
Scheduled start time, formatted in the campaign timezone. Null when not
scheduled.
timezone:
type: string
description: IANA timezone the campaign was scheduled in.
recording_file_id:
oneOf:
- type: integer
- type: 'null'
description: ID of the uploaded contact list file, if any.
recording_file_name:
oneOf:
- type: string
- type: 'null'
description: Filename of the uploaded contact list, if any.
failed_reason:
oneOf:
- type: string
- type: boolean
description: Reason the campaign failed to start, or `false` when there is none.
auto_retry:
type: boolean
description: Whether failed calls are automatically retried.
auto_retry_schedule:
type: string
description: When retries fire (e.g. `immediately`, `after_delay`).
retry_schedule_days:
type: integer
description: Days to wait before retrying when `auto_retry_schedule` uses a delay.
retry_schedule_hours:
type: integer
description: Hours to wait before retrying when `auto_retry_schedule` uses a delay.
retry_count:
type: integer
description: Total retries already performed.
retry_limit:
type: integer
description: Maximum retries allowed per contact.
enabled_reschedule_call:
type: boolean
description: Whether contacts can request a reschedule mid-call.
concurrent_call_limit:
type: integer
description: Maximum number of calls running in parallel.
enable_daily_hard_stop:
type: boolean
description: Whether the campaign pauses each day at `daily_stop_time`.
daily_stop_time:
type: number
description: Daily hard-stop time as a float-of-day (e.g. 18.5 = 18:30).
daily_stop_time_formatted:
type: string
description: Daily hard-stop time formatted as `HH:MM`.
daily_stop_timezone:
type: string
description: IANA timezone for the daily hard-stop.
enable_daily_auto_start:
type: boolean
description: Whether the campaign auto-resumes each day at `daily_start_time`.
daily_start_time:
type: number
description: Daily auto-start time as a float-of-day.
daily_start_time_formatted:
type: string
description: Daily auto-start time formatted as `HH:MM`.
daily_start_timezone:
type: string
description: IANA timezone for the daily auto-start.
email_on_complete:
type: boolean
description: Whether to email a report when the campaign completes.
email_on_hard_stop:
type: boolean
description: Whether to email a report when a daily hard-stop fires.
email_report_recipients:
oneOf:
- type: string
- type: boolean
description: Comma-separated recipient list, or `false` when empty.
variable_config:
type: array
description: Custom variables exposed to the agent for each contact.
items:
type: object
properties:
id:
type: integer
description: Variable ID.
variable_name:
type: string
description: Variable name as referenced in the agent prompt.
variable_type:
type: string
description: Variable data type (e.g. `text`, `number`, `enum`).
enum_values:
description: Allowed values when `variable_type` is `enum`; `false` otherwise.
oneOf:
- type: array
items:
type: string
- type: boolean
rotation_strategy:
type: string
description: >-
How outbound numbers rotate across the pool (e.g. `none`, `round_robin`,
`health_aware`).
calls_per_number:
type: integer
description: Calls placed on a single number before rotating.
rotation_health_threshold:
type: number
description: Health-score threshold below which a number is skipped during rotation.
rotation_fallback:
type: string
description: >-
Fallback behavior when no healthy number is available (e.g. `pause`,
`continue`).
current_number_assignment_id:
oneOf:
- type: integer
- type: 'null'
description: ID of the number assignment currently dispatching calls. Null when idle.
number_pool_size:
type: integer
description: Number of phone numbers configured in the rotation pool.
number_pool:
type: array
description: Phone numbers available for outbound rotation.
items:
type: object
properties:
id:
type: integer
description: Pool assignment ID.
phone_number_id:
type: integer
description: Underlying phone-number record ID.
phone_number:
type: string
description: The phone number in E.164 format.
phone_number_name:
type: string
description: Display label for the number.
sequence:
type: integer
description: Position of the number in the rotation order.
is_active:
type: boolean
description: Whether the number is currently eligible for dispatch.
calls_dispatched:
type: integer
description: Calls dispatched on this number in this campaign.
calls_picked_up:
type: integer
description: Calls answered on this number in this campaign.
rolling_cpr:
oneOf:
- type: number
- type: 'null'
description: Rolling call-pickup rate. Null until enough calls have been dispatched.
health_score:
oneOf:
- type: number
- type: 'null'
description: Computed health score for the number. Null when not yet computed.
total_calls:
type: integer
description: Total contacts in the campaign.
total_calls_to_dispatch:
type: integer
description: Contacts still eligible for dispatch (excludes skipped).
total_calls_made:
type: integer
description: >-
Calls dispatched so far (excludes pending, in-progress, skipped,
retry-scheduled).
completed_calls:
type: integer
description: Calls that finished (any non-pending, non-skipped status).
pending_calls:
type: integer
description: Calls in `Pending` or `In Progress` state.
failed_calls:
type: integer
description: Calls that ended with status `Failed`.
skipped_calls:
type: integer
description: Calls explicitly skipped (e.g. duplicates, opt-outs).
low_interaction_calls:
type: integer
description: Calls flagged as `No/Low Interaction`.
no_low_interaction_calls:
type: integer
description: Same as `low_interaction_calls`. Kept for backward compatibility.
total_pending_calls:
type: integer
description: Pending plus in-progress count.
total_not_reachable_calls:
type: integer
description: Calls that ended with `failed`, `no-answer`, or `busy`.
total_skipped_calls:
type: integer
description: Skipped count (matches `skipped_calls`).
total_reschedule_calls:
type: integer
description: Calls that completed with a reschedule request.
total_call_transfer_count:
type: integer
description: Calls where the agent transferred to a human.
total_call_cost:
type: number
description: Total campaign cost in the user's currency.
total_voiceai_cost:
type: number
description: Voice-AI portion of the cost.
total_telephony_cost:
type: number
description: Telephony portion of the cost.
total_duration_seconds:
type: integer
description: Sum of call durations in seconds.
avg_duration_seconds:
type: integer
description: Average call duration across picked-up calls.
incoming_calls:
type: integer
description: Inbound calls received during the campaign window.
total_lines:
type: integer
description: Total contact rows in the campaign list.
calls_picked_up:
type: integer
description: Calls that were answered (completed or completed-with-reschedule).
call_status_counts:
type: object
description: >-
Map of per-status counts. Keys are call statuses (e.g. `completed`, `Pending`,
`no-answer`, `busy`, `Failed`, `Skipped`); values are integer counts.
additionalProperties:
type: integer
create_date:
type: string
description: Campaign creation timestamp in the user's timezone.
write_date:
type: string
description: Last update timestamp in the user's timezone.
contact_list:
type: array
description: Original recipient list submitted with the campaign.
items:
type: object
properties:
to_number:
type: string
example:
status: success
details:
id: 314
name: test
campaign_type: ai_agent
user_id: 1234
user_name: Demo User
twilio_number: '+15551234567'
bot_id: 6337
bot_name: Customer Support Agent
recording_file_id: null
recording_file_name: null
status: completed
total_calls: 1
completed_calls: 1
pending_calls: 0
failed_calls: 0
skipped_calls: 0
low_interaction_calls: 0
create_date: 04/22/2026 22:10:22
write_date: 04/22/2026 22:10:48
is_scheduled: false
is_dynamic: false
scheduled_datetime: null
timezone: Asia/Kolkata
failed_reason: false
auto_retry: false
auto_retry_schedule: immediately
retry_schedule_days: 0
retry_schedule_hours: 0
retry_count: 0
retry_limit: 1
enabled_reschedule_call: false
concurrent_call_limit: 1
enable_daily_hard_stop: false
daily_stop_time: 0
daily_stop_time_formatted: '00:00'
daily_stop_timezone: America/Los_Angeles
enable_daily_auto_start: false
daily_start_time: 0
daily_start_time_formatted: '00:00'
daily_start_timezone: America/Los_Angeles
email_on_complete: false
email_on_hard_stop: false
email_report_recipients: ''
variable_config:
- id: 45
variable_name: user_name
variable_type: text
enum_values: false
- id: 46
variable_name: agent_name
variable_type: text
enum_values: false
- id: 47
variable_name: company_name
variable_type: text
enum_values: false
rotation_strategy: none
calls_per_number: 50
rotation_health_threshold: 30
rotation_fallback: pause
current_number_assignment_id: null
number_pool_size: 1
number_pool:
- id: 200
phone_number_id: 212
phone_number: '+15551234567'
phone_number_name: '+15551234567'
sequence: 1
is_active: true
calls_dispatched: 1
calls_picked_up: 0
rolling_cpr: null
health_score: null
total_calls_to_dispatch: 1
total_calls_made: 1
calls_picked_up: 0
total_pending_calls: 0
total_not_reachable_calls: 1
no_low_interaction_calls: 0
total_skipped_calls: 0
total_reschedule_calls: 0
total_call_cost: 0
total_voiceai_cost: 0
total_telephony_cost: 0
total_call_transfer_count: 0
call_status_counts:
no-answer: 1
total_duration_seconds: 0
avg_duration_seconds: 0
incoming_calls: 0
total_lines: 1
contact_list:
- to_number: '+15551234567'
```
**Python SDK**
```python
# Get detailed information about a bulk call
response = client.bulk_call.detail_bulk_call(bulk_call_id=123)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/calls/bulk_call/{bulk_call_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Bulk call live status (/docs/api-reference/bulk-calls/getBulkCallLiveStatus)
> Real-time status of a running bulk-call campaign.
**GET** `/bulk-call/{bulk_call_id}/live-status`
Real-time status of a running bulk-call campaign.
```yaml
operationId: getBulkCallLiveStatus
parameters:
- name: bulk_call_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Live status payload.
content:
application/json:
schema:
type: object
properties:
status:
type: string
bulk_call_id:
type: integer
campaign_status:
type: string
summary:
type: object
properties:
total_contacts:
type: integer
queued:
type: integer
in_progress:
type: integer
completed:
type: integer
failed:
type: integer
busy:
type: integer
no_answer:
type: integer
example:
status: success
bulk_call_id: 314
campaign_status: completed
summary:
total_contacts: 1
queued: 0
in_progress: 0
completed: 0
failed: 0
busy: 0
no_answer: 1
```
**Python SDK**
```python
response = client.bulk_call.get_live_status(bulk_call_id=123)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/bulk-call/{bulk_call_id}/live-status" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Create agent (/docs/api-reference/agents/createAgent)
> Create a new agent with the provided configuration. The full
config supports transcriber, model, voice, web search, transfer,
end-call conditions, post-call actions (email + webhook),
ambient background track, initial ringing sound, and multilingual support.
**POST** `/agents/create`
Create a new agent with the provided configuration. The full
config supports transcriber, model, voice, web search, transfer,
end-call conditions, post-call actions (email + webhook),
ambient background track, initial ringing sound, and multilingual support.
```yaml
operationId: createAgent
requestBody:
required: true
content:
application/json:
schema:
allOf:
- type: object
description: Agent configuration.
properties:
name:
type: string
description: Name for the agent.
example: Customer Support Agent
welcome_message:
type: string
description: Initial message the agent will say when answering a call.
example: Hello! How can I help you today?
context_breakdown:
type: array
description: >-
List of context breakdowns, each containing `title`, `body`, and optional
`is_enabled`.
items:
type: object
required:
- title
- body
properties:
title:
type: string
description: Title of the breakdown.
example: Purpose
body:
type: string
description: Body of the breakdown — the detailed prompt content.
example: This agent helps customers with product inquiries and support issues.
is_enabled:
type: boolean
default: true
description: Whether this section is included in the prompt.
call_type:
type: string
enum:
- Incoming
- Outgoing
description: Call type of the assistant.
transcriber:
type: object
description: Configuration for the speech-to-text transcriber.
properties:
provider:
type: string
enum:
- deepgram_stream
- cartesia
- sarvam
- azure_stream
description: The speech-to-text provider to use.
example: deepgram_stream
model:
type: string
enum:
- nova-3
- nova-2
description: >-
The model to use for transcription (required when provider is
`deepgram_stream`).
example: nova-3
silence_timeout_ms:
type: integer
description: Silence timeout in milliseconds.
example: 400
numerals:
type: boolean
description: Convert numbers from words to digits.
punctuate:
type: boolean
description: Add punctuation to the transcript.
smart_format:
type: boolean
description: Apply smart formatting to the transcript.
diarize:
type: boolean
description: Identify different speakers in the transcript.
model:
type: object
description: Configuration for the language model.
properties:
model:
type: string
enum:
- azure-gpt-4.1-mini
- azure-gpt-4.1-nano
- azure-gpt-4o
- azure-gpt-4o-mini
- gemini-2.5-flash
- gemini-2.5-flash-lite
- gpt-3.5-turbo
- gpt-4.1-mini
- gpt-4.1-nano
- gpt-4o
- gpt-4o-mini
- gpt-5.1
- llama-3.3-70b-versatile
description: The language model to use.
example: gpt-4o-mini
temperature:
type: number
minimum: 0
maximum: 1
description: Controls randomness in the model's output (0.0 to 1.0).
example: 0.7
voice:
type: object
description: Configuration for the text-to-speech voice.
properties:
provider:
type: string
enum:
- eleven_labs
- deepgram
- google
- cartesia
- rime
description: The voice provider to use.
example: eleven_labs
voice_id:
type: string
description: The specific external voice identifier from the provider.
example: JBFqnCBsd6RMkjVDRZzb
web_search:
type: object
description: Configuration for web search capabilities.
properties:
enabled:
type: boolean
description: Enable or disable web search functionality.
provider:
type: string
enum:
- DuckDuckGo
description: The search provider to use.
example: DuckDuckGo
post_call_actions:
type: object
description: Side effects that fire once the call ends. Configure email, webhook, or both.
properties:
email:
type: object
properties:
enabled:
type: boolean
recipients:
type: array
description: Email addresses that should receive the notification.
items:
type: string
format: email
example:
- support@example.com
include:
type: array
description: Which sections to include in the email body.
items:
type: string
enum:
- summary
- extracted_variables
- fullConversation
- sentiment
extracted_variables:
type: array
description: Variables the model should pull out of the conversation for the email.
items:
type: object
required:
- key
- prompt
properties:
key:
type: string
description: Unique identifier for the variable in the post-call payload.
example: customer_issue
prompt:
type: string
description: Instruction for the model on what to pull out of the conversation.
example: Identify the main issue the customer is experiencing.
webhook:
type: object
properties:
enabled:
type: boolean
url:
type: string
format: uri
description: Endpoint that receives a POST with the call payload.
example: https://your-webhook-endpoint.com/omnidim-callback
include:
type: array
description: Which sections to include in the webhook body.
items:
type: string
enum:
- summary
- extracted_variables
- fullConversation
- sentiment
extracted_variables:
type: array
description: Variables the model should pull out of the conversation for the webhook.
items:
type: object
required:
- key
- prompt
properties:
key:
type: string
description: Unique identifier for the variable in the post-call payload.
example: customer_issue
prompt:
type: string
description: Instruction for the model on what to pull out of the conversation.
example: Identify the main issue the customer is experiencing.
transfer:
type: object
description: Conditional call transfer to a human agent or another number.
properties:
enabled:
type: boolean
transfer_options:
type: array
description: >-
Where to transfer the call and under what condition. The first matching
condition wins.
items:
type: object
required:
- number
- transfer_condition
- transfer_message
properties:
number:
type: string
description: >-
Primary phone number to transfer to. Include country code with leading
`+`.
example: '+15551234567'
type:
type: string
enum:
- static
- dynamic
default: static
description: |
`static` transfers to `number`. `dynamic` lets the agent
pick a number at runtime based on the conversation.
backup_numbers:
type: array
description: Fallback numbers tried if the primary is unreachable.
items:
type: string
transfer_condition:
type: string
description: Natural-language condition that triggers this transfer option.
example: Transfer if the customer asks to speak with a human.
transfer_message:
type: string
description: Message the agent says to the caller before executing the transfer.
example: Please hold while I connect you to one of our agents.
end_call:
type: object
description: Hang up automatically when a condition is met.
properties:
enabled:
type: boolean
condition:
type: string
description: >-
Natural-language condition that triggers ending the call. Only evaluated when
`enabled` is true.
example: End the call once the customer's issue is resolved.
message:
type: string
description: What the agent says before hanging up.
example: Thank you for contacting us. Have a great day!
background_track:
type: object
description: Ambient background noise that plays under the agent's voice.
properties:
enabled:
type: boolean
description: Whether to mix the ambient track under the agent's audio.
name:
type: string
enum:
- call_center
- filler
- office
- office_1
- restaurant
description: Ambient track to mix under the agent.
volume:
type: number
minimum: 0
maximum: 1
default: 0.2
description: Volume level on a 0–1 scale. Default 0.2.
initial_ringing_sound_enabled:
type: boolean
description: Plays a ringing tone after the call is picked up, until the agent starts speaking.
voicemail:
type: object
description: Voicemail / answering-machine handling for outbound calls.
properties:
enabled:
type: boolean
description: Detect voicemail and react instead of speaking to a machine.
message:
type: string
description: Message to leave when voicemail is detected.
languages:
type: array
description: Languages the agent should support. Pass each language as a display-name string.
items:
type: string
enum:
- English
- English (India)
- English (US)
- Hindi
- Bengali
- Spanish
- Tamil
- Marathi
- Telugu
- Gujarati
- French
example:
- English
- Hindi
- type: object
required:
- name
- welcome_message
- context_breakdown
responses:
'200':
description: Created agent.
content:
application/json:
schema:
type: object
properties:
id:
type: integer
description: Agent identifier. Use this in subsequent calls to `/agents/{agent_id}`.
name:
type: string
description: Echoes the `name` you submitted.
status:
type: string
description: Build state of the agent. Always `Completed` for newly created agents.
example:
id: 6365
name: Customer Support Agent
status: Completed
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Create a basic agent
response = client.agent.create(
name="Customer Support Agent",
welcome_message="Hello! I'm your customer support assistant. How can I help you today?",
context_breakdown=[
{"title": "Purpose", "body": "This agent helps customers with product inquiries and support issues."}
]
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/agents/create" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Delete agent (/docs/api-reference/agents/deleteAgent)
> Permanently delete an agent.
**DELETE** `/agents/{agent_id}`
Permanently delete an agent.
```yaml
operationId: deleteAgent
responses:
'200':
description: Agent deleted.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
example:
success: true
message: Agent deleted successfully
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Delete an agent
agent_id = "your_agent_id_here"
response = client.agent.delete(agent_id)
print(response)
```
**curl**
```bash
curl -X DELETE "https://backend.omnidim.io/api/v1/agents/{agent_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Get agent (/docs/api-reference/agents/getAgent)
> Get details of a specific agent by ID.
**GET** `/agents/{agent_id}`
Get details of a specific agent by ID.
```yaml
operationId: getAgent
responses:
'200':
description: Agent details.
content:
application/json:
schema:
type: object
description: An AI voice agent.
properties:
id:
type: integer
example: 158910
name:
type: string
example: Customer Support Agent
bot_type:
type: string
example: prompt
bot_call_type:
type: string
enum:
- Incoming
- Outgoing
user_id:
type: integer
user_name:
type: string
organization_id:
type: integer
welcome_message:
type: string
is_welcome_message_dynamic:
type: boolean
is_welcome_message_interruption:
type: boolean
is_interruption_allowed:
type: boolean
interruption_min_words:
type: integer
status_of_building_flow:
type: string
example: Completed
context_breakdown:
type: array
items:
type: object
properties:
id:
type: integer
context_title:
type: string
context_body:
type: string
is_enabled:
type: boolean
is_auto_generated:
type: boolean
languages:
type: array
description: Resolved language records. Each entry is `{value, label}` from `bot.language`.
items:
type: object
properties:
value:
type: integer
label:
type: string
llm_service:
type: string
example: gpt-4o-mini
llm_temperature:
type: number
llm_straming_enabled:
type: boolean
asr_service:
type: string
example: deepgram_stream
asr_deepgram_model:
type: string
asr_deepgram_numerals:
type: boolean
asr_deepgram_punctuate:
type: boolean
asr_deepgram_smart_format:
type: boolean
asr_deepgram_diarize:
type: boolean
silence_timeout:
type: integer
voice_provider:
type: string
voice_external_id:
type: string
description: External voice ID from the provider.
voice_name:
type: string
english_voice_accent:
type: string
eleven_lab_voice_public_owner_id:
type: string
nullable: true
speech_speed:
type: number
enable_web_search:
type: boolean
web_search_engine:
type: string
background_noise_enabled:
type: boolean
background_noice_name:
oneOf:
- type: string
- type: boolean
background_audio_volume:
type: number
initial_ringing_sound_enabled:
type: boolean
voicemail_enabled:
type: boolean
voicemail_message:
type: string
is_end_call_enabled:
type: boolean
end_call_condition:
type: string
end_call_message:
type: string
end_call_message_type:
type: string
end_call_message_prompt:
type: string
max_call_duration_in_sec:
type: integer
user_idle_threshold_sec:
type: integer
first_ideal_message:
type: string
second_ideal_message:
type: string
last_ideal_message:
type: string
is_first_ideal_message_dynamic:
type: boolean
is_second_ideal_message_dynamic:
type: boolean
is_transfer_enabled:
type: boolean
is_custom_api_transfer_enabled:
type: boolean
transfer_options:
type: array
items:
type: object
properties:
number:
type: string
type:
type: string
enum:
- static
- dynamic
backup_numbers:
type: array
items:
type: string
transfer_condition:
type: string
transfer_message:
type: string
post_call_config_ids:
type: array
description: Resolved post-call notification configs. One entry per email/webhook destination.
items:
type: object
properties:
id:
type: integer
delivery_method:
type: string
enum:
- Email
- Webhook
destination:
type: string
description: Comma-separated recipients for Email; webhook url for Webhook.
include_summary:
type: boolean
include_full_conversation:
type: boolean
include_sentiment:
type: boolean
include_extracted_info:
type: boolean
extracted_variables:
type: array
items:
type: object
properties:
key:
type: string
description:
type: string
attach_file_ids:
type: array
description: IDs of knowledge-base files attached to this agent.
items:
type: integer
integrations:
type: array
description: Connected integration records (HubSpot, Salesforce, Slack, etc.).
items:
type: object
flow_data:
oneOf:
- type: object
- type: boolean
bot_action_name:
oneOf:
- type: string
- type: boolean
example:
id: 6342
organization_id: 14
name: Outbound Real Estate Lead Qualification Agent
context: >
# Agent Identity & Purpose
# AGENT GLOBAL INSTRUCTIONS
## PERSONA
- The agent is a virtual real estate sales assistant.
- Represents a real estate company calling a potential property buyer or renter.
- Speaks directly to the lead (customer).
- Purpose is to confirm interest, qualify the lead, and follow up on previous inquiries.
- Overall intent is to be polite, friendly, and professional, with a calm and helpful
demeanor.
# RESPONSE GENERATION GUIDES
- Your responses will be read aloud by a text-to-speech system.
- Always use short, simple, conversational sentences.
- Never use bullet points, numbered lists, formatted text, or symbols in spoken
responses.
- End responses with a soft, natural conversational hook when appropriate.
- Speak politely and naturally, as if talking to a real person on a phone call.
# SCOPE
- Can introduce the company and reason for calling.
- Can confirm the lead’s interest in buying, selling, or renting property.
- Can ask qualifying questions about property needs, budget, and timeline.
- Can schedule a follow-up call or appointment with a real estate agent.
- Cannot provide legal, financial, or technical advice.
- Must politely redirect unsupported queries.
# GUARDRAILS
- Never pressure, manipulate, or rush the lead.
- Never guarantee property availability, pricing, or approval.
- Never ask for sensitive information such as social security numbers or full bank
details.
# Lead Confirmation & Introduction
# LEAD CONFIRMATION & INTRODUCTION
- Confirm the lead’s name and introduce the company.
- State the purpose of the call and reference the lead’s previous inquiry if applicable.
Example response:
Hello [user_name], this is [agent_name] from [company_name]. I am calling because you
showed interest in our real estate listings. Is now a good time to talk?
# Interest & Needs Qualification
# INTEREST & NEEDS QUALIFICATION
- Ask if the lead is still interested in buying, selling, or renting property.
- Ask simple qualifying questions about property type, location, budget, and timeline.
Example response:
Are you still interested in finding a new property? What kind of home or apartment are
you looking for?
# Follow-Up & Appointment Scheduling
# FOLLOW-UP & APPOINTMENT SCHEDULING
- Offer to schedule a call or meeting with a licensed real estate agent if the lead is
interested.
- Confirm preferred times and contact details.
Example response:
Would you like to schedule a call with one of our real estate agents to discuss your
options in more detail? What time works best for you?
# Handle Not Interested or Unavailable
# HANDLE NOT INTERESTED OR UNAVAILABLE
- Respect the lead’s decision if they are not interested or unavailable.
- Offer to follow up later if appropriate.
- Close politely.
Example response:
That is completely fine. Thank you for your time. If you change your mind, feel free to
contact us anytime.
# Closing Statement
# CLOSING STATEMENT
- End the call politely and thank the lead for their time.
Example response:
Thank you for speaking with me today. Have a wonderful day.
# Agent Knowledge & Context
The agent understands real estate lead qualification, polite follow-up etiquette, and
how to schedule appointments with licensed agents. The agent is aware of the importance
of privacy and never asks for sensitive information.
# FAQ Examples
User: How did you get my number?
Agent: You shared your contact details with us when you showed interest in our real
estate listings.
User: Can you send me more property details?
Agent: I can arrange for a real estate agent to send you more information or schedule a
call to discuss your needs.
User: Are you a real person?
Agent: I am a virtual assistant calling on behalf of [company_name] to help with your
real estate inquiry.
user_id: 1234
user_name: Demo User
bot_action_id: false
context_breakdown:
- id: 114705
context_title: Agent Identity & Purpose
context_body: >-
# AGENT GLOBAL INSTRUCTIONS
## PERSONA
- The agent is a virtual real estate sales assistant.
- Represents a real estate company calling a potential property buyer or renter.
- Speaks directly to the lead (customer).
- Purpose is to confirm interest, qualify the lead, and follow up on previous
inquiries.
- Overall intent is to be polite, friendly, and professional, with a calm and
helpful demeanor.
# RESPONSE GENERATION GUIDES
- Your responses will be read aloud by a text-to-speech system.
- Always use short, simple, conversational sentences.
- Never use bullet points, numbered lists, formatted text, or symbols in spoken
responses.
- End responses with a soft, natural conversational hook when appropriate.
- Speak politely and naturally, as if talking to a real person on a phone call.
# SCOPE
- Can introduce the company and reason for calling.
- Can confirm the lead’s interest in buying, selling, or renting property.
- Can ask qualifying questions about property needs, budget, and timeline.
- Can schedule a follow-up call or appointment with a real estate agent.
- Cannot provide legal, financial, or technical advice.
- Must politely redirect unsupported queries.
# GUARDRAILS
- Never pressure, manipulate, or rush the lead.
- Never guarantee property availability, pricing, or approval.
- Never ask for sensitive information such as social security numbers or full bank
details.
is_enabled: true
is_auto_generated: false
- id: 114706
context_title: Lead Confirmation & Introduction
context_body: >-
# LEAD CONFIRMATION & INTRODUCTION
- Confirm the lead’s name and introduce the company.
- State the purpose of the call and reference the lead’s previous inquiry if
applicable.
Example response:
Hello [user_name], this is [agent_name] from [company_name]. I am calling because
you showed interest in our real estate listings. Is now a good time to talk?
is_enabled: true
is_auto_generated: false
- id: 114707
context_title: Interest & Needs Qualification
context_body: >-
# INTEREST & NEEDS QUALIFICATION
- Ask if the lead is still interested in buying, selling, or renting property.
- Ask simple qualifying questions about property type, location, budget, and
timeline.
Example response:
Are you still interested in finding a new property? What kind of home or apartment
are you looking for?
is_enabled: true
is_auto_generated: false
- id: 114708
context_title: Follow-Up & Appointment Scheduling
context_body: >-
# FOLLOW-UP & APPOINTMENT SCHEDULING
- Offer to schedule a call or meeting with a licensed real estate agent if the lead
is interested.
- Confirm preferred times and contact details.
Example response:
Would you like to schedule a call with one of our real estate agents to discuss your
options in more detail? What time works best for you?
is_enabled: true
is_auto_generated: false
- id: 114709
context_title: Handle Not Interested or Unavailable
context_body: >-
# HANDLE NOT INTERESTED OR UNAVAILABLE
- Respect the lead’s decision if they are not interested or unavailable.
- Offer to follow up later if appropriate.
- Close politely.
Example response:
That is completely fine. Thank you for your time. If you change your mind, feel free
to contact us anytime.
is_enabled: true
is_auto_generated: false
- id: 114710
context_title: Closing Statement
context_body: |-
# CLOSING STATEMENT
- End the call politely and thank the lead for their time.
Example response:
Thank you for speaking with me today. Have a wonderful day.
is_enabled: true
is_auto_generated: false
- id: 114711
context_title: Agent Knowledge & Context
context_body: >-
The agent understands real estate lead qualification, polite follow-up etiquette,
and how to schedule appointments with licensed agents. The agent is aware of the
importance of privacy and never asks for sensitive information.
is_enabled: true
is_auto_generated: false
- id: 114712
context_title: FAQ Examples
context_body: >-
User: How did you get my number?
Agent: You shared your contact details with us when you showed interest in our real
estate listings.
User: Can you send me more property details?
Agent: I can arrange for a real estate agent to send you more information or
schedule a call to discuss your needs.
User: Are you a real person?
Agent: I am a virtual assistant calling on behalf of [company_name] to help with
your real estate inquiry.
is_enabled: true
is_auto_generated: false
llm_service: gpt-4.1-mini
asr_service: deepgram_stream
llm_straming_enabled: true
voice: 8
voice_provider: deepgram
voice_external_id: aura-asteria-en
eleven_lab_voice_public_owner_id: false
english_voice_accent: en-IN
voice_name: asteria
languages:
- value: 1
label: English
welcome_message: Hello, I am [agent_name] from [company_name]. Am I speaking with [user_name]?
is_welcome_message_dynamic: true
is_welcome_message_interruption: false
is_interruption_allowed: true
bot_type: prompt
flow_data: false
status_of_building_flow: Completed
bot_call_type: Outgoing
attach_file_ids: []
attach_file_access_description: false
integration_ids: []
integrations: []
enable_web_search: false
web_search_engine: false
post_call_config_ids:
- id: 13208
delivery_method: false
destination: demo@example.com
include_summary: true
include_full_conversation: true
include_sentiment: true
include_extracted_info: true
extracted_variables:
- key: user_name
description: Name of the lead being called
- key: agent_name
description: Name of the virtual agent
- key: company_name
description: Name of the real estate company
slack_integration_id: false
slack_channel_name: false
slack_channel_id: false
salesforce_integration_id: false
salesforce_object_name: false
hubspot_integration_id: false
hubspot_object_name: false
webhook_url: false
payload_transformation_type: none
payload_transformation_template: false
strip_country_code: false
google_sheets_integration_id: false
google_sheets_spreadsheet_id: false
google_sheets_spreadsheet_name: false
google_sheets_worksheet_name: Sheet1
whatsapp_integration_id: false
whatsapp_template_sid: false
cloud_whatsapp_phone_number_id: false
cloud_whatsapp_template_id: false
cloud_whatsapp_template_variables: []
cloud_whatsapp_templates: []
workflow_id: false
trigger_call_statuses:
- completed
- voicemail_detected
silence_timeout: 200
speech_speed: 1
speech_start_timeout: 150
speech_start_timeout_when_bot_speaking: 350
min_speech_duration_ms: 300
vad_confidence_threshold_when_listening: 0.6
vad_confidence_threshold_when_bot_speaking: 0.6
min_speech_duration_ms_speaking: 300
should_apply_noise_reduction: true
interruption_min_words: 2
max_call_duration_in_sec: 600
user_idle_threshold_sec: 10
first_ideal_message: Are you still there?
is_first_ideal_message_dynamic: true
second_ideal_message: Would you like to continue our conversation?
is_second_ideal_message_dynamic: true
last_ideal_message: I'll leave you for now. Have a nice day!
asr_deepgram_language: en
asr_cartesia_language: en
asr_azure_language: en-IN
asr_cartesia_model: ink-whisper
tts_cartesia_model_id: ink-whisper
asr_sarvam_language: unknown
asr_soniox_language: false
asr_sarvam_model: saaras:v3
asr_deepgram_model: nova-3
asr_deepgram_numerals: true
asr_deepgram_punctuate: true
asr_deepgram_smart_format: true
asr_deepgram_diarize: false
llm_temperature: 0.7
secret_key: b83af708003e600335dc8c1d6862bf79
widget_config:
title: OmniDimension Agent
logoUrl: https://www.omnidim.io/logo.png
position: bottom-right
iframeUrl: http://localhost:3000/chat-widget?secret=b83af708003e600335dc8c1d6862bf79
textColor: '#b1fbf8'
background: '#142744'
widgetType: chat
iframeWidth: 350px
iframeHeight: 550px
voiceWidgetStyle: full
dynamic_variables: []
is_transfer_enabled: false
is_custom_api_transfer_enabled: false
transfer_options: []
is_end_call_enabled: true
end_call_condition: >-
End the call when the user says goodbye, thank you, or indicates they are done with the
conversation
end_call_message: Thank you for calling. Have a great day! Goodbye.
end_call_message_type: prompt
end_call_message_prompt: End the call politely in the same language user is speaking
voicemail_enabled: false
voicemail_message: false
call_cost_per_min: 0.09
background_noice_name: false
background_audio_volume: 0.2
background_noise_enabled: false
initial_ringing_sound_enabled: false
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Get details of a specific agent
agent_id = "your_agent_id_here"
response = client.agent.get(agent_id)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/agents/{agent_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List agents (/docs/api-reference/agents/listAgents)
> Retrieve all agents for the authenticated user with pagination support.
**GET** `/agents`
Retrieve all agents for the authenticated user with pagination support.
```yaml
operationId: listAgents
parameters:
- name: pageno
in: query
schema:
type: integer
default: 1
description: Page number for pagination.
- name: pagesize
in: query
schema:
type: integer
default: 30
maximum: 150
description: Number of items per page (max 150).
- name: name
in: query
schema:
type: string
description: Filter agents whose name matches this substring (case-insensitive).
responses:
'200':
description: Paginated list of agents.
content:
application/json:
schema:
type: object
properties:
bots:
type: array
items:
type: object
description: An AI voice agent.
properties:
id:
type: integer
example: 158910
name:
type: string
example: Customer Support Agent
bot_type:
type: string
example: prompt
bot_call_type:
type: string
enum:
- Incoming
- Outgoing
user_id:
type: integer
user_name:
type: string
organization_id:
type: integer
welcome_message:
type: string
is_welcome_message_dynamic:
type: boolean
is_welcome_message_interruption:
type: boolean
is_interruption_allowed:
type: boolean
interruption_min_words:
type: integer
status_of_building_flow:
type: string
example: Completed
context_breakdown:
type: array
items:
type: object
properties:
id:
type: integer
context_title:
type: string
context_body:
type: string
is_enabled:
type: boolean
is_auto_generated:
type: boolean
languages:
type: array
description: Resolved language records. Each entry is `{value, label}` from `bot.language`.
items:
type: object
properties:
value:
type: integer
label:
type: string
llm_service:
type: string
example: gpt-4o-mini
llm_temperature:
type: number
llm_straming_enabled:
type: boolean
asr_service:
type: string
example: deepgram_stream
asr_deepgram_model:
type: string
asr_deepgram_numerals:
type: boolean
asr_deepgram_punctuate:
type: boolean
asr_deepgram_smart_format:
type: boolean
asr_deepgram_diarize:
type: boolean
silence_timeout:
type: integer
voice_provider:
type: string
voice_external_id:
type: string
description: External voice ID from the provider.
voice_name:
type: string
english_voice_accent:
type: string
eleven_lab_voice_public_owner_id:
type: string
nullable: true
speech_speed:
type: number
enable_web_search:
type: boolean
web_search_engine:
type: string
background_noise_enabled:
type: boolean
background_noice_name:
oneOf:
- type: string
- type: boolean
background_audio_volume:
type: number
initial_ringing_sound_enabled:
type: boolean
voicemail_enabled:
type: boolean
voicemail_message:
type: string
is_end_call_enabled:
type: boolean
end_call_condition:
type: string
end_call_message:
type: string
end_call_message_type:
type: string
end_call_message_prompt:
type: string
max_call_duration_in_sec:
type: integer
user_idle_threshold_sec:
type: integer
first_ideal_message:
type: string
second_ideal_message:
type: string
last_ideal_message:
type: string
is_first_ideal_message_dynamic:
type: boolean
is_second_ideal_message_dynamic:
type: boolean
is_transfer_enabled:
type: boolean
is_custom_api_transfer_enabled:
type: boolean
transfer_options:
type: array
items:
type: object
properties:
number:
type: string
type:
type: string
enum:
- static
- dynamic
backup_numbers:
type: array
items:
type: string
transfer_condition:
type: string
transfer_message:
type: string
post_call_config_ids:
type: array
description: >-
Resolved post-call notification configs. One entry per email/webhook
destination.
items:
type: object
properties:
id:
type: integer
delivery_method:
type: string
enum:
- Email
- Webhook
destination:
type: string
description: Comma-separated recipients for Email; webhook url for Webhook.
include_summary:
type: boolean
include_full_conversation:
type: boolean
include_sentiment:
type: boolean
include_extracted_info:
type: boolean
extracted_variables:
type: array
items:
type: object
properties:
key:
type: string
description:
type: string
attach_file_ids:
type: array
description: IDs of knowledge-base files attached to this agent.
items:
type: integer
integrations:
type: array
description: Connected integration records (HubSpot, Salesforce, Slack, etc.).
items:
type: object
flow_data:
oneOf:
- type: object
- type: boolean
bot_action_name:
oneOf:
- type: string
- type: boolean
total_records:
type: integer
description: Total number of agents on the account.
example:
bots:
- id: 6342
name: Customer Support Agent
bot_type: prompt
user_name: Demo User
user_id: 1234
bot_action_name: false
language:
- English
voice: cgSgspJ2msm6clMCkdW9
voice_provider: deepgram
voice_external_id: aura-asteria-en
eleven_lab_voice_public_owner_id: false
english_voice_accent: en-IN
voice_name: asteria
llm_service: gpt-4.1-mini
llm_straming_enabled: true
allow_to_delete: true
status_of_building_flow: Completed
dynamic_variables: []
flow_data: false
bot_call_type: Outgoing
attach_file_ids: []
attach_file_access_description: false
integration_ids: []
integrations: []
enable_web_search: false
web_search_engine: false
post_call_config_ids:
- id: 13208
delivery_method: false
destination: demo@example.com
include_summary: true
include_full_conversation: true
include_sentiment: true
include_extracted_info: true
extracted_variables:
- key: user_name
description: Name of the lead being called
- key: agent_name
description: Name of the virtual agent
- key: company_name
description: Name of the real estate company
slack_integration_id: false
slack_channel_name: false
slack_channel_id: false
salesforce_integration_id: false
salesforce_object_name: false
hubspot_integration_id: false
hubspot_object_name: false
webhook_url: false
payload_transformation_type: none
payload_transformation_template: false
strip_country_code: false
google_sheets_integration_id: false
google_sheets_spreadsheet_id: false
google_sheets_spreadsheet_name: false
google_sheets_worksheet_name: Sheet1
whatsapp_integration_id: false
whatsapp_template_sid: false
cloud_whatsapp_phone_number_id: false
cloud_whatsapp_template_id: false
cloud_whatsapp_template_variables: []
cloud_whatsapp_templates: []
workflow_id: false
trigger_call_statuses:
- completed
- voicemail_detected
is_end_call_enabled: true
end_call_condition: >-
End the call when the user says goodbye, thank you, or indicates they are done with
the conversation
end_call_message: Thank you for calling. Have a great day! Goodbye.
end_call_message_type: prompt
end_call_message_prompt: End the call politely in the same language user is speaking
voicemail_enabled: false
background_noice_name: false
background_audio_volume: 0.2
background_noise_enabled: false
initial_ringing_sound_enabled: false
speech_speed: 1
organization_branch_ids: []
closed_organization_branch_ids: []
total_records: 61
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# List all agents with pagination
response = client.agent.list(page=1, page_size=10)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/agents" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Update agent (/docs/api-reference/agents/updateAgent)
> Update an existing agent. Send only the fields you want to change.
**PUT** `/agents/{agent_id}`
Update an existing agent. Send only the fields you want to change.
```yaml
operationId: updateAgent
requestBody:
required: true
content:
application/json:
schema:
type: object
description: Agent configuration.
properties:
name:
type: string
description: Name for the agent.
example: Customer Support Agent
welcome_message:
type: string
description: Initial message the agent will say when answering a call.
example: Hello! How can I help you today?
context_breakdown:
type: array
description: >-
List of context breakdowns, each containing `title`, `body`, and optional
`is_enabled`.
items:
type: object
required:
- title
- body
properties:
title:
type: string
description: Title of the breakdown.
example: Purpose
body:
type: string
description: Body of the breakdown — the detailed prompt content.
example: This agent helps customers with product inquiries and support issues.
is_enabled:
type: boolean
default: true
description: Whether this section is included in the prompt.
call_type:
type: string
enum:
- Incoming
- Outgoing
description: Call type of the assistant.
transcriber:
type: object
description: Configuration for the speech-to-text transcriber.
properties:
provider:
type: string
enum:
- deepgram_stream
- cartesia
- sarvam
- azure_stream
description: The speech-to-text provider to use.
example: deepgram_stream
model:
type: string
enum:
- nova-3
- nova-2
description: The model to use for transcription (required when provider is `deepgram_stream`).
example: nova-3
silence_timeout_ms:
type: integer
description: Silence timeout in milliseconds.
example: 400
numerals:
type: boolean
description: Convert numbers from words to digits.
punctuate:
type: boolean
description: Add punctuation to the transcript.
smart_format:
type: boolean
description: Apply smart formatting to the transcript.
diarize:
type: boolean
description: Identify different speakers in the transcript.
model:
type: object
description: Configuration for the language model.
properties:
model:
type: string
enum:
- azure-gpt-4.1-mini
- azure-gpt-4.1-nano
- azure-gpt-4o
- azure-gpt-4o-mini
- gemini-2.5-flash
- gemini-2.5-flash-lite
- gpt-3.5-turbo
- gpt-4.1-mini
- gpt-4.1-nano
- gpt-4o
- gpt-4o-mini
- gpt-5.1
- llama-3.3-70b-versatile
description: The language model to use.
example: gpt-4o-mini
temperature:
type: number
minimum: 0
maximum: 1
description: Controls randomness in the model's output (0.0 to 1.0).
example: 0.7
voice:
type: object
description: Configuration for the text-to-speech voice.
properties:
provider:
type: string
enum:
- eleven_labs
- deepgram
- google
- cartesia
- rime
description: The voice provider to use.
example: eleven_labs
voice_id:
type: string
description: The specific external voice identifier from the provider.
example: JBFqnCBsd6RMkjVDRZzb
web_search:
type: object
description: Configuration for web search capabilities.
properties:
enabled:
type: boolean
description: Enable or disable web search functionality.
provider:
type: string
enum:
- DuckDuckGo
description: The search provider to use.
example: DuckDuckGo
post_call_actions:
type: object
description: Side effects that fire once the call ends. Configure email, webhook, or both.
properties:
email:
type: object
properties:
enabled:
type: boolean
recipients:
type: array
description: Email addresses that should receive the notification.
items:
type: string
format: email
example:
- support@example.com
include:
type: array
description: Which sections to include in the email body.
items:
type: string
enum:
- summary
- extracted_variables
- fullConversation
- sentiment
extracted_variables:
type: array
description: Variables the model should pull out of the conversation for the email.
items:
type: object
required:
- key
- prompt
properties:
key:
type: string
description: Unique identifier for the variable in the post-call payload.
example: customer_issue
prompt:
type: string
description: Instruction for the model on what to pull out of the conversation.
example: Identify the main issue the customer is experiencing.
webhook:
type: object
properties:
enabled:
type: boolean
url:
type: string
format: uri
description: Endpoint that receives a POST with the call payload.
example: https://your-webhook-endpoint.com/omnidim-callback
include:
type: array
description: Which sections to include in the webhook body.
items:
type: string
enum:
- summary
- extracted_variables
- fullConversation
- sentiment
extracted_variables:
type: array
description: Variables the model should pull out of the conversation for the webhook.
items:
type: object
required:
- key
- prompt
properties:
key:
type: string
description: Unique identifier for the variable in the post-call payload.
example: customer_issue
prompt:
type: string
description: Instruction for the model on what to pull out of the conversation.
example: Identify the main issue the customer is experiencing.
transfer:
type: object
description: Conditional call transfer to a human agent or another number.
properties:
enabled:
type: boolean
transfer_options:
type: array
description: >-
Where to transfer the call and under what condition. The first matching condition
wins.
items:
type: object
required:
- number
- transfer_condition
- transfer_message
properties:
number:
type: string
description: Primary phone number to transfer to. Include country code with leading `+`.
example: '+15551234567'
type:
type: string
enum:
- static
- dynamic
default: static
description: |
`static` transfers to `number`. `dynamic` lets the agent
pick a number at runtime based on the conversation.
backup_numbers:
type: array
description: Fallback numbers tried if the primary is unreachable.
items:
type: string
transfer_condition:
type: string
description: Natural-language condition that triggers this transfer option.
example: Transfer if the customer asks to speak with a human.
transfer_message:
type: string
description: Message the agent says to the caller before executing the transfer.
example: Please hold while I connect you to one of our agents.
end_call:
type: object
description: Hang up automatically when a condition is met.
properties:
enabled:
type: boolean
condition:
type: string
description: >-
Natural-language condition that triggers ending the call. Only evaluated when
`enabled` is true.
example: End the call once the customer's issue is resolved.
message:
type: string
description: What the agent says before hanging up.
example: Thank you for contacting us. Have a great day!
background_track:
type: object
description: Ambient background noise that plays under the agent's voice.
properties:
enabled:
type: boolean
description: Whether to mix the ambient track under the agent's audio.
name:
type: string
enum:
- call_center
- filler
- office
- office_1
- restaurant
description: Ambient track to mix under the agent.
volume:
type: number
minimum: 0
maximum: 1
default: 0.2
description: Volume level on a 0–1 scale. Default 0.2.
initial_ringing_sound_enabled:
type: boolean
description: Plays a ringing tone after the call is picked up, until the agent starts speaking.
voicemail:
type: object
description: Voicemail / answering-machine handling for outbound calls.
properties:
enabled:
type: boolean
description: Detect voicemail and react instead of speaking to a machine.
message:
type: string
description: Message to leave when voicemail is detected.
languages:
type: array
description: Languages the agent should support. Pass each language as a display-name string.
items:
type: string
enum:
- English
- English (India)
- English (US)
- Hindi
- Bengali
- Spanish
- Tamil
- Marathi
- Telugu
- Gujarati
- French
example:
- English
- Hindi
responses:
'200':
description: Updated agent.
content:
application/json:
schema:
type: object
properties:
id:
type: integer
description: Agent identifier.
name:
type: string
status:
type: string
description: >-
Build state of the agent after the update. Always `Completed` once the operation
returns.
example:
id: 6365
name: Updated Support Agent
status: Completed
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Update an existing agent
agent_id = "your_agent_id_here"
update_data = {
"name": "Updated Support Agent",
"welcome_message": "Hello! I'm your updated support assistant. How can I help you today?",
"model": {
"temperature": 0.8
}
}
response = client.agent.update(agent_id, update_data)
print(response)
```
**curl**
```bash
curl -X PUT "https://backend.omnidim.io/api/v1/agents/{agent_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Dispatch call (/docs/api-reference/calls/dispatchCall)
> Initiate a call to a phone number using a specified agent. The
phone number must include a country code with a leading plus.
**POST** `/calls/dispatch`
Initiate a call to a phone number using a specified agent. The
phone number must include a country code with a leading plus.
```yaml
operationId: dispatchCall
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- agent_id
- to_number
properties:
agent_id:
type: integer
description: The ID of the agent that will handle the call.
example: 158910
to_number:
type: string
description: The phone number to call. Must include country code (e.g., +15551234567).
example: '+15551234567'
from_number_id:
type: integer
description: The imported phone number id to call.
example: 23
call_context:
type: object
description: >-
Optional context information as key-value pairs to be passed to the agent during the
call. Can contain any custom fields relevant to your use case.
additionalProperties: true
example:
user_name: Jane Doe
account_id: A-2031
last_order: '2026-04-15'
example:
agent_id: 158910
to_number: '+15551234567'
from_number_id: 23
call_context:
user_name: Jane Doe
account_id: A-2031
last_order: '2026-04-15'
responses:
'200':
description: Call dispatched.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
status:
type: string
description: >-
Dispatch state on the platform side. `dispatched` means the call has been queued for
the dialer.
example: dispatched
requestId:
type: integer
description: >-
Internal call request id. Use it to correlate with `call_request_id` on
`/calls/logs`.
example: 3166940
custom_variables_count:
type: integer
description: Number of keys the platform extracted from `call_context`.
example:
success: true
status: dispatched
requestId: 3166940
custom_variables_count: 1
```
**Python SDK**
```python
# Dispatch a call to a specific number using an agent
agent_id = 123 # Replace with your agent ID
to_number = "+15551234567" # Must include country code
from_number_id = 23 # get the from number id from phone number API. /api/v1/phone_number/list
call_context = {
"customer_name": "John Doe",
"account_id": "ACC-12345",
"priority": "high"
}
response = client.call.dispatch_call(agent_id, to_number, call_context=call_context)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/calls/dispatch" \
-H "Authorization: Bearer $OMNIDIM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": 158910,
"to_number": "+15551234567",
"from_number_id": 23,
"call_context": {
"user_name": "Jane Doe",
"account_id": "A-2031",
"last_order": "2026-04-15"
}
}'
```
# Get call log (/docs/api-reference/calls/getCallLog)
> Detailed information about a specific call (duration, status, transcript, sentiment, extracted variables).
**GET** `/calls/logs/{call_log_id}`
Detailed information about a specific call (duration, status, transcript, sentiment, extracted variables).
```yaml
operationId: getCallLog
parameters:
- name: call_log_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Call log details (singleton in the `call_log_data` array).
content:
application/json:
schema:
type: object
properties:
call_log_data:
type: array
items:
type: object
description: A single call log entry.
properties:
id:
type: integer
example: 3517893
bot_name:
type: string
organization_branch_name:
type: string
is_bot_response:
type: boolean
time_of_call:
type: string
description: Display-formatted timestamp (`MM/DD/YYYY HH:MM:SS`).
example: 05/06/2026 13:31:54
from_number:
type: string
to_number:
type: string
call_direction:
type: string
enum:
- inbound
- outbound
call_status:
type: string
example: completed
call_duration:
type: string
description: Display-formatted duration (`M:S`).
example: '0:42'
call_duration_in_seconds:
type: integer
call_duration_in_minutes:
type: number
recording_url:
oneOf:
- type: string
format: uri
- type: boolean
description: Signed URL to the recording, or `false` if unavailable.
internal_recording_url:
oneOf:
- type: string
- type: boolean
channel_type:
type: string
example: Voice
sentiment_score:
type: string
example: Positive
sentiment_analysis_details:
type: string
call_conversation:
type: string
description: Full transcript with `
`-separated turns.
extracted_variables:
type: object
additionalProperties: true
interactions:
type: array
items:
type: object
additionalProperties: true
post_call_actions:
type: object
additionalProperties: true
cqs_score:
type: number
prompt_tokens:
type: integer
completion_tokens:
type: integer
total_tokens:
type: integer
aggregated_estimated_cost:
type: number
model_name:
type: string
asr_service:
type: string
tts_service:
type: string
is_simulation:
type: boolean
is_voicemail:
type: boolean
amd_detected:
type: boolean
hangup_source:
oneOf:
- type: string
- type: 'null'
hangup_reason:
oneOf:
- type: string
- type: 'null'
call_request_id:
type: object
additionalProperties: true
total_records:
type: integer
example:
call_log_data:
- id: 50958
organization_branch_name: ''
bot_name: Customer Support Agent
is_bot_response: true
time_of_call: 05/04/2026 14:46:15
from_number: Chat
to_number: Assistant
call_direction: outbound
call_duration: '0:0'
recording_url: false
internal_recording_url: false
recording_available_at: ''
call_conversation: '
user:
LLM: Hello, I am Kevin from OmniDimension support. How may I help you?
user: i awnt ti book a meetig
LLM: Sure, I can help with that. Could you please provide me with your name and email address?
user: aok demo@example.com
LLM: Let''s confirm your email address: demo@example.com Is that correct?
user: y
LLM: Great, you can book a meeting using the link below.
'
call_status: completed
channel_type: Widget-Chat
sentiment_score: Positive
sentiment_analysis_details: >-
The user requested to book a meeting, providing their email address. The agent
confirmed the email and provided a link for booking the meeting successfully.
call_type: false
is_call_transfer: false
status: ''
cqs_score: 0
cqs_score_message: false
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
p50_latency: 2.53
p99_latency: 2.79
prompt_tokens: 31727
completion_tokens: 95
total_tokens: 31822
total_tts_speaking_minutes: 0
total_tts_speaking_seconds: 0
llm_prompt: false
aggregated_estimated_cost: 0.123
model_name: gpt-4o
model_type: chat
asr_service: deepgram_stream
tts_service: eleven_labs
has_issue: false
is_simulation: false
json_evolution_matrix_score: {}
issues: []
call_duration_in_seconds: 0
call_duration_in_minutes: 0
extracted_variables:
industry: Not provided
use_case: Not provided
user_name: Demo User
main_purpose: Booking a meeting
phone_number: Not provided
preferred_language: Not provided
monthly_call_volume: Not provided
interaction_count_total: 4
voice_insides: false
amd_detected: false
amd_answered_by: false
amd_duration: 0
is_voicemail: false
is_fax: false
voicemail_type: false
hangup_source: null
hangup_reason: null
user_name: Demo User
call_cost: 0
call_request_id:
id: false
type_of_request: ''
interactions:
- id: 88247
interaction_sequence: 1
user_query: ''
bot_response: Hello, I am Kevin from OmniDimension support. How may I help you?
customer_phone_number: false
time_of_call: 05/04/2026 14:43:00
llm2_time: 2.349710792
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 2.349710792
latency_tts: 0
total_response_time: 2.349710792
evaluation_remarks: false
total_tokens: 6314
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data: false
tts_speaking_duration: 0
- id: 88248
interaction_sequence: 2
user_query: i awnt ti book a meetig
bot_response: >-
Sure, I can help with that. Could you please provide me with your name and email
address?
customer_phone_number: false
time_of_call: 05/04/2026 14:43:08
llm2_time: 2.534026668
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 2.534026668
latency_tts: 0
total_response_time: 2.534026668
evaluation_remarks: false
total_tokens: 6318
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data: false
tts_speaking_duration: 0
- id: 88249
interaction_sequence: 3
user_query: aok demo@example.com
bot_response: 'Let''s confirm your email address: demo@example.com Is that correct?'
customer_phone_number: false
time_of_call: 05/04/2026 14:43:13
llm2_time: 1.136648417
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 1.136648417
latency_tts: 0
total_response_time: 1.136648417
evaluation_remarks: false
total_tokens: 6351
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data: false
tts_speaking_duration: 0
- id: 88250
interaction_sequence: 4
user_query: 'y'
bot_response: Great, you can book a meeting using the link below.
customer_phone_number: false
time_of_call: 05/04/2026 14:43:18
llm2_time: 2.787461793
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 2.787461793
latency_tts: 0
total_response_time: 2.787461793
evaluation_remarks: false
total_tokens: 12839
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data:
- args: {}
result: >-
Calendly card is now visible to the visitor below your reply. Stop and wait
for them to tap. Do not ask any follow-up question this turn.
success: true
time_taken: 0.002235458
function_name: offer_calendly_meeting
tts_speaking_duration: 0
post_call_actions:
call_recording_webhook_ids:
- id: 1870
name: >-
Webhook to https://webhook.site/94b3db04-2a3f-480f-86f5-6bcc84b4cc5b on
2026-05-04 14:46:15
webhook_url: https://webhook.site/94b3db04-2a3f-480f-86f5-6bcc84b4cc5b
webhook_method: POST
payload: >-
{"call_id": 50958, "call_sid":
"secret_key_fb6cac5ad0ba353d30768b2f6d92dab3_74f67317-cdd6-4b56-9954-440933284998",
"bot_id": 6340, "bot_name": "Demo User", "phone_number": "Chat",
"call_direction": "outbound", "to_number": "Assistant", "call_request_id":
false, "from_number": "Chat", "call_date": "2026-05-04 14:46:15",
"start_time": "2026-05-04 14:46:15", "end_time": "2026-05-04 14:46:15",
"call_duration": 0, "user_email": "demo@example.com", "call_status":
"completed", "hangup_source": false, "recording_url": false,
"recording_available_at": null, "low_interaction": true, "call_report":
{"summary": "The user requested to book a meeting, providing their email
address. The agent confirmed the email and provided a link for booking the
meeting successfully.", "sentiment": "Positive", "extracted_variables":
{"user_name": "Not provided", "phone_number": "Not provided", "main_purpose":
"Booking a meeting", "use_case": "Not provided", "monthly_call_volume": "Not
provided", "industry": "Not provided", "preferred_language": "Not provided"},
"full_conversation": " \n user: \n LLM: Hello, I am Kevin from OmniDimension
support. How may I help you? \n \n user: i awnt ti book a meetig \n LLM: Sure,
I can help with that. Could you please provide me with your name and email
address? \n \n user: aok demo@example.com \n LLM: Let's confirm your email
address: demo@example.com Is that correct? \n \n user: y \n LLM: Great, you
can book a meeting using the link below. \n", "interactions": [{"sequence": 1,
"user_query": "", "bot_response": "Hello, I am Kevin from OmniDimension
support. How may I help you?", "time": "2026-05-04 14:43:00"}, {"sequence": 2,
"user_query": "i awnt ti book a meetig", "bot_response": "Sure, I can help
with that. Could you please provide me with your name and email address?",
"time": "2026-05-04 14:43:08"}, {"sequence": 3, "user_query": "aok
demo@example.com", "bot_response": "Let's confirm your email address:
demo@example.com Is that correct?", "time": "2026-05-04 14:43:13"},
{"sequence": 4, "user_query": "y", "bot_response": "Great, you can book a
meeting using the link below.", "time": "2026-05-04 14:43:18"}]}}
status: sent
response_code: 200
response_body: >-
This URL has no default content configured. Change
response in Webhook.site.
error_message: false
call_recording_id: 50958
user_id: 1234
create_date: '2026-05-04 14:46:15'
create_by: Demo User
email_service_ids: []
hubspot_service_ids: []
slack_service_ids: []
salesforce_service_ids: []
google_sheets_service_ids: []
total_records: 1
```
**Python SDK**
```python
# Get details of a specific call log
call_log_id = "your_call_log_id_here"
response = client.call.get_call_log(call_log_id)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/calls/logs/{call_log_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List call logs (/docs/api-reference/calls/listCallLogs)
> Retrieve call logs with pagination and optional filtering.
**GET** `/calls/logs`
Retrieve call logs with pagination and optional filtering.
```yaml
operationId: listCallLogs
parameters:
- name: pageno
in: query
schema:
type: integer
default: 1
description: Page number for pagination.
- name: pagesize
in: query
schema:
type: integer
default: 30
maximum: 150
description: Number of items per page.
- name: agentid
in: query
schema:
type: integer
description: Filter by agent ID.
- name: call_status
in: query
schema:
type: string
enum:
- completed
- busy
- failed
- no-answer
- name: bulk_call_id
in: query
schema:
type: integer
description: Filter by bulk-call campaign ID.
responses:
'200':
description: Paginated list of call logs.
content:
application/json:
schema:
type: object
properties:
call_log_data:
type: array
items:
type: object
description: A single call log entry.
properties:
id:
type: integer
example: 3517893
bot_name:
type: string
organization_branch_name:
type: string
is_bot_response:
type: boolean
time_of_call:
type: string
description: Display-formatted timestamp (`MM/DD/YYYY HH:MM:SS`).
example: 05/06/2026 13:31:54
from_number:
type: string
to_number:
type: string
call_direction:
type: string
enum:
- inbound
- outbound
call_status:
type: string
example: completed
call_duration:
type: string
description: Display-formatted duration (`M:S`).
example: '0:42'
call_duration_in_seconds:
type: integer
call_duration_in_minutes:
type: number
recording_url:
oneOf:
- type: string
format: uri
- type: boolean
description: Signed URL to the recording, or `false` if unavailable.
internal_recording_url:
oneOf:
- type: string
- type: boolean
channel_type:
type: string
example: Voice
sentiment_score:
type: string
example: Positive
sentiment_analysis_details:
type: string
call_conversation:
type: string
description: Full transcript with `
`-separated turns.
extracted_variables:
type: object
additionalProperties: true
interactions:
type: array
items:
type: object
additionalProperties: true
post_call_actions:
type: object
additionalProperties: true
cqs_score:
type: number
prompt_tokens:
type: integer
completion_tokens:
type: integer
total_tokens:
type: integer
aggregated_estimated_cost:
type: number
model_name:
type: string
asr_service:
type: string
tts_service:
type: string
is_simulation:
type: boolean
is_voicemail:
type: boolean
amd_detected:
type: boolean
hangup_source:
oneOf:
- type: string
- type: 'null'
hangup_reason:
oneOf:
- type: string
- type: 'null'
call_request_id:
type: object
additionalProperties: true
total_records:
type: integer
example:
call_log_data:
- id: 50958
organization_branch_name: ''
bot_name: Customer Support Agent
is_bot_response: true
time_of_call: 05/04/2026 14:46:15
from_number: Chat
to_number: Assistant
call_direction: outbound
call_duration: '0:0'
recording_url: false
internal_recording_url: false
recording_available_at: ''
call_conversation: '
user:
LLM: Hello, I am Kevin from OmniDimension support. How may I help you?
user: i awnt ti book a meetig
LLM: Sure, I can help with that. Could you please provide me with your name and email address?
user: aok demo@example.com
LLM: Let''s confirm your email address: demo@example.com Is that correct?
user: y
LLM: Great, you can book a meeting using the link below.
'
call_status: completed
channel_type: Widget-Chat
sentiment_score: Positive
sentiment_analysis_details: >-
The user requested to book a meeting, providing their email address. The agent
confirmed the email and provided a link for booking the meeting successfully.
call_type: false
is_call_transfer: false
status: ''
cqs_score: 0
cqs_score_message: false
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
p50_latency: 2.53
p99_latency: 2.79
prompt_tokens: 31727
completion_tokens: 95
total_tokens: 31822
total_tts_speaking_minutes: 0
total_tts_speaking_seconds: 0
llm_prompt: false
aggregated_estimated_cost: 0.123
model_name: gpt-4o
model_type: chat
asr_service: deepgram_stream
tts_service: eleven_labs
has_issue: false
is_simulation: false
json_evolution_matrix_score: {}
issues: []
call_duration_in_seconds: 0
call_duration_in_minutes: 0
extracted_variables:
industry: Not provided
use_case: Not provided
user_name: Demo User
main_purpose: Booking a meeting
phone_number: Not provided
preferred_language: Not provided
monthly_call_volume: Not provided
interaction_count_total: 4
voice_insides: false
amd_detected: false
amd_answered_by: false
amd_duration: 0
is_voicemail: false
is_fax: false
voicemail_type: false
hangup_source: null
hangup_reason: null
user_name: Demo User
call_cost: 0
call_request_id:
id: false
type_of_request: ''
interactions:
- id: 88247
interaction_sequence: 1
user_query: ''
bot_response: Hello, I am Kevin from OmniDimension support. How may I help you?
customer_phone_number: false
time_of_call: 05/04/2026 14:43:00
llm2_time: 2.349710792
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 2.349710792
latency_tts: 0
total_response_time: 2.349710792
evaluation_remarks: false
total_tokens: 6314
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data: false
tts_speaking_duration: 0
- id: 88248
interaction_sequence: 2
user_query: i awnt ti book a meetig
bot_response: >-
Sure, I can help with that. Could you please provide me with your name and email
address?
customer_phone_number: false
time_of_call: 05/04/2026 14:43:08
llm2_time: 2.534026668
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 2.534026668
latency_tts: 0
total_response_time: 2.534026668
evaluation_remarks: false
total_tokens: 6318
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data: false
tts_speaking_duration: 0
- id: 88249
interaction_sequence: 3
user_query: aok demo@example.com
bot_response: 'Let''s confirm your email address: demo@example.com Is that correct?'
customer_phone_number: false
time_of_call: 05/04/2026 14:43:13
llm2_time: 1.136648417
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 1.136648417
latency_tts: 0
total_response_time: 1.136648417
evaluation_remarks: false
total_tokens: 6351
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data: false
tts_speaking_duration: 0
- id: 88250
interaction_sequence: 4
user_query: 'y'
bot_response: Great, you can book a meeting using the link below.
customer_phone_number: false
time_of_call: 05/04/2026 14:43:18
llm2_time: 2.787461793
asr_time: 0
tts_time: 0
metric_score_intent: 0
metric_score_relevance: 0
metric_score_latency: 0
metric_score_coherence: 0
latency_llm: 2.787461793
latency_tts: 0
total_response_time: 2.787461793
evaluation_remarks: false
total_tokens: 12839
has_issue: false
total_cost: 0
issues: []
json_evolution_matrix_score: {}
function_call_data:
- args: {}
result: >-
Calendly card is now visible to the visitor below your reply. Stop and wait
for them to tap. Do not ask any follow-up question this turn.
success: true
time_taken: 0.002235458
function_name: offer_calendly_meeting
tts_speaking_duration: 0
post_call_actions:
call_recording_webhook_ids:
- id: 1870
name: >-
Webhook to https://webhook.site/94b3db04-2a3f-480f-86f5-6bcc84b4cc5b on
2026-05-04 14:46:15
webhook_url: https://webhook.site/94b3db04-2a3f-480f-86f5-6bcc84b4cc5b
webhook_method: POST
payload: >-
{"call_id": 50958, "call_sid":
"secret_key_fb6cac5ad0ba353d30768b2f6d92dab3_74f67317-cdd6-4b56-9954-440933284998",
"bot_id": 6340, "bot_name": "Demo User", "phone_number": "Chat",
"call_direction": "outbound", "to_number": "Assistant", "call_request_id":
false, "from_number": "Chat", "call_date": "2026-05-04 14:46:15",
"start_time": "2026-05-04 14:46:15", "end_time": "2026-05-04 14:46:15",
"call_duration": 0, "user_email": "demo@example.com", "call_status":
"completed", "hangup_source": false, "recording_url": false,
"recording_available_at": null, "low_interaction": true, "call_report":
{"summary": "The user requested to book a meeting, providing their email
address. The agent confirmed the email and provided a link for booking the
meeting successfully.", "sentiment": "Positive", "extracted_variables":
{"user_name": "Not provided", "phone_number": "Not provided", "main_purpose":
"Booking a meeting", "use_case": "Not provided", "monthly_call_volume": "Not
provided", "industry": "Not provided", "preferred_language": "Not provided"},
"full_conversation": " \n user: \n LLM: Hello, I am Kevin from OmniDimension
support. How may I help you? \n \n user: i awnt ti book a meetig \n LLM: Sure,
I can help with that. Could you please provide me with your name and email
address? \n \n user: aok demo@example.com \n LLM: Let's confirm your email
address: demo@example.com Is that correct? \n \n user: y \n LLM: Great, you
can book a meeting using the link below. \n", "interactions": [{"sequence": 1,
"user_query": "", "bot_response": "Hello, I am Kevin from OmniDimension
support. How may I help you?", "time": "2026-05-04 14:43:00"}, {"sequence": 2,
"user_query": "i awnt ti book a meetig", "bot_response": "Sure, I can help
with that. Could you please provide me with your name and email address?",
"time": "2026-05-04 14:43:08"}, {"sequence": 3, "user_query": "aok
demo@example.com", "bot_response": "Let's confirm your email address:
demo@example.com Is that correct?", "time": "2026-05-04 14:43:13"},
{"sequence": 4, "user_query": "y", "bot_response": "Great, you can book a
meeting using the link below.", "time": "2026-05-04 14:43:18"}]}}
status: sent
response_code: 200
response_body: >-
This URL has no default content configured. Change
response in Webhook.site.
error_message: false
call_recording_id: 50958
user_id: 1234
create_date: '2026-05-04 14:46:15'
create_by: Demo User
email_service_ids: []
hubspot_service_ids: []
slack_service_ids: []
salesforce_service_ids: []
google_sheets_service_ids: []
total_records: 1672
```
**Python SDK**
```python
# Get all call logs with pagination
response = client.call.get_call_logs(page=1, page_size=10)
print(response)
# Filter by agent ID
response = client.call.get_call_logs(page=1, page_size=10, agent_id=123)
print(response)
# Filter by call status
response = client.call.get_call_logs(page=1, call_status="completed")
print(response)
# Filter by bulk call campaign
response = client.call.get_call_logs(page=1, page_size=50, bulk_call_id=123)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/calls/logs" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Attach files to agent (/docs/api-reference/knowledge-base/attachKnowledgeBaseFiles)
> Attach multiple knowledge-base files to an agent.
**POST** `/knowledge_base/attach`
Attach multiple knowledge-base files to an agent.
```yaml
operationId: attachKnowledgeBaseFiles
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- file_ids
- agent_id
properties:
file_ids:
type: array
minItems: 1
items:
type: integer
description: List of knowledge-base file IDs to attach.
example:
- 17686
agent_id:
type: integer
description: ID of the agent to attach files to.
example: 158910
when_to_use:
type: string
description: Instruction to the agent on when to consult these files.
example: Use these documents to answer billing-related questions.
responses:
'200':
description: Files attached.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
example:
success: true
message: 1 files attached to agent successfully
```
**Python SDK**
```python
# Attach files to an agent
file_ids = [123, 456] # Replace with your file IDs
agent_id = 789 # Replace with your agent ID
response = client.knowledge_base.attach(
file_ids,
agent_id,
when_to_use="Use KB When User ask for pricing"
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/knowledge_base/attach" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Check file upload capability (/docs/api-reference/knowledge-base/canUploadFile)
> Check whether a file can be uploaded based on size and type.
**POST** `/knowledge_base/can_upload`
Check whether a file can be uploaded based on size and type.
```yaml
operationId: canUploadFile
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- file_size
- file_type
properties:
file_size:
type: integer
minimum: 1
description: Size in bytes.
example: 524288
file_type:
type: string
description: File extension. Only `pdf` is accepted.
example: pdf
responses:
'200':
description: Upload capability and quota information.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
quota:
type: object
description: Knowledge-base storage quota in megabytes.
properties:
total:
type: number
used:
type: number
remaining:
type: number
example:
success: true
message: File can be uploaded
quota:
total: 10
used: 0
remaining: 10
```
**Python SDK**
```python
# Check if a file of the given size can be uploaded
file_size = 1024 * 1024 # 1MB file
response = client.knowledge_base.can_upload(file_size)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/knowledge_base/can_upload" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Delete file from knowledge base (/docs/api-reference/knowledge-base/deleteKnowledgeBaseFile)
> Permanently delete a file. Removes it from any attached agents. Cannot be undone.
**POST** `/knowledge_base/delete`
Permanently delete a file. Removes it from any attached agents. Cannot be undone.
```yaml
operationId: deleteKnowledgeBaseFile
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- file_id
properties:
file_id:
type: integer
description: ID of the file to delete.
example: 17686
responses:
'200':
description: File deleted.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
example:
success: true
message: File deleted successfully
```
**Python SDK**
```python
# Delete a file from the knowledge base
file_id = 123 # Replace with your file ID
response = client.knowledge_base.delete(file_id)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/knowledge_base/delete" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Detach files from agent (/docs/api-reference/knowledge-base/detachKnowledgeBaseFiles)
> Detach multiple knowledge-base files from an agent.
**POST** `/knowledge_base/detach`
Detach multiple knowledge-base files from an agent.
```yaml
operationId: detachKnowledgeBaseFiles
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- file_ids
- agent_id
properties:
file_ids:
type: array
minItems: 1
items:
type: integer
description: List of knowledge-base file IDs to detach.
example:
- 17686
agent_id:
type: integer
description: ID of the agent to detach files from.
example: 158910
responses:
'200':
description: Files detached.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
example:
success: true
message: 1 files detached from agent successfully
```
**Python SDK**
```python
# Detach files from an agent
file_ids = [123, 456] # Replace with your file IDs
agent_id = 789 # Replace with your agent ID
response = client.knowledge_base.detach(file_ids, agent_id)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/knowledge_base/detach" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List knowledge base files (/docs/api-reference/knowledge-base/listKnowledgeBaseFiles)
> List all knowledge-base files for the authenticated user.
**GET** `/knowledge_base/list`
List all knowledge-base files for the authenticated user.
```yaml
operationId: listKnowledgeBaseFiles
responses:
'200':
description: List of files.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
files:
type: array
items:
type: object
description: A file uploaded to the knowledge base.
properties:
id:
type: integer
example: 17686
name:
type: string
example: customer_call.mp3
original_filename:
type: string
example: customer_call.mp3
file_size:
type: integer
description: Size in bytes.
mime_type:
type: string
example: audio/mpeg
download_url:
type: string
format: uri
upload_status:
type: string
example: uploaded
upload_date:
type: string
example: 04/11/2026 16:24:00
user_name:
type: string
user_id:
type: integer
organization_id:
type: integer
example:
success: true
files:
- id: 964
name: customer_call.mp3
original_filename: customer_call.mp3
file_size: 1145133
mime_type: audio/mpeg
download_url: >-
https://omnidim.s3.amazonaws.com/live_uploads/1234/20260411_162353_customer_call.mp3?AWSAccessKeyId=AKIA...&Signature=...&Expires=...
upload_status: uploaded
upload_date: 04/11/2026 16:24:00
user_name: Demo User
user_id: 1234
organization_id: 14
```
**Python SDK**
```python
# List all knowledge base files
response = client.knowledge_base.list()
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/knowledge_base/list" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Upload file to knowledge base (/docs/api-reference/knowledge-base/uploadKnowledgeBaseFile)
> Upload a PDF file. The file content must be Base64 encoded.
**POST** `/knowledge_base/create`
Upload a PDF file. The file content must be Base64 encoded.
```yaml
operationId: uploadKnowledgeBaseFile
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- file
- filename
properties:
file:
type: string
description: Base64-encoded file content.
filename:
type: string
description: Filename including the `.pdf` extension.
example: sample.pdf
responses:
'200':
description: Uploaded file metadata.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
file:
type: object
description: A file uploaded to the knowledge base.
properties:
id:
type: integer
example: 17686
name:
type: string
example: customer_call.mp3
original_filename:
type: string
example: customer_call.mp3
file_size:
type: integer
description: Size in bytes.
mime_type:
type: string
example: audio/mpeg
download_url:
type: string
format: uri
upload_status:
type: string
example: uploaded
upload_date:
type: string
example: 04/11/2026 16:24:00
user_name:
type: string
user_id:
type: integer
organization_id:
type: integer
example:
success: true
message: File uploaded successfully
file:
id: 964
name: sample.pdf
original_filename: sample.pdf
file_size: 524288
mime_type: application/pdf
upload_status: uploaded
upload_date: 05/08/2026 10:30:00
user_id: 1234
user_name: Demo User
organization_id: 14
```
**Python SDK**
```python
# Upload a file to the knowledge base
import base64
file_path = "sample.pdf" # Path to your PDF file
file_name = "sample.pdf" # Name for the file in the knowledge base
with open(file_path, "rb") as file:
file_data = base64.b64encode(file.read()).decode('utf-8')
response = client.knowledge_base.create(file_data, file_name)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/knowledge_base/create" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Attach phone number to agent (/docs/api-reference/phone-numbers/attachPhoneNumber)
> Attach an account-owned phone number to an existing agent.
**POST** `/phone_number/attach`
Attach an account-owned phone number to an existing agent.
```yaml
operationId: attachPhoneNumber
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- phone_number_id
- agent_id
properties:
phone_number_id:
type: integer
description: ID of the phone number to attach.
example: 23
agent_id:
type: integer
description: ID of the agent to attach the phone number to.
example: 158910
responses:
'200':
description: Phone number attached.
content:
application/json:
schema:
type: object
properties:
phone_number_id:
type: integer
message:
type: string
example:
phone_number_id: 23
message: Phone Number +15551234567 Attach Successfully.
```
**Python SDK**
```python
import os
from omnidimension import Client
# Initialize the client
api_key = os.environ.get('OMNIDIM_API_KEY')
client = Client(api_key)
# Attach a phone number to an agent
phone_number_id = 123 # Replace with your phone number ID
agent_id = 456 # Replace with your agent ID
response = client.phone_number.attach(phone_number_id, agent_id)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/phone_number/attach" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Detach phone number (/docs/api-reference/phone-numbers/detachPhoneNumber)
> Detach a phone number from its associated agent.
**POST** `/phone_number/detach`
Detach a phone number from its associated agent.
```yaml
operationId: detachPhoneNumber
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- phone_number_id
properties:
phone_number_id:
type: integer
description: ID of the phone number to detach.
example: 23
responses:
'200':
description: Phone number detached.
content:
application/json:
schema:
type: object
properties:
phone_number_id:
type: integer
message:
type: string
example:
phone_number_id: 23
message: Phone Number +15551234567 Detached Successfully.
```
**Python SDK**
```python
import os
from omnidimension import Client
# Initialize the client
api_key = os.environ.get('OMNIDIM_API_KEY')
client = Client(api_key)
# Detach a phone number from its associated agent
phone_number_id = 123 # Replace with your phone number ID
response = client.phone_number.detach(phone_number_id)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/phone_number/detach" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Import Exotel number (/docs/api-reference/phone-numbers/importExotelNumber)
> Import an Exotel number by providing your Exotel credentials.
**POST** `/phone_number/import/exotel`
Import an Exotel number by providing your Exotel credentials.
```yaml
operationId: importExotelNumber
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- exotel_phone_number
- exotel_api_key
- exotel_api_token
- exotel_subdomain
- exotel_account_sid
- exotel_app_id
properties:
exotel_phone_number:
type: string
description: Exotel phone number in E.164 format.
example: '+919876543210'
exotel_api_key:
type: string
description: Your Exotel API key.
exotel_api_token:
type: string
description: Your Exotel API token.
exotel_subdomain:
type: string
description: Your Exotel subdomain (e.g. `your-account.in.exotel.com`).
exotel_account_sid:
type: string
description: Your Exotel account SID.
exotel_app_id:
type: string
description: The Exotel App ID configured for the bot.
name:
type: string
description: Optional friendly name for the imported number.
responses:
'200':
description: Exotel number imported.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
id:
type: integer
description: ID of the newly imported phone number record. Use this with `/phone_number/attach`.
example:
success: true
message: Number added successfully
id: 3360
```
**Python SDK**
```python
import os
from omnidimension import Client
# Initialize the client
api_key = os.environ.get('OMNIDIM_API_KEY')
client = Client(api_key)
# Import an existing Exotel number
response = client.phone_number.import_exotel_number(
exotel_phone_number="02261234567",
exotel_api_key="your_exotel_api_key",
exotel_api_token="your_exotel_api_token",
exotel_subdomain="your_subdomain",
exotel_account_sid="your_account_sid",
exotel_app_id="your_app_id",
name="My Exotel Number" # Optional
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/phone_number/import/exotel" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Import SIP trunk (/docs/api-reference/phone-numbers/importSipTrunk)
> Import a phone number associated with a SIP trunk.
**POST** `/phone_number/import/sip`
Import a phone number associated with a SIP trunk.
```yaml
operationId: importSipTrunk
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- phone_number
- sip_host
- sip_trunk_name
properties:
phone_number:
type: string
description: Phone number in E.164 format (starting with `+`).
example: '+12025550123'
sip_host:
type: string
description: SIP server hostname or IP.
example: sip.yourprovider.com
sip_trunk_name:
type: string
description: Name for this SIP trunk (must be unique within your account).
name:
type: string
description: Optional friendly name for the imported number.
sip_port:
type: integer
default: 5060
description: SIP server port.
sip_username:
type: string
description: SIP authentication username.
sip_password:
type: string
format: password
description: SIP authentication password.
sip_dial_prefix:
type: string
description: >-
Optional prefix to prepend before the destination number when dialing (e.g. to strip
the country code).
sip_strip_plus:
type: boolean
description: When true, strips the leading `+` from the dialed number.
responses:
'200':
description: SIP trunk imported.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
id:
type: integer
description: ID of the newly imported phone number record. Use this with `/phone_number/attach`.
example:
success: true
message: SIP trunk registered successfully
id: 3360
```
**Python SDK**
```python
import os
from omnidimension import Client
# Initialize the client
api_key = os.environ.get('OMNIDIM_API_KEY')
client = Client(api_key)
# Import a SIP trunk
response = client.phone_number.import_sip_number(
phone_number="+1234567890",
sip_host="sip.yourprovider.com",
sip_trunk_name="my-sip-trunk",
name="My SIP Number", # Optional
sip_port=5060, # Optional, defaults to 5060
sip_username="user123", # Optional
sip_password="secret", # Optional
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/phone_number/import/sip" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Import Twilio number (/docs/api-reference/phone-numbers/importTwilioNumber)
> Import an existing Twilio number by providing your Twilio credentials.
**POST** `/phone_number/import/twilio`
Import an existing Twilio number by providing your Twilio credentials.
```yaml
operationId: importTwilioNumber
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- phone_number
- account_sid
- account_token
properties:
phone_number:
type: string
description: Phone number in E.164 format (starting with `+`).
example: '+12025550123'
account_sid:
type: string
description: Your Twilio account SID.
account_token:
type: string
description: Your Twilio auth token.
name:
type: string
description: Optional friendly name for the imported number.
responses:
'200':
description: Twilio number imported.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
id:
type: integer
description: ID of the newly imported phone number record. Use this with `/phone_number/attach`.
example:
success: true
message: Number added successfully
id: 3360
```
**Python SDK**
```python
import os
from omnidimension import Client
# Initialize the client
api_key = os.environ.get('OMNIDIM_API_KEY')
client = Client(api_key)
# Import an existing Twilio number
response = client.phone_number.import_twilio_number(
phone_number="+1234567890",
account_sid="AC1234567890abcdef1234567890abcdef",
account_token="your_twilio_auth_token",
name="My Twilio Number" # Optional
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/phone_number/import/twilio" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List phone numbers (/docs/api-reference/phone-numbers/listPhoneNumbers)
> Retrieve all phone numbers associated with your account.
**GET** `/phone_number/list`
Retrieve all phone numbers associated with your account.
```yaml
operationId: listPhoneNumbers
parameters:
- name: pageno
in: query
schema:
type: integer
default: 1
- name: pagesize
in: query
schema:
type: integer
default: 30
maximum: 150
responses:
'200':
description: Paginated phone numbers.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
phone_numbers:
type: array
items:
type: object
description: A phone number on the account.
properties:
id:
type: integer
example: 3360
name:
type: string
user_id:
type: integer
user_name:
type: string
phone_number:
type: string
example: '+15551234567'
active_bot_id:
oneOf:
- type: integer
- type: boolean
description: ID of the agent currently attached to this number, or `false` if none.
purchase_date:
type: string
example: 05/01/2026 11:04:56
expiry_date:
oneOf:
- type: string
- type: boolean
location:
type: string
number_provider:
type: string
enum:
- twilio
- exotel
- sip
- cloud_whatsapp
number_source:
type: string
is_manually_imported:
type: boolean
can_message:
type: boolean
call_sid:
oneOf:
- type: string
- type: boolean
session_start_time:
oneOf:
- type: string
- type: 'null'
telephony_did_id:
oneOf:
- type: integer
- type: 'null'
health_score:
oneOf:
- type: number
- type: 'null'
health_score_computed_at:
oneOf:
- type: string
- type: 'null'
health_score_details:
oneOf:
- type: object
- type: 'null'
sip_host:
oneOf:
- type: string
- type: boolean
sip_port:
oneOf:
- type: string
- type: boolean
sip_username:
oneOf:
- type: string
- type: boolean
sip_password:
oneOf:
- type: string
- type: boolean
sip_trunk_name:
oneOf:
- type: string
- type: boolean
sip_id:
oneOf:
- type: string
- type: boolean
exotel_phone_number:
oneOf:
- type: string
- type: boolean
exotel_api_key:
oneOf:
- type: string
- type: boolean
exotel_api_token:
oneOf:
- type: string
- type: boolean
exotel_subdomain:
oneOf:
- type: string
- type: boolean
exotel_account_sid:
oneOf:
- type: string
- type: boolean
exotel_app_id:
oneOf:
- type: string
- type: boolean
is_phone_wa:
type: boolean
is_cloud_wa:
type: boolean
wa_wbaid:
oneOf:
- type: string
- type: boolean
wa_app_id:
oneOf:
- type: string
- type: boolean
wa_business_id:
oneOf:
- type: string
- type: boolean
wa_access_token:
oneOf:
- type: string
- type: boolean
example:
success: true
phone_numbers:
- id: 213
name: sales-line
user_id: 1234
user_name: Demo User
phone_number: '+15551234567'
can_message: false
purchase_date: 04/02/2026 09:24:29
active_bot_id: false
location: US
number_provider: sip
call_sid: false
exotel_api_key: false
exotel_api_token: false
exotel_subdomain: false
exotel_account_sid: false
exotel_phone_number: false
exotel_app_id: false
is_phone_wa: false
session_start_time: null
is_cloud_wa: false
wa_wbaid: false
wa_app_id: false
wa_business_id: false
wa_access_token: false
sip_host:
sip_port:
sip_username:
sip_password:
sip_trunk_name: inbound-trunk
sip_id:
number_source: imported
is_manually_imported: false
telephony_did_id: null
expiry_date: ''
health_score: null
health_score_computed_at: null
health_score_details: null
```
**Python SDK**
```python
import os
from omnidimension import Client
# Initialize the client
api_key = os.environ.get('OMNIDIM_API_KEY')
client = Client(api_key)
# List all phone numbers with pagination
response = client.phone_number.list(page=1, page_size=10)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/phone_number/list" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Get voice details (/docs/api-reference/providers/getVoice)
> Detailed metadata for a specific voice.
**GET** `/providers/voice/{voice_id}`
Detailed metadata for a specific voice.
```yaml
operationId: getVoice
parameters:
- name: voice_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Voice details.
content:
application/json:
schema:
type: object
description: A single voice's metadata.
properties:
id:
oneOf:
- type: integer
- type: 'null'
name:
type: string
display_name:
type: string
service:
type: string
sample_url:
type: string
format: uri
example:
id: 1
name: aura-luna-en
display_name: luna
service: deepgram
sample_url: https://res.cloudinary.com/deepgram/video/upload/v1709565351/aura/luna_docs_clom0e.wav
'404':
description: No voice with that ID.
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Voice not found
```
**Python SDK**
```python
# Get detailed information about a specific voice
voice_details = client.providers.get_voice(123)
print(voice_details)
# Returns: {'id': 123, 'name': 'Voice Name', 'provider': 'eleven_labs', ...}
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/providers/voice/{voice_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List all providers (/docs/api-reference/providers/listAllProviders)
> Comprehensive response with services and voices in one payload.
**GET** `/providers/all`
Comprehensive response with services and voices in one payload.
```yaml
operationId: listAllProviders
responses:
'200':
description: Comprehensive providers list.
content:
application/json:
example:
services:
LLM:
- id: 8
name: gemini-2.5-flash
display_name: gemini-2.5-flash
service_type: LLM
- id: 44
name: gpt-5.4
display_name: gpt-5.4
service_type: LLM
- id: 6
name: gemini-1.5-pro
display_name: gemini-1.5-pro
service_type: LLM
- id: 7
name: gemini-2.0-flash
display_name: gemini-2.0-flash
service_type: LLM
- id: 9
name: gemini-2.5-pro
display_name: gemini-2.5-pro
service_type: LLM
- id: 10
name: gemini-2.5-flash-lite
display_name: gemini-2.5-flash-lite
service_type: LLM
- id: 11
name: gpt-4o
display_name: gpt-4o
service_type: LLM
- id: 12
name: gpt-4o-mini
display_name: gpt-4o-mini
service_type: LLM
- id: 13
name: gpt-3.5-turbo
display_name: gpt-3.5-turbo
service_type: LLM
- id: 14
name: azure-gpt-4o
display_name: azure-gpt-4o
service_type: LLM
- id: 15
name: azure-gpt-4o-mini
display_name: azure-gpt-4o-mini
service_type: LLM
- id: 16
name: azure-gpt-4.1-nano
display_name: azure-gpt-4.1-nano
service_type: LLM
- id: 17
name: azure-gpt-4.1-mini
display_name: azure-gpt-4.1-mini
service_type: LLM
- id: 18
name: llama3-8b-8192
display_name: llama3-8b-8192
service_type: LLM
- id: 19
name: llama3-70b-8192
display_name: llama3-70b-8192
service_type: LLM
- id: 20
name: llama-3.3-70b-versatile
display_name: llama-3.3-70b-versatile
service_type: LLM
- id: 21
name: gemma2-9b-it
display_name: gemma2-9b-it
service_type: LLM
- id: 22
name: claude-opus-4-0
display_name: claude-opus-4-0
service_type: LLM
- id: 23
name: claude-sonnet-4-0
display_name: claude-sonnet-4-0
service_type: LLM
- id: 24
name: claude-3-7-sonnet-latest
display_name: claude-3-7-sonnet-latest
service_type: LLM
- id: 25
name: claude-3-5-sonnet-latest
display_name: claude-3-5-sonnet-latest
service_type: LLM
- id: 26
name: claude-3-5-haiku-latest
display_name: claude-3-5-haiku-latest
service_type: LLM
- id: 27
name: claude-3-opus-latest
display_name: claude-3-opus-latest
service_type: LLM
- id: 28
name: Your own LLM
display_name: Your own LLM
service_type: LLM
- id: 39
name: gemini-3-flash-preview
display_name: gemini-3-flash-preview
service_type: LLM
- id: 40
name: gemini-3-pro-preview
display_name: gemini-3-pro-preview
service_type: LLM
TTS:
- id: 41
name: timepay
display_name: timepay
service_type: TTS
- id: 29
name: deepgram
display_name: deepgram
service_type: TTS
- id: 30
name: google
display_name: google
service_type: TTS
- id: 31
name: eleven_labs
display_name: eleven_labs
service_type: TTS
- id: 32
name: cartesia
display_name: cartesia
service_type: TTS
- id: 37
name: sarvam
display_name: sarvam
service_type: TTS
- id: 35
name: hume
display_name: hume
service_type: TTS
- id: 33
name: rime
display_name: rime
service_type: TTS
- id: 38
name: openAI
display_name: openAI
service_type: TTS
- id: 34
name: playht
display_name: playht
service_type: TTS
- id: 36
name: inworld
display_name: inworld
service_type: TTS
STT:
- id: 42
name: Soniox
display_name: Soniox
service_type: STT
- id: 43
name: Speechmatics
display_name: Speechmatics
service_type: STT
- id: 1
name: whisper
display_name: whisper
service_type: STT
- id: 2
name: deepgram_stream
display_name: deepgram_stream
service_type: STT
- id: 3
name: Cartesia
display_name: Cartesia
service_type: STT
- id: 4
name: Sarvam
display_name: Sarvam
service_type: STT
- id: 5
name: Azure
display_name: Azure
service_type: STT
voices:
- id: 1
name: aura-luna-en
display_name: luna
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565351/aura/luna_docs_clom0e.wav
- id: 2
name: aura-stella-en
display_name: stella
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565349/aura/stella_docs_xh5jbv.wav
- id: 3
name: en-IN-Neural2-A
display_name: Neural2 A (Female)
service: google
sample_url: ''
- id: 4
name: aura-asteria-en
display_name: asteria
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565353/aura/asteria_docs_venw0r.wav
- id: 5
name: aura-hera-en
display_name: hera
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565347/aura/hera_docs_xjkt4x.wav
- id: 7
name: en-IN-Journey-O
display_name: Journey (IN)
service: google
sample_url: http://backend.omnidim.io/web/content/bot.voice/7/sample_audio
- id: 8
name: cgSgspJ2msm6clMCkdW9
display_name: Jessica
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/cgSgspJ2msm6clMCkdW9/56a97bf8-b69b-448f-846c-c3a11683d45a.mp3
- id: 9
name: en-US-Journey-F
display_name: Journey(US-Female)
service: google
sample_url: false
- id: 10
name: aura-athena-en
display_name: athena
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565613/aura/athena_docs_wyznud.wav
- id: 11
name: aura-orion-en
display_name: orion
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565346/aura/orion_docs_aljv1q.mp3
- id: 12
name: aura-arcas-en
display_name: arcas
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565348/aura/arcas_docs_pc9hxp.mp3
- id: 13
name: aura-perseus-en
display_name: perseus
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565350/aura/perseus_docs_ap7fc0.wav
- id: 14
name: aura-angus-en
display_name: angus
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565352/aura/angus_docs_lgse2b.wav
- id: 15
name: aura-orpheus-en
display_name: orpheus
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565350/aura/orpheus_docs_zdlpcf.wav
- id: 16
name: aura-helios-en
display_name: helios
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565346/aura/helios_docs_ycjwoo.wav
- id: 17
name: aura-zeus-en
display_name: zeus
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565347/aura/zeus_docs_fupdiv.wav
- id: 32
name: 9BWtsMINqrJLrRacOk9x
display_name: Aria
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/9BWtsMINqrJLrRacOk9x/405766b8-1f4e-4d3c-aba1-6f25333823ec.mp3
- id: 33
name: CwhRBWXzGAHq8TQ4Fs17
display_name: Roger
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/CwhRBWXzGAHq8TQ4Fs17/58ee3ff5-f6f2-4628-93b8-e38eb31806b0.mp3
- id: 34
name: EXAVITQu4vr4xnSDxMaL
display_name: Sarah
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/EXAVITQu4vr4xnSDxMaL/01a3e33c-6e99-4ee7-8543-ff2216a32186.mp3
- id: 35
name: FGY2WhTYpPnrIDTdsKH5
display_name: Laura
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/FGY2WhTYpPnrIDTdsKH5/67341759-ad08-41a5-be6e-de12fe448618.mp3
- id: 36
name: IKne3meq5aSn9XLyUdCD
display_name: Charlie
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/IKne3meq5aSn9XLyUdCD/102de6f2-22ed-43e0-a1f1-111fa75c5481.mp3
- id: 37
name: JBFqnCBsd6RMkjVDRZzb
display_name: George
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/JBFqnCBsd6RMkjVDRZzb/e6206d1a-0721-4787-aafb-06a6e705cac5.mp3
- id: 38
name: N2lVS1w4EtoT3dr4eOWO
display_name: Callum
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/N2lVS1w4EtoT3dr4eOWO/ac833bd8-ffda-4938-9ebc-b0f99ca25481.mp3
- id: 39
name: SAz9YHcvj6GT2YYXdXww
display_name: River
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/SAz9YHcvj6GT2YYXdXww/e6c95f0b-2227-491a-b3d7-2249240decb7.mp3
- id: 40
name: TX3LPaxmHKxFdv7VOQHJ
display_name: Liam
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/TX3LPaxmHKxFdv7VOQHJ/63148076-6363-42db-aea8-31424308b92c.mp3
- id: 41
name: XB0fDUnXU5powFXDhCwa
display_name: Charlotte
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/XB0fDUnXU5powFXDhCwa/942356dc-f10d-4d89-bda5-4f8505ee038b.mp3
- id: 42
name: Xb7hH8MSUJpSbSDYk0k2
display_name: Alice
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/Xb7hH8MSUJpSbSDYk0k2/d10f7534-11f6-41fe-a012-2de1e482d336.mp3
- id: 43
name: XrExE9yKIg1WjnnlVkGX
display_name: Matilda
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/XrExE9yKIg1WjnnlVkGX/b930e18d-6b4d-466e-bab2-0ae97c6d8535.mp3
- id: 44
name: bIHbv24MWmeRgasZH58o
display_name: Will
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/bIHbv24MWmeRgasZH58o/8caf8f3d-ad29-4980-af41-53f20c72d7a4.mp3
- id: 45
name: cjVigY5qzO86Huf0OWal
display_name: Eric
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/cjVigY5qzO86Huf0OWal/d098fda0-6456-4030-b3d8-63aa048c9070.mp3
- id: 46
name: iP95p4xoKVk53GoZ742B
display_name: Chris
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/iP95p4xoKVk53GoZ742B/3f4bde72-cc48-40dd-829f-57fbf906f4d7.mp3
- id: 47
name: nPczCjzI2devNBz1zQrb
display_name: Brian
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/nPczCjzI2devNBz1zQrb/2dd3e72c-4fd3-42f1-93ea-abc5d4e5aa1d.mp3
- id: 48
name: onwK4e9ZLuTAKqWW03F9
display_name: Daniel
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/onwK4e9ZLuTAKqWW03F9/7eee0236-1a72-4b86-b303-5dcadc007ba9.mp3
- id: 49
name: pFZP5JQG7iQjIQuC4Bku
display_name: Lily
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/pFZP5JQG7iQjIQuC4Bku/89b68b35-b3dd-4348-a84a-a3c13a3c2b30.mp3
- id: 50
name: pqHfZKP75CvOlQylNhV4
display_name: Bill
service: eleven_labs
sample_url: >-
https://storage.googleapis.com/eleven-public-prod/premade/voices/pqHfZKP75CvOlQylNhV4/d782b3ff-84ba-4029-848c-acf01285524d.mp3
- id: 51
name: anushka
display_name: Anushka
service: sarvam
sample_url: false
- id: 52
name: manisha
display_name: Manisha
service: sarvam
sample_url: false
- id: 53
name: vidya
display_name: Vidya
service: sarvam
sample_url: false
- id: 54
name: arya
display_name: Arya
service: sarvam
sample_url: false
- id: 55
name: abhilash
display_name: Abhilash
service: sarvam
sample_url: false
- id: 56
name: karun
display_name: Karun
service: sarvam
sample_url: false
- id: 57
name: hitesh
display_name: Hitesh
service: sarvam
sample_url: false
- id: 58
name: en-IN-Chirp-HD-D
display_name: Chirp HD D (Male)
service: google
sample_url: false
- id: 59
name: en-IN-Chirp-HD-F
display_name: Chirp HD F (Female)
service: google
sample_url: false
- id: 60
name: en-IN-Chirp-HD-O
display_name: Chirp HD O (Female)
service: google
sample_url: false
- id: 61
name: en-IN-Chirp3-HD-Achernar
display_name: Achernar (Female)
service: google
sample_url: false
- id: 62
name: en-IN-Chirp3-HD-Achird
display_name: Achird (Male)
service: google
sample_url: false
- id: 63
name: en-IN-Chirp3-HD-Algenib
display_name: Algenib (Male)
service: google
sample_url: false
- id: 64
name: en-IN-Chirp3-HD-Algieba
display_name: Algieba (Male)
service: google
sample_url: false
- id: 65
name: en-IN-Chirp3-HD-Alnilam
display_name: Alnilam (Male)
service: google
sample_url: false
- id: 66
name: en-IN-Chirp3-HD-Aoede
display_name: Aoede (Female)
service: google
sample_url: false
- id: 67
name: en-IN-Chirp3-HD-Autonoe
display_name: Autonoe (Female)
service: google
sample_url: false
- id: 68
name: en-IN-Chirp3-HD-Callirrhoe
display_name: Callirrhoe (Female)
service: google
sample_url: false
- id: 69
name: en-IN-Chirp3-HD-Charon
display_name: Charon (Male)
service: google
sample_url: false
- id: 70
name: en-IN-Chirp3-HD-Despina
display_name: Despina (Female)
service: google
sample_url: false
- id: 71
name: en-IN-Chirp3-HD-Enceladus
display_name: Enceladus (Male)
service: google
sample_url: false
- id: 72
name: en-IN-Chirp3-HD-Erinome
display_name: Erinome (Female)
service: google
sample_url: false
- id: 73
name: en-IN-Chirp3-HD-Fenrir
display_name: Fenrir (Male)
service: google
sample_url: false
- id: 74
name: en-IN-Chirp3-HD-Gacrux
display_name: Gacrux (Female)
service: google
sample_url: false
- id: 75
name: en-IN-Chirp3-HD-Iapetus
display_name: Iapetus (Male)
service: google
sample_url: false
- id: 76
name: en-IN-Chirp3-HD-Kore
display_name: Kore (Female)
service: google
sample_url: false
- id: 77
name: en-IN-Chirp3-HD-Laomedeia
display_name: Laomedeia (Female)
service: google
sample_url: false
- id: 78
name: en-IN-Chirp3-HD-Leda
display_name: Leda (Female)
service: google
sample_url: false
- id: 79
name: en-IN-Chirp3-HD-Orus
display_name: Orus (Male)
service: google
sample_url: false
- id: 80
name: en-IN-Chirp3-HD-Puck
display_name: Puck (Male)
service: google
sample_url: false
- id: 81
name: en-IN-Chirp3-HD-Pulcherrima
display_name: Pulcherrima (Female)
service: google
sample_url: false
- id: 82
name: en-IN-Chirp3-HD-Rasalgethi
display_name: Rasalgethi (Male)
service: google
sample_url: false
- id: 83
name: en-IN-Chirp3-HD-Sadachbia
display_name: Sadachbia (Male)
service: google
sample_url: false
- id: 84
name: en-IN-Chirp3-HD-Sadaltager
display_name: Sadaltager (Male)
service: google
sample_url: false
- id: 85
name: en-IN-Chirp3-HD-Schedar
display_name: Schedar (Male)
service: google
sample_url: false
- id: 86
name: en-IN-Chirp3-HD-Sulafat
display_name: Sulafat (Female)
service: google
sample_url: false
- id: 87
name: en-IN-Chirp3-HD-Umbriel
display_name: Umbriel (Male)
service: google
sample_url: false
- id: 88
name: en-IN-Chirp3-HD-Vindemiatrix
display_name: Vindemiatrix (Female)
service: google
sample_url: false
- id: 89
name: en-IN-Chirp3-HD-Zephyr
display_name: Zephyr (Female)
service: google
sample_url: false
- id: 90
name: en-IN-Chirp3-HD-Zubenelgenubi
display_name: Zubenelgenubi (Male)
service: google
sample_url: false
- id: 91
name: en-IN-Neural2-B
display_name: Neural2 B (Male)
service: google
sample_url: false
- id: 92
name: en-IN-Neural2-C
display_name: Neural2 C (Male)
service: google
sample_url: false
- id: 93
name: en-IN-Neural2-D
display_name: Neural2 D (Female)
service: google
sample_url: false
- id: 94
name: en-IN-Standard-A
display_name: Standard A (Female)
service: google
sample_url: false
- id: 95
name: en-IN-Standard-B
display_name: Standard B (Male)
service: google
sample_url: false
- id: 96
name: en-IN-Standard-C
display_name: Standard C (Male)
service: google
sample_url: false
- id: 97
name: en-IN-Standard-D
display_name: Standard D (Female)
service: google
sample_url: false
- id: 98
name: en-IN-Standard-E
display_name: Standard E (Female)
service: google
sample_url: false
- id: 99
name: en-IN-Standard-F
display_name: Standard F (Male)
service: google
sample_url: false
- id: 100
name: en-IN-Wavenet-A
display_name: Wavenet A (Female)
service: google
sample_url: false
- id: 101
name: en-IN-Wavenet-B
display_name: Wavenet B (Male)
service: google
sample_url: false
- id: 102
name: en-IN-Wavenet-C
display_name: Wavenet C (Male)
service: google
sample_url: false
- id: 103
name: en-IN-Wavenet-D
display_name: Wavenet D (Female)
service: google
sample_url: false
- id: 104
name: en-IN-Wavenet-E
display_name: Wavenet E (Female)
service: google
sample_url: false
- id: 105
name: en-IN-Wavenet-F
display_name: Wavenet F (Male)
service: google
sample_url: false
- id: 172
name: f8f5f1b2-f02d-4d8e-a40d-fd850a487b3d
display_name: Kiara - Joyful Woman
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/172/sample_audio
- id: 173
name: d7e54830-4754-4b17-952c-bcdb7e80a2fb
display_name: Mabel - Grandma
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/173/sample_audio
- id: 174
name: e00d0e4c-a5c8-443f-a8a3-473eb9a62355
display_name: Zeke - Friendly Sidekick
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/174/sample_audio
- id: 175
name: 42b39f37-515f-4eee-8546-73e841679c1d
display_name: James - Navigator
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/175/sample_audio
- id: 176
name: a38e4e85-e815-43ab-acf1-907c4688dd6c
display_name: Lindsey - Relaxed Rep
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/176/sample_audio
- id: 177
name: 41534e16-2966-4c6b-9670-111411def906
display_name: Clarence - Newsman
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/177/sample_audio
- id: 178
name: f31cc6a7-c1e8-4764-980c-60a361443dd1
display_name: Olivia - Sunny Woman
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/178/sample_audio
- id: 179
name: 21b81c14-f85b-436d-aff5-43f2e788ecf8
display_name: Riley - Chill Friend
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/179/sample_audio
- id: 180
name: 1259b7e3-cb8a-43df-9446-30971a46b8b0
display_name: Devansh - Warm Support Agent
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/180/sample_audio
- id: 181
name: 9cebb910-d4b7-4a4a-85a4-12c79137724c
display_name: Aarti - Conversationalist
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/181/sample_audio
- id: 182
name: 4df027cb-2920-4a1f-8c34-f21529d5c3fe
display_name: Carson - Friendly Support
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/182/sample_audio
- id: 183
name: 0418348a-0ca2-4e90-9986-800fb8b3bbc0
display_name: Antoine - Stern Man
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/183/sample_audio
- id: 184
name: 1fc31370-81b1-4588-9c1a-f93793c6e01d
display_name: Carlo - Roman Guide
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/184/sample_audio
- id: 185
name: 87bc56aa-ab01-4baa-9071-77d497064686
display_name: Jordan - Chill Pal
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/185/sample_audio
- id: 186
name: bec003e2-3cb3-429c-8468-206a393c67ad
display_name: Parvati - Friendly Supporter
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/186/sample_audio
- id: 187
name: f6141af3-5f94-418c-80ed-a45d450e7e2e
display_name: Priya - Trusted Operator
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/187/sample_audio
- id: 188
name: 8985388c-1332-4ce7-8d55-789628aa3df4
display_name: Robyn - Storycrafter
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/188/sample_audio
- id: 189
name: 79743797-2087-422f-8dc7-86f9efca85f1
display_name: Fran - Confident Young Professional
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/189/sample_audio
- id: 190
name: d718e944-b313-4998-b011-d1cc078d4ef3
display_name: Liv - Casual Friend
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/190/sample_audio
- id: 191
name: 043cfc81-d69f-4bee-ae1e-7862cb358650
display_name: Amelia - Instructor
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/191/sample_audio
- id: 192
name: 1d3ba41a-96e6-44ad-aabb-9817c56caa68
display_name: Mia - Agent
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/192/sample_audio
- id: 193
name: 38aabb6a-f52b-4fb0-a3d1-988518f4dc06
display_name: Alina - Engaging Assistant
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/193/sample_audio
- id: 194
name: 82a7fc13-2927-4e42-9b8a-bb1f9e506521
display_name: Tomek - Casual Companion
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/194/sample_audio
- id: 195
name: c8605446-247c-4d39-acd4-8f4c28aa363c
display_name: Edith - Matriarch
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/195/sample_audio
- id: 196
name: f114a467-c40a-4db8-964d-aaba89cd08fa
display_name: Miles - Yogi
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/196/sample_audio
- id: 197
name: 607167f6-9bf2-473c-accc-ac7b3b66b30b
display_name: Brenda - Host
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/197/sample_audio
- id: 198
name: 064b17af-d36b-4bfb-b003-be07dba1b649
display_name: Tatiana - Friendly Storyteller
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/198/sample_audio
- id: 199
name: cccc21e8-5bcf-4ff0-bc7f-be4e40afc544
display_name: Avery - Gaming Girl
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/199/sample_audio
- id: 200
name: c0c374aa-09be-42d9-9828-4d2d7df86962
display_name: Isabel - Teacher
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/200/sample_audio
- id: 201
name: 55deba52-bc73-4481-ab69-9c8831c8a7c3
display_name: Camille - Friendly Expert
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/201/sample_audio
- id: 202
name: bd9120b6-7761-47a6-a446-77ca49132781
display_name: Owen - Tutorial Man
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/202/sample_audio
- id: 203
name: 701a96e1-7fdd-4a6c-a81e-a4a450403599
display_name: Rowan - Team Leader
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/203/sample_audio
- id: 204
name: 1cf751f6-8749-43ab-98bd-230dd633abdb
display_name: Ana Paula - Marketer
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/204/sample_audio
- id: 205
name: 3f4ade23-6eb4-4279-ab05-6a144947c4d5
display_name: Karin - Companion
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/205/sample_audio
- id: 206
name: 8832a0b5-47b2-4751-bb22-6a8e2149303d
display_name: French Narrator Lady
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/206/sample_audio
- id: 207
name: 3e1ed423-17e5-4773-b87c-25b031106e41
display_name: Paul - Straight Talker
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/207/sample_audio
- id: 208
name: 2695b6b5-5543-4be1-96d9-3967fb5e7fec
display_name: Agustin - Clear Storyteller
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/208/sample_audio
- id: 209
name: 700d1ee3-a641-4018-ba6e-899dcadc9e2b
display_name: Luana - Public Speaker
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/209/sample_audio
- id: 210
name: 996a8b96-4804-46f0-8e05-3fd4ef1a87cd
display_name: Darla - Resolution Agent
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/210/sample_audio
- id: 211
name: da4a4eff-3b7e-4846-8f70-f075ff61222c
display_name: Callum - Brand Spokesperson
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/211/sample_audio
- id: 212
name: fb26447f-308b-471e-8b00-8e9f04284eb5
display_name: Thistle - Troublemaker
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/212/sample_audio
- id: 213
name: bf991597-6c13-47e4-8411-91ec2de5c466
display_name: Carol - Task Coach
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/213/sample_audio
- id: 214
name: 5c3c89e5-535f-43ef-b14d-f8ffe148c1f0
display_name: French Narrator Man
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/214/sample_audio
- id: 215
name: ab7c61f5-3daa-47dd-a23b-4ac0aac5f5c3
display_name: Friendly French Man
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/215/sample_audio
- id: 216
name: f91ab3e6-5071-4e15-b016-cde6f2bcd222
display_name: Aadhya - Soother
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/216/sample_audio
- id: 217
name: e07c00bc-4134-4eae-9ea4-1a55fb45746b
display_name: Brooke - Big Sister
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/217/sample_audio
- id: 218
name: 228fca29-3a0a-435c-8728-5cb483251068
display_name: Kiefer
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/218/sample_audio
- id: 219
name: ec1e269e-9ca0-402f-8a18-58e0e022355a
display_name: Ariana
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/219/sample_audio
- id: 220
name: 5cad89c9-d88a-4832-89fb-55f2f16d13d3
display_name: Brandon
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/220/sample_audio
- id: 221
name: 03496517-369a-4db1-8236-3d3ae459ddf7
display_name: Calypso - ASMR Lady
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/221/sample_audio
- id: 222
name: e8e5fffb-252c-436d-b842-8879b84445b6
display_name: Cathy - Coworker
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/222/sample_audio
- id: 223
name: f786b574-daa5-4673-aa0c-cbe3e8534c02
display_name: Katie - Friendly Fixer
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/223/sample_audio
- id: 224
name: 6ccbfb76-1fc6-48f7-b71d-91ac6298247b
display_name: Tessa
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/224/sample_audio
- id: 225
name: 66c6b81c-ddb7-4892-bdd5-19b5a7be38e7
display_name: Dorothy
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/225/sample_audio
- id: 226
name: w99aEsEd2KhfXwCmjAn4
display_name: Jordan - Kind and Friendly
service: eleven_labs
sample_url: false
- id: 227
name: 2b568345-1d48-4047-b25f-7baccf842eb0
display_name: Yumiko - Friendly Agent
service: cartesia
sample_url: >-
https://192d-2401-4900-8f60-ac89-8959-6836-5aed-73c7.ngrok-free.app/web/content/bot.voice/227/sample_audio
- id: 228
name: 498e7f37-7fa3-4e2c-b8e2-8b6e9276f956
display_name: Aiko - Calming Voice
service: cartesia
sample_url: >-
https://192d-2401-4900-8f60-ac89-8959-6836-5aed-73c7.ngrok-free.app/web/content/bot.voice/228/sample_audio
- id: 229
name: 31c55968-a9f4-4115-8831-3a16952179c8
display_name: Ayumi - Sales Guide
service: cartesia
sample_url: >-
https://192d-2401-4900-8f60-ac89-8959-6836-5aed-73c7.ngrok-free.app/web/content/bot.voice/229/sample_audio
- id: 230
name: 62ae83ad-4f6a-430b-af41-a9bede9286ca
display_name: Gemma - Decisive Agent
service: cartesia
sample_url: >-
https://192d-2401-4900-8f60-ac89-8959-6836-5aed-73c7.ngrok-free.app/web/content/bot.voice/230/sample_audio
- id: 231
name: 2f251ac3-89a9-4a77-a452-704b474ccd01
display_name: Lucy - Capable Coordinator
service: cartesia
sample_url: >-
https://192d-2401-4900-8f60-ac89-8959-6836-5aed-73c7.ngrok-free.app/web/content/bot.voice/231/sample_audio
- id: 232
name: 97e7d7a9-dfaa-4758-a936-f5f844ac34cc
display_name: Fuji - Positive Colleague
service: cartesia
sample_url: >-
https://192d-2401-4900-8f60-ac89-8959-6836-5aed-73c7.ngrok-free.app/web/content/bot.voice/232/sample_audio
- id: 233
name: 9e7ef2cf-b69c-46ac-9e35-bbfd73ba82af
display_name: Ren - High-Energy Character
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/233/sample_audio
- id: 234
name: a759ecc5-ac21-487e-88c7-288bdfe76999
display_name: Daichi - Baritone Narrator
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/234/sample_audio
- id: 235
name: 7c58f4a4-a72c-42fa-a503-41b9408820f3
display_name: "Inès\t- Poised Communicator"
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/235/sample_audio
- id: 236
name: 791d5162-d5eb-40f0-8189-f19db44611d8
display_name: Ayush - Friendly Neighbor
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/236/sample_audio
- id: 237
name: db6b0ed5-d5d3-463d-ae85-518a07d3c2b4
display_name: Skylar - Friendly Guide
service: cartesia
sample_url: http://localhost:8069/web/content/bot.voice/237/sample_audio
total_services: 44
total_voices: 156
```
**Python SDK**
```python
# List all providers (comprehensive - services and voices)
all_providers = client.providers.list_all()
print(all_providers)
# Returns: {'services': {...}, 'voices': {...}, 'total_services': 12, 'total_voices': 123}
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/providers/all" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List LLM providers (/docs/api-reference/providers/listLLMProviders)
> Retrieve all available Large Language Model providers.
**GET** `/providers/llms`
Retrieve all available Large Language Model providers.
```yaml
operationId: listLLMProviders
responses:
'200':
description: LLM providers.
content:
application/json:
schema:
type: object
properties:
llms:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string
provider_name:
oneOf:
- type: string
- type: boolean
description: Brand of the underlying service (e.g. `azure` for LLMs). `false` when not set.
is_premium:
type: boolean
service_type:
type: string
enum:
- LLM
- STT
- TTS
- other
is_active:
type: boolean
total:
type: integer
example:
llms:
- id: 17
name: azure-gpt-4.1-mini
provider_name: azure
is_premium: false
service_type: LLM
is_active: true
- id: 8
name: gemini-2.5-flash
provider_name: google
is_premium: false
service_type: LLM
is_active: true
total: 13
```
**Python SDK**
```python
# List all LLM providers
llms = client.providers.list_llms()
print(llms)
# Returns: {'llms': [...], 'total': 5}
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/providers/llms" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List STT providers (/docs/api-reference/providers/listSTTProviders)
> Retrieve all Speech-to-Text providers.
**GET** `/providers/stt`
Retrieve all Speech-to-Text providers.
```yaml
operationId: listSTTProviders
responses:
'200':
description: STT providers.
content:
application/json:
schema:
type: object
properties:
stt:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string
provider_name:
oneOf:
- type: string
- type: boolean
description: Brand of the underlying service (e.g. `azure` for LLMs). `false` when not set.
is_premium:
type: boolean
service_type:
type: string
enum:
- LLM
- STT
- TTS
- other
is_active:
type: boolean
total:
type: integer
example:
stt:
- id: 2
name: deepgram_stream
provider_name: false
is_premium: false
service_type: STT
is_active: true
- id: 5
name: Azure
provider_name: false
is_premium: false
service_type: STT
is_active: true
total: 4
```
**Python SDK**
```python
# List all STT providers
stt_providers = client.providers.list_stt()
print(stt_providers)
# Returns: {'stt': [...], 'total': 3}
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/providers/stt" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List TTS providers (/docs/api-reference/providers/listTTSProviders)
> Retrieve all Text-to-Speech providers.
**GET** `/providers/tts`
Retrieve all Text-to-Speech providers.
```yaml
operationId: listTTSProviders
responses:
'200':
description: TTS providers.
content:
application/json:
schema:
type: object
properties:
tts:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string
provider_name:
oneOf:
- type: string
- type: boolean
description: Brand of the underlying service (e.g. `azure` for LLMs). `false` when not set.
is_premium:
type: boolean
service_type:
type: string
enum:
- LLM
- STT
- TTS
- other
is_active:
type: boolean
total:
type: integer
example:
tts:
- id: 32
name: cartesia
provider_name: false
is_premium: false
service_type: TTS
is_active: true
- id: 30
name: google
provider_name: false
is_premium: false
service_type: TTS
is_active: true
total: 4
```
**Python SDK**
```python
# List all TTS providers
tts_providers = client.providers.list_tts()
print(tts_providers)
# Returns: {'tts': [...], 'total': 4}
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/providers/tts" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List voices (/docs/api-reference/providers/listVoices)
> Retrieve voices with filtering and pagination support. ElevenLabs
supports advanced filtering by name, language, accent, and gender.
Other providers support basic pagination only.
**GET** `/providers/voices`
Retrieve voices with filtering and pagination support. ElevenLabs
supports advanced filtering by name, language, accent, and gender.
Other providers support basic pagination only.
```yaml
operationId: listVoices
parameters:
- name: provider
in: query
schema:
type: string
enum:
- eleven_labs
- google
- deepgram
- cartesia
- sarvam
- name: search
in: query
schema:
type: string
description: ElevenLabs only.
- name: language
in: query
schema:
type: string
description: ElevenLabs only.
- name: accent
in: query
schema:
type: string
description: ElevenLabs only.
- name: gender
in: query
schema:
type: string
enum:
- male
- female
description: ElevenLabs only.
- name: page
in: query
schema:
type: integer
default: 1
- name: page_size
in: query
schema:
type: integer
default: 30
maximum: 100
responses:
'200':
description: Voices and filter metadata.
content:
application/json:
schema:
type: object
properties:
voices:
type: array
items:
type: object
properties:
id:
oneOf:
- type: integer
- type: 'null'
name:
type: string
display_name:
type: string
service:
type: string
sample_url:
type: string
format: uri
tags:
type: array
items:
type: string
source:
type: string
description: Origin marker (e.g. `external` for ElevenLabs community voices).
external_id:
type: string
description: Identifier on the upstream provider.
description:
type: string
total:
type: integer
page:
type: integer
page_size:
type: integer
filters_applied:
type: object
description: >-
Echoes the filter parameters the request applied. `null` for any filter that wasn't
sent.
properties:
provider:
type: string
nullable: true
search:
type: string
nullable: true
language:
type: string
nullable: true
accent:
type: string
nullable: true
gender:
type: string
nullable: true
example:
voices:
- id: 1
name: aura-luna-en
display_name: luna
service: deepgram
sample_url: >-
https://res.cloudinary.com/deepgram/video/upload/v1709565351/aura/luna_docs_clom0e.wav
tags:
- feminine
- Young Adult
- en-us
- American
- Friendly, Natural, Engaging
- IVR
total: 30
page: 1
page_size: 30
filters_applied:
provider: null
search: null
language: null
accent: null
gender: null
```
**Python SDK**
```python
# Basic usage - list all voices with default pagination
voices = client.providers.list_voices()
print(voices)
# Returns: {'voices': [...], 'total': 123, 'page': 1, 'page_size': 30, 'filters_applied': False}
# With pagination
voices = client.providers.list_voices(page=2, page_size=50)
print(voices)
# Filter by specific provider (only supports basic pagination)
voices = client.providers.list_voices(provider='eleven_labs', page=1, page_size=20)
print(voices)
# Advanced filtering (ElevenLabs only)
voices = client.providers.list_voices(
provider='eleven_labs',
search='professional',
language='en',
accent='american',
gender='male',
page=1,
page_size=15
)
print(voices)
# Search by voice name/description
voices = client.providers.list_voices(
provider='eleven_labs',
search='excited',
gender='female'
)
print(voices)
# Filter by language
voices = client.providers.list_voices(
provider='eleven_labs',
language='en'
)
print(voices)
# Filter by accent
voices = client.providers.list_voices(
provider='eleven_labs',
accent='british'
)
print(voices)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/providers/voices" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Create simulation (/docs/api-reference/simulation/createSimulation)
> Create a new test simulation with scenarios.
**POST** `/simulations`
Create a new test simulation with scenarios.
```yaml
operationId: createSimulation
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
- agent_id
properties:
name:
type: string
description: Name of the simulation.
example: My Simulation
agent_id:
type: integer
description: ID of the agent to test.
example: 158910
number_of_call_to_make:
type: integer
default: 1
minimum: 1
maximum: 3
description: Number of calls to make per scenario (default 1, max 3).
concurrent_call_count:
type: integer
default: 3
minimum: 1
maximum: 3
description: Number of concurrent calls to run (default 3, max 3).
max_call_duration_in_minutes:
type: integer
default: 3
minimum: 1
maximum: 10
description: Maximum duration for each call in minutes (default 3, max 10).
scenarios:
type: array
description: List of test scenarios to execute.
items:
type: object
required:
- name
- description
- expected_result
properties:
name:
type: string
description: Name of the test scenario.
example: Polite cancellation
description:
type: string
description: Detailed instructions for the test scenario.
example: Ask to cancel a subscription, but be friendly.
expected_result:
type: string
description: Expected outcome or behavior from the agent.
example: Agent acknowledges the request and routes to retention.
selected_voices:
type: array
description: >-
Voice configurations for the test calls. If multiple voices are selected, the
agent randomly picks one per call per scenario.
items:
type: object
required:
- id
- provider
properties:
id:
type: string
description: Voice ID from the provider.
provider:
type: string
enum:
- eleven_labs
- play_ht
- deepgram
- cartesia
- rime
example: eleven_labs
responses:
'200':
description: Simulation created.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
simulation:
type: object
description: A test simulation for an agent.
properties:
id:
type: integer
example: 772
name:
type: string
bot_id:
type: object
description: The agent under test.
properties:
id:
type: integer
name:
type: string
status:
type: string
enum:
- Draft
- Pending
- In Progress
- Calculating Summary
- Completed
- Stopped
number_of_call_to_make:
type: integer
concurrent_call_count:
type: integer
max_call_duration_in_minutes:
type: integer
scenarios_ids:
type: array
description: Scenario records attached to this simulation.
items:
type: object
additionalProperties: true
what_went_wrong:
oneOf:
- type: string
- type: boolean
suggestions_for_improvement:
oneOf:
- type: string
- type: boolean
prompt_suggestion:
oneOf:
- type: string
- type: boolean
is_auto_prompt_suggestions_applied:
type: boolean
how_many_scenario_to_generate:
type: integer
summary:
oneOf:
- type: string
- type: boolean
analyticsData:
type: object
properties:
Positive:
type: integer
Negative:
type: integer
Neutral:
type: integer
total_simulation_remaining_records:
type: integer
total_simulation_in_progress_records:
type: integer
total_simulation_finished_records:
type: integer
total_records:
type: integer
progress:
type: array
minItems: 1
maxItems: 1
items:
type: integer
description: >-
Single-element array containing the progress percentage (0-100). Quirky shape
preserved for backwards compatibility.
example:
- 0
simulation_call_recording:
type: array
items:
type: object
additionalProperties: true
can_stop:
type: boolean
active_calls_count:
type: integer
create_date:
type: string
example: 05/06/2026 13:31:54
example:
success: true
simulation:
id: 456
name: Customer Support Test
bot_id:
id: 1234
name: Customer Support Agent
scenarios_ids: []
status: Draft
number_of_call_to_make: 1
concurrent_call_count: 3
max_call_duration_in_minutes: 3
what_went_wrong: false
suggestions_for_improvement: false
prompt_suggestion: false
is_auto_prompt_suggestions_applied: false
how_many_scenario_to_generate: 0
summary: false
analyticsData:
Positive: 0
Negative: 0
Neutral: 0
total_simulation_remaining_records: 0
total_simulation_in_progress_records: 0
total_simulation_finished_records: 0
total_records: 0
progress:
- 0
create_date: 05/08/2026 09:10:29
simulation_call_recording: []
can_stop: false
active_calls_count: 0
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Create a basic simulation
response = client.simulation.create(
name="Restaurant Order Taking Test",
agent_id=123,
number_of_call_to_make=1,
concurrent_call_count=3,
max_call_duration_in_minutes=3,
scenarios=[
{
"name": "Order Pizza",
"description": "1. Act as a customer wanting to order pizza\n2. Ask for menu items\n3. Order a large pepperoni pizza\n4. Provide contact details\n5. End call with thank you",
"expected_result": "Order should be placed successfully and confirmation provided",
"selected_voices": [
{"id": "voice_id_1", "provider": "eleven_labs"},
{"id": "voice_id_2", "provider": "play_ht"}
]
}
]
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/simulations" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Delete simulation (/docs/api-reference/simulation/deleteSimulation)
> Permanently delete a simulation.
**DELETE** `/simulations/{simulation_id}`
Permanently delete a simulation.
```yaml
operationId: deleteSimulation
responses:
'200':
description: Simulation deleted.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
example:
success: true
message: Simulation deleted successfully
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Delete a simulation
simulation_id = 456
response = client.simulation.delete(simulation_id)
print(response)
```
**curl**
```bash
curl -X DELETE "https://backend.omnidim.io/api/v1/simulations/{simulation_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Enhance prompt (/docs/api-reference/simulation/enhancePrompt)
> Generate prompt-improvement suggestions for a completed simulation.
**POST** `/simulations/{simulation_id}/enhance-prompt`
Generate prompt-improvement suggestions for a completed simulation.
```yaml
operationId: enhancePrompt
parameters:
- name: simulation_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: |
Enhanced prompt suggestions. The simulation must be in
`Completed` status — otherwise the API returns 400.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
previous_context:
type: array
description: The agent's existing context-breakdown sections.
items:
type: object
properties:
title:
type: string
prompt:
type: string
prompt_breakdown:
type: array
description: Suggested replacement sections, structured the same way.
items:
type: object
properties:
title:
type: string
prompt:
type: string
example:
success: true
previous_context:
- title: Purpose
prompt: This agent helps customers with product inquiries and support issues.
prompt_breakdown:
- title: Purpose
prompt: >-
This agent helps customers with product inquiries, support issues, and frequently
asked product questions.
'400':
description: >
Simulation is not in `Completed` status. Body:
`{"error": "invalid_state", "error_description": "Enhanced prompt suggestions are only
available for completed simulations"}`.
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Get enhanced prompt suggestions
simulation_id = 456
response = client.simulation.enhance_prompt(simulation_id)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/simulations/{simulation_id}/enhance-prompt" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Get simulation (/docs/api-reference/simulation/getSimulation)
> Detailed simulation information.
**GET** `/simulations/{simulation_id}`
Detailed simulation information.
```yaml
operationId: getSimulation
responses:
'200':
description: Simulation details.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
simulation:
type: object
description: A test simulation for an agent.
properties:
id:
type: integer
example: 772
name:
type: string
bot_id:
type: object
description: The agent under test.
properties:
id:
type: integer
name:
type: string
status:
type: string
enum:
- Draft
- Pending
- In Progress
- Calculating Summary
- Completed
- Stopped
number_of_call_to_make:
type: integer
concurrent_call_count:
type: integer
max_call_duration_in_minutes:
type: integer
scenarios_ids:
type: array
description: Scenario records attached to this simulation.
items:
type: object
additionalProperties: true
what_went_wrong:
oneOf:
- type: string
- type: boolean
suggestions_for_improvement:
oneOf:
- type: string
- type: boolean
prompt_suggestion:
oneOf:
- type: string
- type: boolean
is_auto_prompt_suggestions_applied:
type: boolean
how_many_scenario_to_generate:
type: integer
summary:
oneOf:
- type: string
- type: boolean
analyticsData:
type: object
properties:
Positive:
type: integer
Negative:
type: integer
Neutral:
type: integer
total_simulation_remaining_records:
type: integer
total_simulation_in_progress_records:
type: integer
total_simulation_finished_records:
type: integer
total_records:
type: integer
progress:
type: array
minItems: 1
maxItems: 1
items:
type: integer
description: >-
Single-element array containing the progress percentage (0-100). Quirky shape
preserved for backwards compatibility.
example:
- 0
simulation_call_recording:
type: array
items:
type: object
additionalProperties: true
can_stop:
type: boolean
active_calls_count:
type: integer
create_date:
type: string
example: 05/06/2026 13:31:54
example:
success: true
simulation:
id: 456
name: Customer Support Test
bot_id:
id: 1234
name: Customer Support Agent
scenarios_ids: []
status: Draft
number_of_call_to_make: 1
concurrent_call_count: 3
max_call_duration_in_minutes: 3
what_went_wrong: false
suggestions_for_improvement: false
prompt_suggestion: false
is_auto_prompt_suggestions_applied: false
how_many_scenario_to_generate: 0
summary: false
analyticsData:
Positive: 0
Negative: 0
Neutral: 0
total_simulation_remaining_records: 0
total_simulation_in_progress_records: 0
total_simulation_finished_records: 0
total_records: 0
progress:
- 0
create_date: 05/08/2026 09:10:29
simulation_call_recording: []
can_stop: false
active_calls_count: 0
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Get details of a specific simulation
simulation_id = 456
response = client.simulation.get(simulation_id)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/simulations/{simulation_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# List simulations (/docs/api-reference/simulation/listSimulations)
> Retrieve simulations with pagination.
**GET** `/simulations`
Retrieve simulations with pagination.
```yaml
operationId: listSimulations
parameters:
- name: pageno
in: query
schema:
type: integer
default: 1
- name: pagesize
in: query
schema:
type: integer
default: 10
maximum: 150
responses:
'200':
description: Paginated list of simulations.
content:
application/json:
schema:
type: object
properties:
records:
type: array
items:
type: object
description: A test simulation for an agent.
properties:
id:
type: integer
example: 772
name:
type: string
bot_id:
type: object
description: The agent under test.
properties:
id:
type: integer
name:
type: string
status:
type: string
enum:
- Draft
- Pending
- In Progress
- Calculating Summary
- Completed
- Stopped
number_of_call_to_make:
type: integer
concurrent_call_count:
type: integer
max_call_duration_in_minutes:
type: integer
scenarios_ids:
type: array
description: Scenario records attached to this simulation.
items:
type: object
additionalProperties: true
what_went_wrong:
oneOf:
- type: string
- type: boolean
suggestions_for_improvement:
oneOf:
- type: string
- type: boolean
prompt_suggestion:
oneOf:
- type: string
- type: boolean
is_auto_prompt_suggestions_applied:
type: boolean
how_many_scenario_to_generate:
type: integer
summary:
oneOf:
- type: string
- type: boolean
analyticsData:
type: object
properties:
Positive:
type: integer
Negative:
type: integer
Neutral:
type: integer
total_simulation_remaining_records:
type: integer
total_simulation_in_progress_records:
type: integer
total_simulation_finished_records:
type: integer
total_records:
type: integer
progress:
type: array
minItems: 1
maxItems: 1
items:
type: integer
description: >-
Single-element array containing the progress percentage (0-100). Quirky shape
preserved for backwards compatibility.
example:
- 0
simulation_call_recording:
type: array
items:
type: object
additionalProperties: true
can_stop:
type: boolean
active_calls_count:
type: integer
create_date:
type: string
example: 05/06/2026 13:31:54
total_records:
type: integer
example:
records: []
total_records: 0
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# List all simulations with pagination
response = client.simulation.list(pageno=1, pagesize=10)
print(response)
```
**curl**
```bash
curl -X GET "https://backend.omnidim.io/api/v1/simulations" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Start simulation (/docs/api-reference/simulation/startSimulation)
> Begin running a simulation. Optionally update scenarios at start time (same shape as Update simulation).
**POST** `/simulations/{simulation_id}/start`
Begin running a simulation. Optionally update scenarios at start time (same shape as Update simulation).
```yaml
operationId: startSimulation
parameters:
- name: simulation_id
in: path
required: true
schema:
type: integer
requestBody:
content:
application/json:
schema:
type: object
properties:
scenarios:
type: array
description: Optional array of scenarios to update before starting.
items:
type: object
required:
- name
- description
- expected_result
properties:
id:
type: integer
description: Include this to update an existing scenario; omit it to add a new one.
name:
type: string
description:
type: string
description: Updated instructions for the test scenario.
expected_result:
type: string
description: Updated expected outcome from the agent.
selected_voices:
type: array
description: Updated voice configurations for the test calls.
items:
type: object
required:
- id
- provider
properties:
id:
type: string
description: Voice ID from the provider.
provider:
type: string
enum:
- eleven_labs
- play_ht
- deepgram
- cartesia
- rime
responses:
'200':
description: Simulation started.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
simulation:
type: object
description: A test simulation for an agent.
properties:
id:
type: integer
example: 772
name:
type: string
bot_id:
type: object
description: The agent under test.
properties:
id:
type: integer
name:
type: string
status:
type: string
enum:
- Draft
- Pending
- In Progress
- Calculating Summary
- Completed
- Stopped
number_of_call_to_make:
type: integer
concurrent_call_count:
type: integer
max_call_duration_in_minutes:
type: integer
scenarios_ids:
type: array
description: Scenario records attached to this simulation.
items:
type: object
additionalProperties: true
what_went_wrong:
oneOf:
- type: string
- type: boolean
suggestions_for_improvement:
oneOf:
- type: string
- type: boolean
prompt_suggestion:
oneOf:
- type: string
- type: boolean
is_auto_prompt_suggestions_applied:
type: boolean
how_many_scenario_to_generate:
type: integer
summary:
oneOf:
- type: string
- type: boolean
analyticsData:
type: object
properties:
Positive:
type: integer
Negative:
type: integer
Neutral:
type: integer
total_simulation_remaining_records:
type: integer
total_simulation_in_progress_records:
type: integer
total_simulation_finished_records:
type: integer
total_records:
type: integer
progress:
type: array
minItems: 1
maxItems: 1
items:
type: integer
description: >-
Single-element array containing the progress percentage (0-100). Quirky shape
preserved for backwards compatibility.
example:
- 0
simulation_call_recording:
type: array
items:
type: object
additionalProperties: true
can_stop:
type: boolean
active_calls_count:
type: integer
create_date:
type: string
example: 05/06/2026 13:31:54
example:
success: true
message: Simulation started successfully
simulation:
id: 456
name: Customer Support Test
status: Pending
number_of_call_to_make: 1
concurrent_call_count: 3
max_call_duration_in_minutes: 3
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Start a simulation
simulation_id = 456
response = client.simulation.start(simulation_id)
print(response)
# Start with updated scenarios
response = client.simulation.start(
simulation_id,
scenarios=[
{
"id": 789,
"name": "Updated Order Pizza",
"description": "Updated instructions...",
"expected_result": "Updated expected behavior...",
"selected_voices": [...]
}
]
)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/simulations/{simulation_id}/start" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Stop simulation (/docs/api-reference/simulation/stopSimulation)
> Stop a running simulation.
**POST** `/simulations/{simulation_id}/stop`
Stop a running simulation.
```yaml
operationId: stopSimulation
parameters:
- name: simulation_id
in: path
required: true
schema:
type: integer
responses:
'200':
description: |
Stop attempted. `success: true` when the simulation was
running and is now stopped; `success: false` (still HTTP
200) when the simulation isn't in a stoppable state — the
`message` explains why. `disconnect_results` is only
present on the success path.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
disconnect_results:
type: object
description: Per-recording stop counts. Only present when `success` is true.
properties:
successful_disconnects:
type: integer
failed_disconnects:
type: integer
pending_stopped:
type: integer
example:
success: true
message: Simulation stopped successfully
disconnect_results:
successful_disconnects: 0
failed_disconnects: 0
pending_stopped: 0
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Stop a running simulation
simulation_id = 456
response = client.simulation.stop(simulation_id)
print(response)
```
**curl**
```bash
curl -X POST "https://backend.omnidim.io/api/v1/simulations/{simulation_id}/stop" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```
# Update simulation (/docs/api-reference/simulation/updateSimulation)
> Update an existing simulation. Pass the full `scenarios` array (existing entries you want to keep plus any changes).
**PUT** `/simulations/{simulation_id}`
Update an existing simulation. Pass the full `scenarios` array (existing entries you want to keep plus any changes).
```yaml
operationId: updateSimulation
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: Name of the simulation for identification.
agent_id:
type: integer
description: ID of the agent to test.
number_of_call_to_make:
type: integer
minimum: 1
maximum: 3
description: Number of calls to make per scenario (default 1, max 3).
concurrent_call_count:
type: integer
minimum: 1
maximum: 3
description: Number of concurrent calls to run (default 3, max 3).
max_call_duration_in_minutes:
type: integer
minimum: 1
maximum: 10
description: Maximum duration for each call in minutes (default 3, max 10).
scenarios:
type: array
description: >-
Full scenario list. Include existing scenarios you want to keep, plus any new or
updated ones.
items:
type: object
required:
- name
- description
- expected_result
properties:
id:
type: integer
description: Include this to update an existing scenario; omit it to add a new one.
name:
type: string
description: Name of the test scenario.
description:
type: string
description: Updated instructions for the test scenario.
expected_result:
type: string
description: Updated expected outcome from the agent.
selected_voices:
type: array
description: Updated voice configurations for the test calls.
items:
type: object
required:
- id
- provider
properties:
id:
type: string
description: Voice ID from the provider.
provider:
type: string
enum:
- eleven_labs
- play_ht
- deepgram
- cartesia
- rime
responses:
'200':
description: Updated simulation.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
simulation:
type: object
description: A test simulation for an agent.
properties:
id:
type: integer
example: 772
name:
type: string
bot_id:
type: object
description: The agent under test.
properties:
id:
type: integer
name:
type: string
status:
type: string
enum:
- Draft
- Pending
- In Progress
- Calculating Summary
- Completed
- Stopped
number_of_call_to_make:
type: integer
concurrent_call_count:
type: integer
max_call_duration_in_minutes:
type: integer
scenarios_ids:
type: array
description: Scenario records attached to this simulation.
items:
type: object
additionalProperties: true
what_went_wrong:
oneOf:
- type: string
- type: boolean
suggestions_for_improvement:
oneOf:
- type: string
- type: boolean
prompt_suggestion:
oneOf:
- type: string
- type: boolean
is_auto_prompt_suggestions_applied:
type: boolean
how_many_scenario_to_generate:
type: integer
summary:
oneOf:
- type: string
- type: boolean
analyticsData:
type: object
properties:
Positive:
type: integer
Negative:
type: integer
Neutral:
type: integer
total_simulation_remaining_records:
type: integer
total_simulation_in_progress_records:
type: integer
total_simulation_finished_records:
type: integer
total_records:
type: integer
progress:
type: array
minItems: 1
maxItems: 1
items:
type: integer
description: >-
Single-element array containing the progress percentage (0-100). Quirky shape
preserved for backwards compatibility.
example:
- 0
simulation_call_recording:
type: array
items:
type: object
additionalProperties: true
can_stop:
type: boolean
active_calls_count:
type: integer
create_date:
type: string
example: 05/06/2026 13:31:54
example:
success: true
simulation:
id: 456
name: Customer Support Test (Updated)
bot_id:
id: 1234
name: Customer Support Agent
status: Draft
number_of_call_to_make: 1
concurrent_call_count: 3
max_call_duration_in_minutes: 5
```
**Python SDK**
```python
from omnidimension import Client
client = Client(api_key)
# Update an existing simulation
simulation_id = 456
update_data = {
"name": "Updated Restaurant Test",
"max_call_duration_in_minutes": 5,
"scenarios": [
{
"name": "Updated Order Pizza",
"description": "Updated instructions...",
"expected_result": "Updated expected behavior..."
}
]
}
response = client.simulation.update(simulation_id, update_data)
print(response)
```
**curl**
```bash
curl -X PUT "https://backend.omnidim.io/api/v1/simulations/{simulation_id}" \
-H "Authorization: Bearer $OMNIDIM_API_KEY"
```