Skip to main content

OmniDimension Python SDK

Build and ship AI voice agents from a single prompt.

OmniDimension lets you build, test, and deploy reliable voice AI assistants by simply describing them in plain text. The platform offers rigorous simulation testing and real-time observability, making it easy to debug and monitor agents in production.

👉 Try the Web UI — You can also build and test voice agents visually using our no-code interface.


🚀 Features

  • Prompt-based creation: Define voice agents with natural language.
  • Drag-and-drop editor: Chat or visually edit flows, voices, models, and more.
  • Prebuilt templates: Use plug-and-play agent templates for common use cases.
  • Testing & monitoring: Simulate edge cases and debug live calls.
  • Knowledge Base support: Upload and attach documents (PDFs) for factual grounding.
  • Integrations: Connect to external APIs, CRMs, or tools like Cal.com.
  • Phone agents: Assign numbers and initiate real voice calls via the SDK.
  • Bulk Call: Send multiple voice calls AI to multiple numbers simultaneously.
  • Account balance: Check remaining credit, the minutes it buys, and concurrency headroom before you dial.

📦 Installation

Basic SDK

pip install omnidimension

Requires Python 3.9+


🔐 Authentication

First, obtain your API key from the OmniDimension dashboard. Store it in your environment variables:

Linux/macOS

export OMNIDIM_API_KEY="your_api_key_here"

Windows (CMD)

set OMNIDIM_API_KEY=your_api_key_here

In Python

import os
from omnidimension import Client

api_key = os.environ.get("OMNIDIM_API_KEY")
client = Client(api_key)

✨ SDK Usage

from omnidimension import Client

# Initialize the client with your API key
client = Client(api_key="your_api_key")

# List agents
agents = client.agent.list()
print(agents)

🛰️ MCP server

The OmniDimension MCP server lives in its own repositories, not in this SDK. Pick whichever fits your client.

Hosted (no install)

Point any MCP client at the hosted server. It speaks the standard OAuth flow, so clients discover the rest automatically:

https://mcp.omnidim.io/mcp

For Claude Code:

claude mcp add --transport http omnidim https://mcp.omnidim.io/mcp --scope user

Source: Omnidim/omnidim-mcp-cloud

Local (stdio)

For clients that launch a local server (Claude Desktop, Cursor, Windsurf), use the npm package @omnidim-ai/mcp-server. Save this as your MCP client config:

{
  "mcpServers": {
    "omnidim": {
      "command": "npx",
      "args": ["-y", "@omnidim-ai/mcp-server"],
      "env": {
        "OMNIDIM_API_KEY": "<your_omnidim_api_key>"
      }
    }
  }
}

Source: Omnidim/omnidim-mcp-server


📡 Providers API

The Providers API allows you to discover and explore all available AI providers for LLMs, voices, STT, and TTS services.

Quick Examples

# Get all LLM providers
llms = client.providers.list_llms()
print(f"[SUCCESS] Found {llms['total']} LLM providers")

# List voices with pagination
voices = client.providers.list_voices(page=1, page_size=50)
print(f"[SUCCESS] Found {voices['total']} voices")

![INFO] Complete Providers Documentation


📚 Knowledge Base

files = client.knowledge_base.list()
print(files)

file_ids = [123]
agent_id = 456
response = client.knowledge_base.attach(file_ids, agent_id)
print(response)

🔌 Integrations

response = client.integrations.create_custom_api_integration(
    name="WeatherAPI",
    url="https://api.example.com/weather",
    method="GET"
)
print(response)

client.integrations.add_integration_to_agent(agent_id=123, integration_id=789)

☎️ Phone Number Management

numbers = client.phone_number.list(page=1, page_size=10)
print(numbers)

client.phone_number.attach(phone_number_id=321, agent_id=123)

# Search for numbers available to purchase in a region
# carrier is region-specific; every region currently requires one. Omitting it
# (or passing an unknown value) gets a 409/404 back listing the valid carriers.
available = client.phone_number.search(region="US", pattern="415", page=1, limit=20, carrier="carrier-us")
print(available)

# Purchase one of the numbers found above
purchase = client.phone_number.purchase(
    region="US",
    phone_number="+14155550123",
    carrier="carrier-us",
    idempotency_key="order-2024-12-01-001"  # safe to retry with the same key
)
print(purchase)

# Release a number you no longer need
client.phone_number.release(phone_number="+14155550123")

Reseller accounts can pass user_id to list, search, purchase, and release to act on a specific child client's account instead of their own.


🤝 Reseller Management

Reseller-only methods for managing child organizations, users, credits, and KYC.

# List child organizations
orgs = client.reseller.list_organizations()

# Create a new child user
new_user = client.reseller.add_user(
    name="Jane Doe",
    email="jane@example.com",
    phone="+14155550123",
    password="a-strong-password",
    welcome_minutes_to_credit=100,
    cost_per_min=0.05
)

# Control which dashboard menus a child user can see
client.reseller.set_access_control(
    user_id=456,
    dashboard_menu_access={"billing": True, "agents": True, "integrations": False}
)

# Set or clear a child account's expiry date
client.reseller.set_expiry(user_id=456, expiry_date="2025-12-31")
client.reseller.set_expiry(user_id=456)  # clears the expiry

# Set a child organization's concurrent call limit (absolute value, not a delta)
client.reseller.set_concurrency(child_organization_id=789, new_limit=10)

# Calculate and transfer credits
cost = client.reseller.calculate_credits(minutes=500, cost_per_min=0.05)
client.reseller.transfer_credits(to_organization_id=789, minutes=500, cost_per_min=0.05)

# Revert a previous transfer (uses the original rate, no cost_per_min to pass)
client.reseller.revert_credits(from_organization_id=789, minutes=500)

# Credit transfer/revert history
logs = client.reseller.credit_logs(page=1, page_size=30)

# KYC: check status, then walk next_step until it reports "completed"
# carrier decides both the requirements and the step flow; every region
# currently requires one, and step names are only knowable from this call.
status = client.reseller.kyc_status(user_id=456)
requirements = client.reseller.kyc_requirements(region="IN", carrier="carrier-1")
client.reseller.submit_kyc_step(
    step="register", user_id=456, region="IN", carrier="carrier-1", full_name="Jane Doe")

# A step with method "upload" takes a document: a path, bytes, or an open file
client.reseller.upload_kyc_document(
    "upload-pan", user_id=456, region="IN", carrier="carrier-2-new",
    document="pan-card.pdf")

# A step with method "redirect" can bring your client back to your own app
client.reseller.submit_kyc_step(
    "verify-aadhaar", user_id=456, region="IN", carrier="carrier-2-new",
    return_url="https://app.example.com/kyc/done")

📞 Bulk Call Management

# First, get your phone number IDs
phone_numbers = client.phone_number.list()
phone_number_id = phone_numbers['phone_numbers'][0]['id']  # Use the first available phone number

# Create a bulk call campaign
contact_list = [
    {
        "phone_number": "+1234567890",
        "customer_name": "John Doe",
        "product_interest": "Premium Plan"
    },
    {
        "phone_number": "+1987654321", 
        "customer_name": "Jane Smith",
        "product_interest": "Basic Plan"
    }
]

# Create immediate bulk call
bulk_call = client.bulk_call.create_bulk_calls(
    name="Marketing Campaign - Q4 2024",
    contact_list=contact_list,
    phone_number_id=phone_number_id
)

# Create scheduled bulk call
scheduled_call = client.bulk_call.create_bulk_calls(
    name="Scheduled Campaign",
    contact_list=contact_list,
    phone_number_id=phone_number_id,
    is_scheduled=True,
    scheduled_datetime="2024-12-25 10:00:00",
    timezone="America/New_York"
)

# Create a draft campaign with number rotation and call conditions
draft = client.bulk_call.create_bulk_calls(
    name="Draft Campaign",
    contact_list=contact_list,
    phone_number_id=phone_number_id,
    save_as_draft=True,
    call_conditions=[
        {"column": "product_interest", "operator": "=", "value": "Premium Plan"}
    ],
    rotation={
        "numbers": [
            {"phone_number_id": phone_number_id, "sequence": 1},
            {"phone_number_id": 456, "sequence": 2}
        ],
        "strategy": "round_robin",
        "calls_per_number": 50
    },
    concurrent_call_limit=5
)
bulk_call_id = draft['json']['id']

# Add contacts to an existing campaign
client.bulk_call.add_contact(
    bulk_call_id=bulk_call_id,
    to_number="+1234567890",
    custom_variables={"customer_name": "John Doe"}
)
client.bulk_call.add_contacts(
    bulk_call_id=bulk_call_id,
    contacts=[
        {"to_number": "+1987654321", "custom_variables": {"customer_name": "Jane Smith"}}
    ]  # up to 1000 contacts per request
)

# Start the draft campaign
client.bulk_call.start_bulk_call(bulk_call_id=bulk_call_id)

# Fetch all bulk calls
bulk_calls = client.bulk_call.fetch_bulk_calls(page=1, page_size=10, status="active")

# Get bulk call details
details = client.bulk_call.detail_bulk_calls(bulk_call_id=123)

# Control bulk call actions
client.bulk_call.bulk_calls_actions(bulk_call_id=123, action="pause")
client.bulk_call.bulk_calls_actions(bulk_call_id=123, action="resume")
client.bulk_call.bulk_calls_actions(
    bulk_call_id=123, 
    action="reschedule",
    new_scheduled_datetime="2024-12-26 14:00:00",
    new_timezone="America/New_York"
)

# Cancel bulk call
client.bulk_call.cancel_bulk_calls(bulk_call_id=123)

# Live status of a running campaign
status = client.bulk_call.get_live_status(bulk_call_id=123)

# Call lines with cursor pagination and filters
lines = client.bulk_call.get_bulk_call_lines(
    bulk_call_id=123,
    pagesize=50,  # max 150
    call_status="completed",
    include_total=True
)
next_page = client.bulk_call.get_bulk_call_lines(
    bulk_call_id=123,
    cursor=lines['json']['next_cursor']
)

# Retry failed calls manually
client.bulk_call.manual_retry(bulk_call_id=123)

# Change the concurrent call limit of a campaign
client.bulk_call.update_concurrency(bulk_call_id=123, concurrent_call_limit=10)

# Manage the campaign's number rotation
numbers = client.bulk_call.list_rotation_numbers(bulk_call_id=123)
client.bulk_call.add_rotation_number(bulk_call_id=123, phone_number_id=456)
client.bulk_call.set_rotation_number_active(bulk_call_id=123, assignment_id=789, is_active=False)

💳 Account Balance

Check what is left in the wallet before starting a campaign, so you find out you are low on credit here rather than from a call failing with 402 payment_required.

wallet = client.account.balance()["json"]

print(wallet["balance"]["amount"], wallet["balance"]["currency"])
print(wallet["estimated_minutes_remaining"], "minutes left")
print(wallet["concurrency"]["available"], "concurrent call slots free")

if not wallet["plan"]["is_usage_based"] and wallet["balance"]["amount"] <= 0:
    raise SystemExit("Out of credit. Top up before dialing.")

Check plan["is_usage_based"] before treating a zero balance as a stop condition: such an organization keeps placing calls and is metered to its payment method instead. The response also carries the active plan, the per-minute rate, and auto-recharge settings. The API key's user needs Billing access in the organization.


/docs/
  ├── agents/
  ├── calling/
  ├── integrations/
  ├── knowledge_base/
  └── phone_numbers/

/examples/         # Sample Python scripts
/cookbook/         # Ready-made project use cases

🌐 Learn More

Visit omnidim.io to explore the full platform, UI builder, and templates.


💬 Support

Metadata

Release files for omnidimension 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for omnidimension 0.5.0
File Size Uploaded Provenance Actions
omnidimension-0.5.0.tar.gz 37.7 kB With provenance Details for omnidimension-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for omnidimension 0.5.0
File Interpreter ABI Platform Actions
omnidimension-0.5.0-py3-none-any.whl Python 3 none any Details for omnidimension-0.5.0-py3-none-any.whl

Total release size: 78.6 kB

Release files / omnidimension-0.5.0.tar.gz

Download URL omnidimension-0.5.0.tar.gz
Size 37.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e7c959385084da68a8936a0be97d3b5121a3f636f3b88a1e731caa3a24a8ffdb
BLAKE2b-256 checksum
How to use checksums
74c4011ebeb7b054f6ab202db0c382aa5a2f6170ac226aa64a786939325f0b0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / omnidimension-0.5.0-py3-none-any.whl

Download URL omnidimension-0.5.0-py3-none-any.whl
Size 40.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e16496ffb05be955e0312f89bfed04b7081e1a1c0ed9ae1b99ad61e76bc16ffd
BLAKE2b-256 checksum
How to use checksums
cf1d4c186b741eea2677d77ae0dc5ac0ad52403cfeaa17e2674c8867029ccdeb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Security for omnidimension 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for omnidimension-0.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page