Skip to main content

Python SDK for the 3CX XAPI (OData v4)

Project description

3CX Python SDK

A typed Python SDK for the 3CX XAPI (/xapi/v1), built on httpx and Pydantic v2.

Features

  • OAuth2 client-credentials authentication with automatic token refresh
  • OData v4 query builder ($filter, $select, $expand, $orderby, $top, $skip, $count)
  • Automatic pagination — iterate over all pages with a single generator call
  • Full CRUD for users, queues, ring groups, trunks, contacts, and phones
  • Reporting helpers for call log, queue performance, extension statistics, activity log, and more
  • Context-manager support for clean resource management
  • Escape hatches (client.get() / client.post()) for any unlisted endpoint

Installation

pip install 3cx-xapi-python-sdk

Quick start

from threecx import ThreeCXClient, ODataQuery

client = ThreeCXClient(
    base_url="https://pbx.example.com",
    client_id="<service-principal-client-id>",
    client_secret="<service-principal-secret>",
)

# ── Active calls ─────────────────────────────────────────────────────────────
for call in client.active_calls.list():
    print(f"{call.caller}{call.callee}  (duration: {call.duration}s)")

# Drop a specific call
client.active_calls.drop(call_id=42)

# ── Users ─────────────────────────────────────────────────────────────────────
# List first 50 enabled users, sorted by extension number
q = ODataQuery().filter("Enabled eq true").order_by("Number").top(50)
for user in client.users.list(q):
    print(user.number, user.full_name, user.email)

# Get a single user and update their e-mail
user = client.users.get(101)
client.users.update(101, {"Email": "new@example.com"})

# Create a user
from threecx.models import User
new_user = client.users.create(User(
    Number="200",
    FirstName="Alice",
    LastName="Smith",
    Email="alice@example.com",
))

# ── Queues ────────────────────────────────────────────────────────────────────
for queue in client.queues.list():
    agents = client.queues.get_agents(queue.id)
    print(f"Queue {queue.name}: {len(agents)} agents")

# ── Call history ──────────────────────────────────────────────────────────────
q = ODataQuery().filter("CallDirection eq 'Inbound'").order_by("StartTime desc").top(100)
for entry in client.call_history.iterate(q):
    print(entry.start_time, entry.caller, "→", entry.callee, entry.status)

# ── Reports ───────────────────────────────────────────────────────────────────
from datetime import datetime, timedelta, timezone

end = datetime.now(timezone.utc)
start = end - timedelta(days=7)
rows = client.reports.get_call_log(start, end)
print(f"{len(rows)} call-log entries for the last 7 days")

# ── System status ─────────────────────────────────────────────────────────────
status = client.system.get_status()
print(f"PBX {status.pbx_version}  calls: {status.calls_active}  cpu: {status.cpu_usage}%")

# ── Context manager ───────────────────────────────────────────────────────────
with ThreeCXClient(base_url="https://pbx.example.com",
                   client_id="...", client_secret="...") as c:
    print(c.system.get_license())

OData query builder

from threecx import ODataQuery

q = (
    ODataQuery()
    .filter("LastName eq 'Smith'")
    .select("Id", "Number", "FirstName", "LastName", "Email")
    .expand("Groups")
    .order_by("Number")
    .top(25)
    .skip(0)
    .count()
)

All query parameters map directly to OData v4 syntax. Refer to the 3CX XAPI swagger for supported fields per endpoint.

Creating a service principal

  1. Log in to 3CX as admin.
  2. Navigate to Admin → Integrations → API.
  3. Create a new service principal and copy the Client ID and Client Secret.

Services reference

client.<service> Resource
active_calls /ActiveCalls — list & drop live calls
users /Users — CRUD extensions/users
queues /Queues — CRUD call queues & agents
ring_groups /RingGroups — CRUD ring groups
call_history /CallHistoryView — paginated call log
trunks /Trunks, /Peers, /Sbcs
contacts /Contacts — company phone book
phones /Phones, /PhoneTemplates — IP phones
system /SystemStatus, /LicenseStatus, /Parameters
reports Call log, queue & extension statistics, activity log

Escape hatch

Any endpoint not covered by a typed service can be called directly:

data = client.get("/InboundRules", params={"$top": "10"})
result = client.post("/Backups/Pbx.CreateBackup")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

3cx_xapi_python_sdk-1.0.2.tar.gz (42.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

3cx_xapi_python_sdk-1.0.2-py3-none-any.whl (55.7 kB view details)

Uploaded Python 3

File details

Details for the file 3cx_xapi_python_sdk-1.0.2.tar.gz.

File metadata

  • Download URL: 3cx_xapi_python_sdk-1.0.2.tar.gz
  • Upload date:
  • Size: 42.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for 3cx_xapi_python_sdk-1.0.2.tar.gz
Algorithm Hash digest
SHA256 81d24e348ef8069a863bb59ea5a2d5a9d10d4efce64e73cef396f1c88ee99e16
MD5 d20ea27def70b424f81c0a55d021273e
BLAKE2b-256 8252a366f9bf26b431b91af6e0e22427cb8aa40b516f2a5fb25340594087af7c

See more details on using hashes here.

File details

Details for the file 3cx_xapi_python_sdk-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: 3cx_xapi_python_sdk-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 55.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for 3cx_xapi_python_sdk-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6d0075ccaeb891d284557f7a2125a7725a4c5779c3a14d407663669ddcd26523
MD5 9898b77df191aae270d1af2d7f45557d
BLAKE2b-256 8541cff27b7d610278ed5004619377d5117be45cb46ec69cf252cf2a9817304b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page