openapi: 3.1.0
info:
  title: OmniDimension API
  version: "1.0"
  description: |
    Public REST API for the OmniDimension voice-agent platform. Use it
    to manage agents, dispatch calls, run bulk-call campaigns, manage
    knowledge bases, attach phone numbers, run agent simulations, and
    administer reseller accounts.
  contact:
    name: OmniDimension
    url: https://omnidim.io
servers:
  - url: https://backend.omnidim.io/api/v1
    description: Production
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        Bearer token authentication. Obtain your API key from the
        OmniDimension dashboard.
  schemas:
    Pagination:
      type: object
      properties:
        page:
          type: integer
          example: 1
        page_size:
          type: integer
          example: 30
        total:
          type: integer
          example: 100
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
    ResellerDashboardMenuAccess:
      type: object
      description: |
        Reseller-managed dashboard menu access flags. Each property is
        a boolean toggle for a feature area in the child user's
        dashboard. On read endpoints, only flags the reseller
        themselves has enabled are returned (so a child cannot have a
        flag the reseller doesn't have).
      properties:
        is_bots_menu_access: { type: boolean }
        is_leads_access: { type: boolean }
        is_voice_cloning_access: { type: boolean }
        is_workflow_access: { type: boolean }
        is_asr_evaluation_menu_access: { type: boolean }
        is_train_with_call_recording_menu_access: { type: boolean }
        is_call_logs_menu_access: { type: boolean }
        is_call_simulation_menu_access: { type: boolean }
        is_omni_crm_access: { type: boolean }
        access_to_monitor_live_call: { type: boolean }
        is_whatsapp_flow_enabled: { type: boolean }
        is_billing_menu_access: { type: boolean }
        is_knowledge_base_access: { type: boolean }
        is_integration_access: { type: boolean }
        is_phone_number_access: { type: boolean }
        is_bulk_call_access: { type: boolean }
        is_analytics_access: { type: boolean }
    Agent:
      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
          description: Whether voicemail detection is on. To change it, send the nested `voicemail.enabled` field when creating or updating the agent.
        voicemail_message:
          type: string
          description: Message the agent leaves when voicemail is detected. To change it, send the nested `voicemail.message` field when creating or updating the agent.
        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
    Call:
      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 `<br/>`-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
    BulkCallSummary:
      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
    BulkCallDetail:
      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.
    KnowledgeBaseFile:
      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
    PhoneNumber:
      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
    Provider:
      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
    Voice:
      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
    VoiceDetail:
      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
    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"
    ExtractedVariable:
      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.
    AgentConfigInput:
      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?
        is_welcome_message_dynamic:
          type: boolean
          description: When true, the welcome message is treated as a directive the agent uses to generate a tailored greeting for each call, rather than being spoken word for word. When false, the welcome message is spoken exactly as written.
        is_welcome_message_interruption:
          type: boolean
          description: Allow the caller to interrupt the welcome message. When false, the agent finishes speaking the welcome before listening.
        is_interruption_allowed:
          type: boolean
          description: Global toggle for whether the caller can interrupt the agent mid-sentence at any point in the call.
        dynamic_variables:
          type: object
          description: |
            Key/value map used to substitute placeholders in the agent's
            prompt and welcome message at call time. Reference a variable
            in your prompt with `{{variable_name}}`. Useful for
            personalising the same agent across many calls.
          additionalProperties:
            type: string
          example:
            customer_name: Jane Doe
            order_id: "ORD-12345"
        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
                - soniox
              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
            language:
              type: string
              description: |
                Language code for the transcriber. Format and supported
                values depend on the provider (e.g. `en-US` for Deepgram,
                `hi-IN` for Sarvam). Applies regardless of which
                `provider` is selected.
              example: en-US
            silence_timeout_ms:
              type: integer
              description: Silence timeout in milliseconds.
              example: 400
            should_apply_noise_reduction:
              type: boolean
              description: Reduce background noise on the inbound audio stream before transcription.
            interruption_min_words:
              type: integer
              minimum: 1
              description: Minimum number of words the caller must say before their speech is treated as an interruption.
              example: 2
            max_call_duration_in_sec:
              type: integer
              minimum: 1
              description: Hard upper bound on call length in seconds. The agent will end the call once this is reached.
              example: 600
            first_ideal_message:
              type: string
              description: |
                First nudge spoken when the caller goes silent past the
                idle threshold. Set `is_first_ideal_message_dynamic` to
                `true` to have the LLM regenerate this each time.
            is_first_ideal_message_dynamic:
              type: boolean
              description: When true, `first_ideal_message` is treated as a prompt and the LLM generates a fresh nudge each call.
            second_ideal_message:
              type: string
              description: Second nudge spoken if silence continues after the first.
            is_second_ideal_message_dynamic:
              type: boolean
              description: When true, `second_ideal_message` is treated as a prompt and the LLM generates a fresh nudge each call.
            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. The current catalog is returned by the LLM providers list.
              example: gpt-4.1-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
                - google
                - cartesia
                - sarvam
              description: The voice provider to use. The current catalog is returned by the TTS providers list.
              example: eleven_labs
            voice_id:
              type: string
              description: The provider's voice identifier, returned in the `name` field of the voices list (not the numeric `id`).
              example: JBFqnCBsd6RMkjVDRZzb
            model:
              type: string
              description: |
                TTS model identifier. Only consumed when `provider` is
                `cartesia` (e.g. `sonic-3.5`). For ElevenLabs and other
                providers the model is implied by `voice_id` and this
                field is ignored.
              example: sonic-3.5
            speech_speed:
              type: number
              minimum: 0.5
              maximum: 2.0
              default: 1.0
              description: Playback speed multiplier for the agent's voice. 1.0 is normal speed.
        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:
                    $ref: "#/components/schemas/ExtractedVariable"
                trigger_call_statuses:
                  type: array
                  description: |
                    Call outcomes that should fire this action. Omit to
                    use the default (`completed`, `voicemail_detected`).
                    Pass an explicit list to also include failed calls,
                    no-answers, busy signals, etc.
                  items:
                    type: string
                    enum:
                      - completed
                      - voicemail_detected
                      - failed
                      - no_answer
                      - busy
                      - cancelled
                  example:
                    - completed
                    - voicemail_detected
            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:
                    $ref: "#/components/schemas/ExtractedVariable"
                trigger_call_statuses:
                  type: array
                  description: |
                    Call outcomes that should fire this webhook. Omit to
                    use the default (`completed`, `voicemail_detected`).
                  items:
                    type: string
                    enum:
                      - completed
                      - voicemail_detected
                      - failed
                      - no_answer
                      - busy
                      - cancelled
                  example:
                    - completed
                    - failed
        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!
            message_type:
              type: string
              enum:
                - static
                - prompt
              description: |
                `static` speaks `message` verbatim. `prompt` treats
                `message_prompt` as an LLM instruction and generates a
                fresh closing line each call (useful for matching the
                caller's language and tone).
            message_prompt:
              type: string
              description: LLM prompt used to generate the closing line when `message_type` is `prompt`.
              example: End the call politely in the same language the user is speaking.
        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.
            tts_volume_reduction:
              type: number
              minimum: 0
              maximum: 1
              description: Amount to drop the agent's TTS volume while the ambient track plays, on a 0–1 scale. Helps the voice cut through without raising the overall mix.
        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. Set this with the
            nested object shown here; the agent object returns these values as the
            flat fields `voicemail_enabled` and `voicemail_message`. Voicemail detection
            is an access-gated feature. If it isn't enabled for your account,
            [request access](https://omnidim.io/contact-us?reason=product&lock=1).
          properties:
            enabled:
              type: boolean
              description: Detect voicemail and leave your message 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 exactly as it appears in the dashboard's language picker. Unrecognized names are skipped.
          items:
            type: string
          example:
            - English (India)
            - Hindi
security:
  - BearerAuth: []
tags:
  - name: Agents
    description: |
      Create, retrieve, update, and delete AI voice agents. Configure
      transcriber, model, voice, integrations, and post-call actions.
  - name: Calls
    description: |
      Dispatch calls to phone numbers, retrieve call logs, and inspect
      individual call sessions.
  - name: Bulk calls
    description: |
      Run outbound campaigns against a contact list. Schedule, retry,
      pause, resume, and monitor live status.
  - name: Knowledge base
    description: |
      Upload, manage, and attach PDF documents to agents.
  - name: Phone numbers
    description: |
      Manage phone numbers, attach and detach from agents, import from
      Twilio, Exotel, or your own SIP trunk.
  - name: Providers
    description: |
      Discover available LLM, voice, STT, and TTS providers, with
      advanced filtering for ElevenLabs voices.
  - name: Simulation
    description: |
      Run automated agent test simulations with scenarios and quick-test
      workflows.
  - name: Reseller
    description: |
      Manage child organizations, add users, transfer credits, and
      control dashboard access flags. Reseller accounts only.
      [Request access](https://omnidim.io/contact-us?reason=partnership&lock=1).
paths:
  /agents:
    get:
      tags:
        - Agents
      operationId: listAgents
      summary: List agents
      description: Retrieve all agents for the authenticated user with pagination support.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # List all agents with pagination
            response = client.agent.list(page=1, page_size=10)
            print(response)
      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:
                      $ref: "#/components/schemas/Agent"
                  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
  /agents/create:
    post:
      tags:
        - Agents
      operationId: createAgent
      summary: Create agent
      description: |
        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.

        > **Voicemail detection is an access-gated feature** that we turn on per
        account. If it isn't enabled for yours yet,
        [request access](https://omnidim.io/contact-us?reason=product&lock=1)
        before configuring the `voicemail` object.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/AgentConfigInput"
                - 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
  /agents/{agent_id}:
    parameters:
      - name: agent_id
        in: path
        required: true
        schema:
          type: integer
        description: The ID of the agent.
    get:
      tags:
        - Agents
      operationId: getAgent
      summary: Get agent
      description: Get details of a specific agent by ID.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      responses:
        "200":
          description: Agent details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
              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
    put:
      tags:
        - Agents
      operationId: updateAgent
      summary: Update agent
      description: >-
        Update an existing agent. Send only the fields you want to change.


        > **Voicemail detection is an access-gated feature** that we turn on per
        account. If it isn't enabled for yours yet,
        [request access](https://omnidim.io/contact-us?reason=product&lock=1)
        before configuring the `voicemail` object below.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgentConfigInput"
      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
    delete:
      tags:
        - Agents
      operationId: deleteAgent
      summary: Delete agent
      description: Permanently delete an agent.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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
  /calls/dispatch:
    post:
      tags:
        - Calls
      operationId: dispatchCall
      summary: Dispatch call
      description: |
        Initiate a call to a phone number using a specified agent. The
        phone number must include a country code with a leading plus.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      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: Id of a phone number on your account to place the call from (see the phone number list endpoint). Omit to use the platform's default number.
                  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
  /calls/logs:
    get:
      tags:
        - Calls
      operationId: listCallLogs
      summary: List call logs
      description: Retrieve call logs with pagination and optional filtering.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      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
          description: Filter by call outcome.
          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:
                      $ref: "#/components/schemas/Call"
                  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: " <br/> user:  <br/> LLM: Hello, I am Kevin from OmniDimension support. How may I help you? <br/> <br/> user: i awnt ti book a meetig <br/> LLM: Sure, I can help with that. Could you please provide me with your name and email address? <br/> <br/> user: aok demo@example.com <br/> LLM: Let's confirm your email address: demo@example.com Is that correct? <br/> <br/> user: y <br/> LLM: Great, you can book a meeting using the link below. <br/>"
                    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. <a
                            href="https://webhook.site/#!/edit/94b3db04-2a3f-480f-86f5-6bcc84b4cc5b">Change response in
                            Webhook.site</a>.
                          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
  /calls/logs/{call_log_id}:
    get:
      tags:
        - Calls
      operationId: getCallLog
      summary: Get call log
      description: Detailed information about a specific call (duration, status, transcript, sentiment, extracted variables).
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      parameters:
        - name: call_log_id
          in: path
          required: true
          schema:
            type: integer
          description: Id of the call log, as returned by the call log list.
      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:
                      $ref: "#/components/schemas/Call"
                  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: " <br/> user:  <br/> LLM: Hello, I am Kevin from OmniDimension support. How may I help you? <br/> <br/> user: i awnt ti book a meetig <br/> LLM: Sure, I can help with that. Could you please provide me with your name and email address? <br/> <br/> user: aok demo@example.com <br/> LLM: Let's confirm your email address: demo@example.com Is that correct? <br/> <br/> user: y <br/> LLM: Great, you can book a meeting using the link below. <br/>"
                    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. <a
                            href="https://webhook.site/#!/edit/94b3db04-2a3f-480f-86f5-6bcc84b4cc5b">Change response in
                            Webhook.site</a>.
                          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
  /calls/bulk_call:
    get:
      tags:
        - Bulk calls
      operationId: fetchBulkCalls
      summary: Fetch bulk calls
      description: List bulk-call campaigns with pagination and optional status filter.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      parameters:
        - name: pageno
          in: query
          description: Page number for pagination.
          schema:
            type: integer
            default: 1
        - name: pagesize
          in: query
          schema:
            type: integer
            default: 10
            maximum: 150
          description: Items per page (max 150).
        - 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:
                      $ref: "#/components/schemas/BulkCallSummary"
              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
  /calls/bulk_call/create:
    post:
      tags:
        - Bulk calls
      operationId: createBulkCall
      summary: Create bulk call
      description: |
        Create a new bulk-call campaign. Supports immediate, scheduled,
        and auto-retry modes.

        There are two kinds of campaign:

        - **Static** (default): you supply the full `contact_list` up
          front and the campaign dials through it.
        - **Dynamic**: set `is_dynamic` to `true` and the campaign accepts
          contacts in real time via the Add contact to dynamic campaign
          webhook. `contact_list` is optional here, so you can start the
          campaign empty and feed it from a CRM, form, or automation. A
          dynamic campaign stays alive waiting for contacts instead of
          completing when its queue drains.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
        - lang: bash
          label: Dynamic (cURL)
          source: |
            # Create a dynamic campaign with no contacts up front.
            # Feed it later with the add_contact webhook.
            curl -X POST "https://backend.omnidim.io/api/v1/calls/bulk_call/create" \
              -H "Authorization: Bearer YOUR_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "name": "Real-Time Lead Outreach",
                "phone_number_id": "1",
                "is_dynamic": true
              }'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - 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.
                is_dynamic:
                  type: boolean
                  default: false
                  description: |
                    Set to `true` to create a dynamic campaign that accepts
                    contacts in real time via the Add contact to dynamic
                    campaign webhook. When `true`, `contact_list` is optional
                    and may be omitted to start the campaign empty.
                contact_list:
                  type: array
                  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.

                    Required for static campaigns. Optional when `is_dynamic`
                    is `true` (you can omit it and add contacts later via the
                    webhook).
                  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`. A dynamic campaign created with no
            contacts comes back `waiting` (alive, ready for webhook
            contacts). Otherwise it is 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
                  is_dynamic:
                    type: boolean
                  current_status:
                    type: string
              example:
                status: success
                message: Bulk call created successfully
                id: 314
                is_scheduled: false
                is_dynamic: false
                current_status: pending
  /calls/bulk_call/{campaign_id}/add_contact:
    post:
      tags:
        - Bulk calls
      operationId: addBulkCallContact
      summary: Add contact to dynamic campaign
      description: |
        Push a single contact into a dynamic bulk-call campaign in real
        time. Dynamic campaigns are created from the dashboard (Bulk Call
        > Create New Campaign > Dynamic Campaign) and stay alive waiting
        for contacts, so this webhook is how you feed them from a CRM,
        form, or automation platform. The contact is queued immediately,
        and the campaign starts calling it as soon as it is within
        operating hours.
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |
            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": "Demo User",
                  "interest": "Home Insurance"
                },
                "metadata": {
                  "crm_lead_id": "lead_9876",
                  "source": "website_form"
                }
              }'
      parameters:
        - name: campaign_id
          in: path
          required: true
          description: ID of the dynamic campaign to add the contact to.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - to_number
              properties:
                to_number:
                  type: string
                  description: Contact phone number in international format (e.g., +15551234567).
                  example: "+15551234567"
                custom_variables:
                  type: object
                  description: |
                    Key-value pairs passed to the agent as context for this
                    call, so the agent can reference them during the
                    conversation (e.g. the contact's name or reason for the
                    call). Match these keys to the variables used in your
                    agent's welcome message or prompt.
                  additionalProperties: true
                  example:
                    name: Demo User
                    interest: Home Insurance
                metadata:
                  type: object
                  description: |
                    Key-value pairs stored on the contact for your own
                    tracking (e.g. CRM or lead IDs). Not shared with the
                    agent.
                  additionalProperties: true
                  example:
                    crm_lead_id: lead_9876
                    source: website_form
      responses:
        "200":
          description: |
            Contact accepted and queued. `campaign_status` reflects the
            campaign state after the contact was added (`in_progress` when
            calling resumes, or `waiting` / `auto_paused` when the contact
            is queued for the next operating window).
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  message:
                    type: string
                  campaign_id:
                    type: integer
                  line_id:
                    type: integer
                    nullable: true
                    description: ID of the new contact record in this campaign.
                  campaign_status:
                    type: string
                  to_number:
                    type: string
              example:
                status: success
                message: Contact added successfully
                campaign_id: 123
                line_id: 4567
                campaign_status: in_progress
                to_number: "+15551234567"
  /calls/bulk_call/{bulk_call_id}:
    put:
      tags:
        - Bulk calls
      operationId: bulkCallActions
      summary: Bulk call actions
      description: Pause, resume, or reschedule a running campaign.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      parameters:
        - name: bulk_call_id
          in: path
          required: true
          schema:
            type: integer
          description: Id of the bulk call campaign.
      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
    delete:
      tags:
        - Bulk calls
      operationId: cancelBulkCall
      summary: Cancel bulk call
      description: Cancel a bulk-call campaign.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # Cancel a bulk call
            response = client.bulk_call.cancel_bulk_call(bulk_call_id=123)
            print(response)
      parameters:
        - name: bulk_call_id
          in: path
          required: true
          schema:
            type: integer
          description: Id of the bulk call campaign.
      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
    get:
      tags:
        - Bulk calls
      operationId: getBulkCall
      summary: Bulk call details
      description: Get detailed information about a bulk-call campaign.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # Get detailed information about a bulk call
            response = client.bulk_call.detail_bulk_call(bulk_call_id=123)
            print(response)
      parameters:
        - name: bulk_call_id
          in: path
          required: true
          schema:
            type: integer
          description: Id of the bulk call campaign.
      responses:
        "200":
          description: Bulk call details.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  details:
                    $ref: "#/components/schemas/BulkCallDetail"
                  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"
  /bulk-call/{bulk_call_id}/live-status:
    get:
      tags:
        - Bulk calls
      operationId: getBulkCallLiveStatus
      summary: Bulk call live status
      description: Real-time status of a running bulk-call campaign.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            response = client.bulk_call.get_live_status(bulk_call_id=123)
            print(response)
      parameters:
        - name: bulk_call_id
          in: path
          required: true
          schema:
            type: integer
          description: Id of the bulk call campaign.
      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
  /knowledge_base/list:
    get:
      tags:
        - Knowledge base
      operationId: listKnowledgeBaseFiles
      summary: List knowledge base files
      description: List all knowledge-base files for the authenticated user.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # List all knowledge base files
            response = client.knowledge_base.list()
            print(response)
      responses:
        "200":
          description: List of files.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  files:
                    type: array
                    items:
                      $ref: "#/components/schemas/KnowledgeBaseFile"
              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
  /knowledge_base/can_upload:
    post:
      tags:
        - Knowledge base
      operationId: canUploadFile
      summary: Check file upload capability
      description: Check whether a file can be uploaded based on size and type.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      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.0
                  used: 0.0
                  remaining: 10.0
  /knowledge_base/create:
    post:
      tags:
        - Knowledge base
      operationId: uploadKnowledgeBaseFile
      summary: Upload file to knowledge base
      description: Upload a PDF file. The file content must be Base64 encoded.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      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:
                    $ref: "#/components/schemas/KnowledgeBaseFile"
              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
  /knowledge_base/attach:
    post:
      tags:
        - Knowledge base
      operationId: attachKnowledgeBaseFiles
      summary: Attach files to agent
      description: Attach multiple knowledge-base files to an agent.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      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
  /knowledge_base/detach:
    post:
      tags:
        - Knowledge base
      operationId: detachKnowledgeBaseFiles
      summary: Detach files from agent
      description: Detach multiple knowledge-base files from an agent.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      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
  /knowledge_base/delete:
    post:
      tags:
        - Knowledge base
      operationId: deleteKnowledgeBaseFile
      summary: Delete file from knowledge base
      description: Permanently delete a file. Removes it from any attached agents. Cannot be undone.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # Delete a file from the knowledge base
            file_id = 123  # Replace with your file ID

            response = client.knowledge_base.delete(file_id)
            print(response)
      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
  /phone_number/list:
    get:
      tags:
        - Phone numbers
      operationId: listPhoneNumbers
      summary: List phone numbers
      description: Retrieve all phone numbers associated with your account.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      parameters:
        - name: pageno
          in: query
          description: Page number for pagination.
          schema:
            type: integer
            default: 1
        - name: pagesize
          in: query
          description: Items per page (max 150).
          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:
                      $ref: "#/components/schemas/PhoneNumber"
              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: <redacted>
                    sip_port: <redacted>
                    sip_username: <redacted>
                    sip_password: <redacted>
                    sip_trunk_name: inbound-trunk
                    sip_id: <redacted>
                    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
  /phone_number/attach:
    post:
      tags:
        - Phone numbers
      operationId: attachPhoneNumber
      summary: Attach phone number to agent
      description: Attach an account-owned phone number to an existing agent.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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.
  /phone_number/detach:
    post:
      tags:
        - Phone numbers
      operationId: detachPhoneNumber
      summary: Detach phone number
      description: Detach a phone number from its associated agent.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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.
  /phone_number/import/twilio:
    post:
      tags:
        - Phone numbers
      operationId: importTwilioNumber
      summary: Import Twilio number
      description: Import an existing Twilio number by providing your Twilio credentials.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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
  /phone_number/import/exotel:
    post:
      tags:
        - Phone numbers
      operationId: importExotelNumber
      summary: Import Exotel number
      description: Import an Exotel number by providing your Exotel credentials.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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
  /phone_number/import/sip:
    post:
      tags:
        - Phone numbers
      operationId: importSipTrunk
      summary: Import SIP trunk
      description: Import a phone number associated with a SIP trunk.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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
  /providers/llms:
    get:
      tags:
        - Providers
      operationId: listLLMProviders
      summary: List LLM providers
      description: Retrieve all available Large Language Model providers.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # List all LLM providers
            llms = client.providers.list_llms()
            print(llms)
            # Returns: {'llms': [...], 'total': 5}
      responses:
        "200":
          description: LLM providers.
          content:
            application/json:
              schema:
                type: object
                properties:
                  llms:
                    type: array
                    items:
                      $ref: "#/components/schemas/Provider"
                  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
  /providers/voices:
    get:
      tags:
        - Providers
      operationId: listVoices
      summary: List voices
      description: |
        Retrieve voices with filtering and pagination support. ElevenLabs
        supports advanced filtering by name, language, accent, and gender.
        Other providers support basic pagination only.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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)
      parameters:
        - name: provider
          in: query
          description: TTS provider to list voices from. Omit to list across all providers.
          schema:
            type: string
            enum:
              - eleven_labs
              - google
              - deepgram
              - cartesia
              - sarvam
        - name: search
          in: query
          description: Substring match against voice name or description. ElevenLabs only.
          schema:
            type: string
        - name: language
          in: query
          description: ISO language code (e.g. `en`, `hi`, `es`). ElevenLabs only.
          schema:
            type: string
        - name: accent
          in: query
          description: Accent label (e.g. `american`, `british`). ElevenLabs only.
          schema:
            type: string
        - name: gender
          in: query
          description: Filter voices by gender. ElevenLabs only.
          schema:
            type: string
            enum:
              - male
              - female
        - name: page
          in: query
          description: 1-indexed page number.
          schema:
            type: integer
            default: 1
        - name: page_size
          in: query
          description: Voices per page. Capped at 100.
          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:
                      $ref: "#/components/schemas/Voice"
                  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
  /providers/stt:
    get:
      tags:
        - Providers
      operationId: listSTTProviders
      summary: List STT providers
      description: Retrieve all Speech-to-Text providers.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # List all STT providers
            stt_providers = client.providers.list_stt()
            print(stt_providers)
            # Returns: {'stt': [...], 'total': 3}
      responses:
        "200":
          description: STT providers.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stt:
                    type: array
                    items:
                      $ref: "#/components/schemas/Provider"
                  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
  /providers/tts:
    get:
      tags:
        - Providers
      operationId: listTTSProviders
      summary: List TTS providers
      description: Retrieve all Text-to-Speech providers.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # List all TTS providers
            tts_providers = client.providers.list_tts()
            print(tts_providers)
            # Returns: {'tts': [...], 'total': 4}
      responses:
        "200":
          description: TTS providers.
          content:
            application/json:
              schema:
                type: object
                properties:
                  tts:
                    type: array
                    items:
                      $ref: "#/components/schemas/Provider"
                  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
  /providers/all:
    get:
      tags:
        - Providers
      operationId: listAllProviders
      summary: List all providers
      description: Comprehensive response with services and voices in one payload.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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}
      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
  /providers/voice/{voice_id}:
    get:
      tags:
        - Providers
      operationId: getVoice
      summary: Get voice details
      description: Detailed metadata for a specific voice.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # 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', ...}
      parameters:
        - name: voice_id
          in: path
          required: true
          schema:
            type: integer
          description: Numeric id of the voice, as returned in the `id` field of the voices list.
      responses:
        "200":
          description: Voice details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/VoiceDetail"
              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
  /simulations:
    get:
      tags:
        - Simulation
      operationId: listSimulations
      summary: List simulations
      description: Retrieve simulations with pagination.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # List all simulations with pagination
            response = client.simulation.list(pageno=1, pagesize=10)
            print(response)
      parameters:
        - name: pageno
          in: query
          description: Page number for pagination.
          schema:
            type: integer
            default: 1
        - name: pagesize
          in: query
          description: Items per page (max 150).
          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:
                      $ref: "#/components/schemas/Simulation"
                  total_records:
                    type: integer
              example:
                records: []
                total_records: 0
    post:
      tags:
        - Simulation
      operationId: createSimulation
      summary: Create simulation
      description: Create a new test simulation with scenarios.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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:
                    $ref: "#/components/schemas/Simulation"
              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
  /simulations/{simulation_id}:
    parameters:
      - name: simulation_id
        in: path
        required: true
        schema:
          type: integer
    get:
      tags:
        - Simulation
      operationId: getSimulation
      summary: Get simulation
      description: Detailed simulation information.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      responses:
        "200":
          description: Simulation details.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  simulation:
                    $ref: "#/components/schemas/Simulation"
              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
    put:
      tags:
        - Simulation
      operationId: updateSimulation
      summary: Update simulation
      description: Update an existing simulation. Pass the full `scenarios` array (existing entries you want to keep plus any changes).
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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:
                    $ref: "#/components/schemas/Simulation"
              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
    delete:
      tags:
        - Simulation
      operationId: deleteSimulation
      summary: Delete simulation
      description: Permanently delete a simulation.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # Delete a simulation
            simulation_id = 456
            response = client.simulation.delete(simulation_id)
            print(response)
      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
  /simulations/{simulation_id}/start:
    post:
      tags:
        - Simulation
      operationId: startSimulation
      summary: Start simulation
      description: Begin running a simulation. Optionally update scenarios at start time (same shape as Update simulation).
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            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)
      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:
                    $ref: "#/components/schemas/Simulation"
              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
  /simulations/{simulation_id}/stop:
    post:
      tags:
        - Simulation
      operationId: stopSimulation
      summary: Stop simulation
      description: Stop a running simulation.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # Stop a running simulation
            simulation_id = 456
            response = client.simulation.stop(simulation_id)
            print(response)
      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
  /simulations/{simulation_id}/enhance-prompt:
    post:
      tags:
        - Simulation
      operationId: enhancePrompt
      summary: Enhance prompt
      description: Generate prompt-improvement suggestions for a completed simulation.
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: |
            from omnidimension import Client
            client = Client(api_key)

            # Get enhanced prompt suggestions
            simulation_id = 456
            response = client.simulation.enhance_prompt(simulation_id)
            print(response)
      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"}`.
  /reseller/organizations:
    get:
      tags:
        - Reseller
      operationId: listChildOrganizations
      summary: List child organizations
      description: |
        List all child organizations and their users under the reseller
        account. Returns each organization's balance, cost-per-minute
        rate, and concurrency limit, plus the dashboard menu access
        flags scoped to your reseller's permissions for every user.
      responses:
        "200":
          description: List of organizations.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  reseller_organization:
                    type: object
                    properties:
                      id: { type: integer }
                      name: { type: string }
                      concurrent_call_limit: { type: integer }
                  organizations:
                    type: array
                    items:
                      type: object
                      properties:
                        id: { type: integer }
                        name: { type: string }
                        cost_per_min: { type: number }
                        org_balance: { type: number }
                        reseller_org_balance_currency_symbol: { type: string }
                        concurrent_call_limit: { type: integer }
                        org_user_currency_symbol: { type: string }
                        timezone: { type: string }
                        created_date: { type: string, format: date-time }
                        total_users: { type: integer }
                        users:
                          type: array
                          items:
                            type: object
                            properties:
                              id: { type: integer }
                              name: { type: string }
                              email: { type: string, format: email }
                              phone: { type: string }
                              login_date:
                                type: string
                                format: date-time
                                nullable: true
                              is_active: { type: boolean }
                              expiry_date:
                                type: string
                                format: date
                                nullable: true
                              access_level: { type: boolean }
                              dashboard_menu_access:
                                $ref: '#/components/schemas/ResellerDashboardMenuAccess'
                  total_organizations: { type: integer }
                  total_users_across_orgs: { type: integer }
                  reseller_access_control:
                    type: object
                    properties:
                      dashboard_menu_access:
                        $ref: '#/components/schemas/ResellerDashboardMenuAccess'
                example:
                  success: true
                  reseller_organization:
                    id: 5678
                    name: Demo Reseller
                    concurrent_call_limit: 10
                  organizations:
                    - id: 4001
                      name: Acme Inc
                      cost_per_min: 0.09
                      org_balance: 24442.60
                      reseller_org_balance_currency_symbol: "$"
                      concurrent_call_limit: 1
                      org_user_currency_symbol: "$"
                      timezone: US/Pacific
                      created_date: "2025-10-09T10:20:58.220633"
                      total_users: 1
                      users:
                        - id: 1110
                          name: Demo User
                          email: demo@example.com
                          phone: false
                          login_date: "2026-04-23T11:00:06.685330"
                          is_active: true
                          expiry_date: null
                          access_level: false
                          dashboard_menu_access:
                            is_bots_menu_access: true
                            is_leads_access: false
                            is_voice_cloning_access: false
                            is_workflow_access: false
                            is_asr_evaluation_menu_access: false
                            is_train_with_call_recording_menu_access: false
                            is_call_logs_menu_access: true
                            is_call_simulation_menu_access: false
                            access_to_monitor_live_call: false
                            is_whatsapp_flow_enabled: true
                            is_billing_menu_access: true
                            is_knowledge_base_access: true
                            is_integration_access: true
                            is_phone_number_access: true
                            is_bulk_call_access: true
                            is_analytics_access: true
                    - id: 4002
                      name: Beta Co
                      cost_per_min: 0.20
                      org_balance: 13.0
                      reseller_org_balance_currency_symbol: "$"
                      concurrent_call_limit: 5
                      org_user_currency_symbol: "$"
                      timezone: US/Pacific
                      created_date: "2026-05-11T11:04:09.426809"
                      total_users: 1
                      users:
                        - id: 1234
                          name: Demo User 2
                          email: demo2@example.com
                          phone: "+15551234567"
                          login_date: null
                          is_active: true
                          expiry_date: null
                          access_level: false
                          dashboard_menu_access:
                            is_bots_menu_access: true
                            is_leads_access: false
                            is_voice_cloning_access: true
                            is_workflow_access: false
                            is_asr_evaluation_menu_access: false
                            is_train_with_call_recording_menu_access: false
                            is_call_logs_menu_access: true
                            is_call_simulation_menu_access: false
                            access_to_monitor_live_call: false
                            is_whatsapp_flow_enabled: true
                            is_billing_menu_access: true
                            is_knowledge_base_access: true
                            is_integration_access: true
                            is_phone_number_access: false
                            is_bulk_call_access: true
                            is_analytics_access: true
                  total_organizations: 2
                  total_users_across_orgs: 2
                  reseller_access_control:
                    dashboard_menu_access:
                      is_bots_menu_access: true
                      is_leads_access: true
                      is_voice_cloning_access: true
                      is_workflow_access: true
                      is_asr_evaluation_menu_access: true
                      is_train_with_call_recording_menu_access: true
                      is_call_logs_menu_access: true
                      is_call_simulation_menu_access: true
                      access_to_monitor_live_call: true
                      is_whatsapp_flow_enabled: true
                      is_billing_menu_access: true
                      is_knowledge_base_access: true
                      is_integration_access: true
                      is_phone_number_access: true
                      is_bulk_call_access: true
                      is_analytics_access: true
  /reseller/users/add:
    post:
      tags:
        - Reseller
      operationId: addUser
      summary: Add user
      description: |
        Create a new child user and organization under the reseller.
        The new organization is linked to your reseller account
        automatically.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - email
                - phone
                - password
              properties:
                name:
                  type: string
                  description: Full name of the new user.
                email:
                  type: string
                  format: email
                  description: Email address. Also used as the login.
                phone:
                  type: string
                  description: Phone number including country code (e.g. `+15551234567`).
                  example: "+15551234567"
                password:
                  type: string
                  format: password
                  description: Account password for the new user.
                welcome_minutes_to_credit:
                  type: integer
                  description: Minutes to credit to the new account on signup.
                cost_per_min:
                  type: number
                  description: Cost per minute charged to this user (e.g. `0.20`). Must be at least the reseller's premium model rate.
                  example: 0.2
                concurrent_call_limit:
                  type: integer
                  description: Maximum number of concurrent calls allowed for this account.
                expiry_date:
                  type: string
                  format: date
                  description: Account expiry date in `YYYY-MM-DD` format (e.g. `2026-12-31`).
                user_currency:
                  type: string
                  description: ISO 4217 currency code for the account (e.g. `USD`, `INR`). Defaults to the reseller's currency.
                  example: USD
            example:
              name: Demo User
              email: demo@example.com
              phone: "+15551234567"
              password: SecurePass123!
              welcome_minutes_to_credit: 50
              cost_per_min: 0.20
              concurrent_call_limit: 2
              expiry_date: "2026-12-31"
              user_currency: USD
      responses:
        "200":
          description: User created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  user_id: { type: integer }
                  organization_id: { type: integer }
                  organization_name: { type: string }
                  organization_balance: { type: number }
                  cost_per_min: { type: number }
                example:
                  success: true
                  message: User and organization created successfully
                  user_id: 1234
                  organization_id: 9012
                  organization_name: Demo User's Organization
                  organization_balance: 10.0
                  cost_per_min: 0.20
  /reseller/users/access-control:
    post:
      tags:
        - Reseller
      operationId: setUserAccessControl
      summary: Update user access control
      description: |
        Enable or disable dashboard menu access flags for a child user.
        Only the flags you pass are changed. Flags outside your
        reseller's permissions are silently ignored.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - user_id
                - dashboard_menu_access
              properties:
                user_id:
                  type: integer
                  description: ID of the child user to update.
                dashboard_menu_access:
                  allOf:
                    - $ref: '#/components/schemas/ResellerDashboardMenuAccess'
                  description: |
                    Flags to update. Only pass the flags you want to
                    change. Others are left untouched. Flags outside
                    your reseller's permissions are silently dropped.
            example:
              user_id: 1234
              dashboard_menu_access:
                is_bots_menu_access: true
                is_call_logs_menu_access: true
                is_phone_number_access: false
      responses:
        "200":
          description: Access control updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  updated_flags:
                    allOf:
                      - $ref: '#/components/schemas/ResellerDashboardMenuAccess'
                    description: The flags that were actually applied (after the reseller-scope filter).
                example:
                  success: true
                  message: User access control updated successfully
                  updated_flags:
                    is_bots_menu_access: true
                    is_call_logs_menu_access: true
                    is_phone_number_access: false
  /reseller/users/expiry:
    post:
      tags:
        - Reseller
      operationId: setUserExpiry
      summary: Update user expiry
      description: |
        Set or remove the expiry date on a child user. The user must
        belong to a child organization of your reseller.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - user_id
              properties:
                user_id:
                  type: integer
                  description: ID of the child user to update.
                expiry_date:
                  type: string
                  format: date
                  nullable: true
                  description: Expiry date in `YYYY-MM-DD` format. Omit or pass `null` to remove the expiry.
            example:
              user_id: 1234
              expiry_date: "2026-12-31"
      responses:
        "200":
          description: Expiry updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  user_id: { type: integer }
                  expiry_date:
                    type: string
                    format: date
                    nullable: true
                example:
                  success: true
                  message: User expiry date updated successfully
                  user_id: 1234
                  expiry_date: "2026-12-31"
  /reseller/concurrency:
    post:
      tags:
        - Reseller
      operationId: setChildConcurrency
      summary: Set child concurrency limit
      description: |
        Set the maximum number of simultaneous calls a child
        organization can run. Slots come from the reseller's shared
        pool. Increasing the limit deducts the delta from your pool
        and fails if you don't have enough slots. Decreasing the
        limit returns the delta to your pool immediately.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - child_organization_id
                - new_limit
              properties:
                child_organization_id:
                  type: integer
                  description: ID of the child organization to update.
                new_limit:
                  type: integer
                  description: The desired absolute concurrent call limit (must be `>= 0`).
            example:
              child_organization_id: 4002
              new_limit: 5
      responses:
        "200":
          description: Concurrency limit updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  child_limit:
                    type: integer
                    description: The child organization's new concurrent call limit.
                  reseller_available:
                    type: integer
                    description: Slots remaining in the reseller's shared pool.
                example:
                  success: true
                  message: Concurrency limit updated successfully.
                  child_limit: 5
                  reseller_available: 7
  /reseller/credits/calculate:
    post:
      tags:
        - Reseller
      operationId: calculateCreditOperation
      summary: Calculate credit operation
      description: |
        Preview the cost of a transfer or revert without moving any
        credits. Use this to confirm amounts before calling the
        transfer or revert endpoints. The response shape differs
        between forward transfers and reverts. See the examples.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - minutes
              properties:
                minutes:
                  type: integer
                  description: Number of minutes to calculate for.
                cost_per_min:
                  type: number
                  description: Rate per minute for a forward transfer (e.g. `0.20`). Not required when `is_revert` is `true`.
                  example: 0.2
                is_revert:
                  type: boolean
                  description: Set to `true` to calculate a revert instead of a forward transfer.
                  default: false
                child_organization_id:
                  type: integer
                  description: ID of the child organization to revert credits from. Required when `is_revert` is `true`.
            examples:
              forward:
                summary: Forward transfer calculation
                value:
                  minutes: 500
                  cost_per_min: 0.20
              revert:
                summary: Revert calculation
                value:
                  minutes: 10
                  is_revert: true
                  child_organization_id: 4002
      responses:
        "200":
          description: Calculated outcome.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  my_cost:
                    type: number
                    description: Forward only. Amount deducted from the reseller balance.
                  user_credit:
                    type: number
                    description: Forward only. Credit value the child receives at `cost_per_min`.
                  profit:
                    type: number
                    description: Forward only. `user_credit - my_cost`.
                  margin:
                    type: number
                    description: Forward only. Per-minute margin.
                  reseller_balance:
                    type: number
                    description: Forward only. Current reseller balance before the transfer.
                  reseller_available_minutes:
                    type: integer
                    description: Forward only. Minutes the reseller could still transfer at its own rate.
                  new_reseller_balance:
                    type: number
                    description: Forward only. Reseller balance after the proposed transfer.
                  refund_amount:
                    type: number
                    description: Revert only. Credits added back to the reseller.
                  deduction_amount:
                    type: number
                    description: Revert only. Credits removed from the child at its current rate.
                  child_balance:
                    type: number
                    description: Revert only. Child balance before the revert.
                  child_available_minutes:
                    type: integer
                    description: Revert only. Minutes available in the child's balance.
                  new_child_balance:
                    type: number
                    description: Revert only. Child balance after the proposed revert.
                  reseller_rate:
                    type: number
                    description: Reseller's wholesale rate (cost per minute).
                  currency_symbol: { type: string }
              examples:
                forward:
                  summary: Forward transfer (500 min at $0.20/min)
                  value:
                    success: true
                    my_cost: 45.0
                    user_credit: 50.0
                    profit: 5.0
                    margin: 0.01
                    reseller_rate: 0.09
                    reseller_balance: 66.113
                    reseller_available_minutes: 734
                    new_reseller_balance: 21.113
                    currency_symbol: "$"
                revert:
                  summary: Revert (10 min from a child)
                  value:
                    success: true
                    refund_amount: 0.9
                    deduction_amount: 2.0
                    reseller_rate: 0.09
                    child_balance: 10.0
                    child_available_minutes: 50
                    new_child_balance: 8.0
                    currency_symbol: "$"
  /reseller/credits/transfer:
    post:
      tags:
        - Reseller
      operationId: transferCreditsToChild
      summary: Transfer credits to a child
      description: |
        Transfer minutes from the reseller balance to a child
        organization. Credits are deducted from your balance
        immediately on success. The target organization must be a
        direct child of your reseller. Use the calculate endpoint
        first to preview the cost.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - to_organization_id
                - minutes
                - cost_per_min
              properties:
                to_organization_id:
                  type: integer
                  description: ID of the child organization to transfer credits to.
                minutes:
                  type: integer
                  description: Number of minutes to transfer.
                cost_per_min:
                  type: number
                  description: Rate per minute to charge the child organization (e.g. `0.20`).
                  example: 0.2
            example:
              to_organization_id: 4002
              minutes: 20
              cost_per_min: 0.20
      responses:
        "200":
          description: Transfer succeeded.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  new_from_balance:
                    type: number
                    description: Reseller balance after the transfer.
                  new_to_balance:
                    type: number
                    description: Child balance after the transfer.
                example:
                  success: true
                  message: Credits allocated successfully
                  new_from_balance: 59.813
                  new_to_balance: 14.0
  /reseller/credits/revert:
    post:
      tags:
        - Reseller
      operationId: revertCreditsFromChild
      summary: Revert credits
      description: |
        Take back unused minutes from a child organization to the
        reseller balance. The refund is calculated at the child's
        current rate, so you don't pass one. This matches exactly
        what was originally charged. Use the calculate endpoint
        first to preview the refund.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - from_organization_id
                - minutes
              properties:
                from_organization_id:
                  type: integer
                  description: ID of the child organization to revert credits from.
                minutes:
                  type: integer
                  description: Number of minutes to revert.
            example:
              from_organization_id: 4002
              minutes: 5
      responses:
        "200":
          description: Credits reverted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  new_from_balance:
                    type: number
                    description: Child balance after the revert.
                  new_to_balance:
                    type: number
                    description: Reseller balance after the revert.
                example:
                  success: true
                  message: Credits reverted successfully
                  new_from_balance: 13.0
                  new_to_balance: 60.263
  /reseller/credits/logs:
    get:
      tags:
        - Reseller
      operationId: getResellerCreditLogs
      summary: Credit transfer logs
      description: |
        Paginated history of all credit transfers and reverts for the
        reseller account. Returns reverse-chronological order by
        default. Date filters are inclusive.
      parameters:
        - name: page
          in: query
          description: Page number for pagination.
          schema:
            type: integer
            default: 1
        - name: page_size
          in: query
          description: Number of records per page (max 100).
          schema:
            type: integer
            default: 20
        - name: date_from
          in: query
          description: Filter logs from this date in `YYYY-MM-DD` format (e.g. `2026-01-01`).
          schema:
            type: string
            format: date
        - name: date_to
          in: query
          description: Filter logs up to and including this date in `YYYY-MM-DD` format (e.g. `2026-03-31`).
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Credit logs.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: object
                    properties:
                      logs:
                        type: array
                        items:
                          type: object
                          properties:
                            id: { type: integer }
                            transfer_reference: { type: string }
                            reseller_organization:
                              type: object
                              properties:
                                id: { type: integer }
                                name: { type: string }
                            from_organization:
                              type: object
                              properties:
                                id: { type: integer }
                                name: { type: string }
                            to_organization:
                              type: object
                              properties:
                                id: { type: integer }
                                name: { type: string }
                            credit_amount: { type: number }
                            cost_amount: { type: number }
                            from_balance_before: { type: number }
                            from_balance_after: { type: number }
                            to_balance_before: { type: number }
                            to_balance_after: { type: number }
                            transfer_date: { type: string, format: date-time }
                            performed_by:
                              type: object
                              properties:
                                id: { type: integer }
                                name: { type: string }
                                email: { type: string, format: email }
                            status: { type: string }
                            transaction_type:
                              type: string
                              description: One of `credit_transfer`, `credit_revert`, or `channel_allocation`.
                            channels_count: { type: integer }
                            previous_channels: { type: integer }
                            new_channels: { type: integer }
                            notes: { type: string }
                      total_records: { type: integer }
                      page: { type: integer }
                      page_size: { type: integer }
                      total_pages: { type: integer }
                example:
                  success: true
                  data:
                    logs:
                      - id: 4
                        transfer_reference: CT-20260115110440-5678-4002
                        reseller_organization: { id: 5678, name: Demo Reseller }
                        from_organization: { id: 5678, name: Demo Reseller }
                        to_organization: { id: 4002, name: Beta Co }
                        credit_amount: 4.0
                        cost_amount: -1.8
                        from_balance_before: 61.613
                        from_balance_after: 59.813
                        to_balance_before: 10.0
                        to_balance_after: 14.0
                        transfer_date: "2026-01-15T16:34:40+05:30"
                        performed_by:
                          id: 1000
                          name: Demo Reseller Admin
                          email: admin@example.com
                        status: success
                        transaction_type: credit_transfer
                        channels_count: 0
                        previous_channels: 0
                        new_channels: 0
                        notes: "Transfer of 20 minutes at 0.20/min"
                      - id: 3
                        transfer_reference: CH-20260115110440-5678-4002
                        reseller_organization: { id: 5678, name: Demo Reseller }
                        from_organization: { id: 5678, name: Demo Reseller }
                        to_organization: { id: 4002, name: Beta Co }
                        credit_amount: 0.0
                        cost_amount: 0.0
                        from_balance_before: 0.0
                        from_balance_after: 0.0
                        to_balance_before: 0.0
                        to_balance_after: 0.0
                        transfer_date: "2026-01-15T16:34:40+05:30"
                        performed_by:
                          id: 1000
                          name: Demo Reseller Admin
                          email: admin@example.com
                        status: success
                        transaction_type: channel_allocation
                        channels_count: 1
                        previous_channels: 4
                        new_channels: 5
                        notes: "Concurrency limit changed from 4 to 5 (Delta: 1)"
                    total_records: 2
                    page: 1
                    page_size: 20
                    total_pages: 1
