# Documentation (/docs) > Build powerful AI voice agents with OmniDimension. Guides, API reference, and integration recipes for the entire platform.
Quickstart
First request in five minutes.
API reference
Interactive playground for every endpoint.
Examples
Real-world builds to learn from and adapt.
## 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. Bulk outbound call best practices ## 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 Welcome message configuration ### 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 Knowledge base integration ## 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 Silence timeout settings ### 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 Language model settings ### 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 Voice selection ### 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 Background noise simulation ## 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 Post-call handling ## 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 Timezone configuration #### Retry strategy [#retry-strategy] * Configure maximum retry attempts per number (typically 2–3 times) * Space retries appropriately: 24–48 hours between attempts Auto-retry configuration ## 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. Analysis and optimization ### 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 Step 1: Campaign Details ### 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 Step 2: Enable Dynamic Mode ### 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 Step 3: Scheduling and retry ### 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 Step 4: Review and create ## 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 Campaign status flow ## 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 integration details ### 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] Deploy agent with phone number ### Agent successfully attached [#agent-successfully-attached] Agent attached confirmation ## 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 Step 1: Campaign details ### 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 Step 2: Upload CSV #### 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 Step 3: Campaign settings #### Configuration options [#configuration-options] Detailed configuration #### 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 Step 4: Review and create ## 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 Campaign management interface ## 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. Overview of conversational flow ### 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 management ### 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 Section configuration ### Welcome message [#welcome-message] You can add or edit the welcome message from the conversation flow section. The welcome message is currently static. Welcome message ### 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 Upload or select files from agent editor ### 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 Dashboard file upload Link uploaded files to 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. Post-Call Delivery Guide ## 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. Email delivery configuration ## 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. Salesforce integration configuration ## 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. HubSpot integration configuration ## 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. Slack integration configuration ## 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. Webhook configuration ### 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 Recent Calls view from the Agent Dashboard ### 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 Main dashboard showing all agent logs Detailed log analytics and filters ### 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 Go to Settings page Update 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 Timezone Notification Update Timezone Modal # 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. The Cloned Voices page in the sidebar ### 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) Fill in the name, language, and upload your audio sample ### 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. Your cloned voice is ready and available for use ### 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 Choose your cloned voice from the Cloned Voices tab in the agent voice picker # 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 Click on Web Bot Widget from Deploy menu Copy the widget script from the deployment panel Paste script into your site before closing body tag Web widget demo ### 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 Edit title, logo, position, and more ### 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. Enabling Web Search from the agent 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. Healthcare appointment booking agent overview 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. Writing the initial prompt ### 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. Answering clarifying questions ### 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. Automatic agent creation ### 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 Customizing agent details ### 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 Test with chat Test with web call ### 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 Updating model Updating voice ### 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 Integration tab view Adding Google Calendar integration Attach integration view 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 Upload documents ### 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 Post-call settings ### 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 Call logs # 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. Insurance claim agent overview 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. Agent prompt configuration ### Answer clarifying questions [#answer-clarifying-questions] Complete the agent setup by answering important questions about your insurance company, claim types, and verification procedures. Configuration questions ### 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 Web call testing interface ### 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 Knowledge base configuration ### 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 Post-call settings ### 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** Speech-to-text configuration ### 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) Voice selection Behavior configuration ### 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 Make.com webhook setup Google Sheets configuration OmniDimension webhook configuration Google sheet view with sample data 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. OmniSupport agent overview 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 Web scraping data ### 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 Cal.com Integration 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.) Slack post-call delivery 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 Add Make.com webhook URL to post-call Extracted variables Make.com webhook 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. Real estate agent overview 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. API key ### 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. Recruitment screening bot overview 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. Writing the initial 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. Answering clarifying questions ### 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. Automatic agent creation ### 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 Customizing agent details ### 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 Outgoing agent Test with web call interface, with context setup ### 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 Configuring the language model Setting up voice Setting up personality ### 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 Knowledge base setup ### 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. Post-call settings ### 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** Click on Purchase Number Attach your number to the bot ### 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 Bulk call campaign setup # Restaurant agent (API) (/docs/examples/restaurant) > Build a voice agent that handles restaurant orders, reservations, and outbound marketing campaigns. Restaurant agent overview 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. API key ### 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. Travel planning agent overview 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. Agent prompt configuration ### Answer clarifying questions [#answer-clarifying-questions] Complete the agent setup by answering important questions about your travel agency, destination specialties, and lead collection procedures. Configuration questions ### 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 Knowledge base configuration ### 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 Web search configuration ### 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 Web call testing interface ### 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** Post-call settings ### 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 n8n webhook setup Webhook configuration in n8n HubSpot node in n8n Add information to HubSpot ticket ### 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. Utility bill payment agent overview 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. API key ### 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. Finding Cal.com in dashboard ### Connect Cal.com [#connect-calcom] Find the Cal.com card and click **Connect**, then configure your integration (see configuration details below). Clicking Connect ### 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. Connecting from agent edit page ## 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 Fill in integration details ## 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. Finding 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. Connecting from dashboard ### 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. Custom API config in dashboard ### 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 Adding query or body parameters ## 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. Running a test before saving integration ### 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. Custom API Airtable integration sample ## 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. Supabase custom API integration setup ### 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. Supabase custom API testing ## 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. Finding Google Calendar in dashboard ### 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. Clicking Connect ## 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) Customize meeting defaults after connecting Google Calendar ## 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. HubSpot integration setup from dashboard ### Connect HubSpot [#connect-hubspot] Find the HubSpot card and click **Connect**. Enter your integration name and description, then click **Connect with HubSpot**. HubSpot Connect Card ### Authorize via OAuth [#authorize-via-oauth] An OAuth popup will appear. Log in to your HubSpot account and grant access. HubSpot OAuth authorization flow ### 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. Salesforce integration dashboard setup ### 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. Configuration screen for Salesforce integration ### 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] Fields required for configuring the integration * **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. Finding Slack integration in dashboard ### Connect Slack [#connect-slack] Find the Slack card and click **Connect**. Configure the integration name and description, then complete the OAuth authorization. Clicking Connect ### 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. Connecting from agent edit page ## 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). Configuring the post-call webhook ### Test the connection [#test-the-connection] Click **Test Connection** to verify and inspect the payload from your automation platform. Webhook payload setup with call summary, full conversation, sentiment analysis, and extracted variables ### 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 Make.com scenario that adds call logs to an Airtable database ## 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`. API call using HTTP module ### 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. Setting up body for call dispatch ## 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**. Navigate to App Builder ### Create new app [#create-new-app] Click on **Create New App** to start building your call flow. Create New App ### 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 Voicebot Applet ### 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 Second Passthru ### 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 Hangup on 200 ### 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. Add Connect on 302 ### Configure Connect applet [#configure-connect-applet] In the connect applet, select **Primary URL** and enter `https://live.omnidim.io/call_transfer`. Configure Connect Applet ### 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 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 Answer ### 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 Passthru for No Dial ### 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. Add Hangup Applets ### 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. Save Call Flow ### 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. Attach Call Flow ## 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. Phone Numbers Section ### 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. Import Button ### 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) Import Form ### 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. Success Import ## 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 Complete call flow overview ## 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. SIP Import Button Location ### Tell us about your provider [#tell-us-about-your-provider] Select your SIP provider from the dropdown and enter your credentials. SIP Credentials Form ### 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. Initiate WhatsApp Connection ### 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 Scan WhatsApp QR Code 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 Attaching a bot to the phone number ### 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. Bot responding to a message on WhatsApp ## 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. Initiate WhatsApp Cloud Connection ### 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**. WhatsApp Cloud Credentials Form ### 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. WhatsApp Phone Numbers List ### 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 Bot attached to WhatsApp Cloud 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" ```