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.1.tar.gz (63.9 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.1-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: 3cx_xapi_python_sdk-1.0.1.tar.gz
  • Upload date:
  • Size: 63.9 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.1.tar.gz
Algorithm Hash digest
SHA256 6e903110e489c9ada808be998729d07c137d0c1075690349bcf0cd97c46681a1
MD5 7b7bb1e6c670fca3df557f05d21fe22f
BLAKE2b-256 92389eade941a407a219ca18a0329e4526180d1e70b012f447c59297e365c273

See more details on using hashes here.

File details

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

File metadata

  • Download URL: 3cx_xapi_python_sdk-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 24.0 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 daca9d7f3b9fbcd0d8a4a461686d9e142a806f732e7a62fbdb18c0c9037f562c
MD5 1681e881b94077089676a9b733f77f53
BLAKE2b-256 f52b951cfbd1357b6efc8758123ab88c83a38dd3660142465dbb32cff16fc0ae

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