Skip to main content

pyquestblue

A modern, typed Python SDK for the QuestBlue telecommunications API. It supports synchronous and asynchronous applications and provides resource-oriented access to the full documented QuestBlue 2.3.2 surface: accounts, voice and international DIDs, SIP trunks, SMS/MMS, 10DLC, Fax.Pro, iFax Enterprise, reports, number portability, and VoIP servers.

Status: stable 1.0. All 103 pinned QuestBlue 2.3.2 operations have typed sync/async coverage; production contract verification remains explicitly credential-gated.

Versioned, searchable documentation is published at schapman1974.github.io/pyquestblue.

Install

pip install pyquestblue

For local development:

git clone https://github.com/schapman1974/pyquestblue.git
cd pyquestblue
python -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
pytest

Quick start

QuestBlue uses HTTP Basic authentication plus a Security-Key header. Credentials can be passed directly or loaded from QUESTBLUE_USERNAME, QUESTBLUE_PASSWORD, and QUESTBLUE_SECURITY_KEY.

from questblue import DIDAvailabilityRequest, DIDType, QuestBlue

with QuestBlue("username", "password", "security-key") as qb:
    balance = qb.account.balance()
    available = qb.dids.available(
        DIDAvailabilityRequest(did_type=DIDType.LOCAL, zip=27513, total_list=10)
    )
    trunks = qb.sip_trunks.list(per_page=100)

Send an SMS/MMS:

result = qb.sms.send(
    did=15551234567,
    did_to=15557654321,
    msg="Hello from pyquestblue",
    file_url=["https://example.com/image.png"],
)

Retrieve typed call history:

from questblue import CallHistoryRequest, Period

calls = qb.reports.call_history(
    CallHistoryRequest(
        period=Period.THIS_MONTH,
        trunk=["primary", "backup"],
        timezone="America/New_York",
        per_page=5000,
    )
)

Async applications use the same resource layout:

from questblue import AsyncQuestBlue, DIDListRequest

async with AsyncQuestBlue() as qb:
    inventory = await qb.dids.list(DIDListRequest(per_page=200))

Typed models preserve new upstream fields instead of dropping them, and paginators offer both item iteration and raw page access:

from questblue import QuestBlueModel, model_parser


class CallRecord(QuestBlueModel):
    call_id: str


records = qb.paginate(
    "/callhistory",
    params={"period": "today", "per_page": 500},
    item_parser=model_parser(CallRecord),
)
for record in records:
    print(record.call_id)

See docs/modeling.md for validation, forward compatibility, raw payloads, and custom pagination selectors.

See docs/transport.md for retry safety, per-request controls, raw responses, transport errors, structured logging, and OpenTelemetry hooks.

See docs/account.md for typed balance, rates, refill, alert, and callback operations, including explicit safeguards around billable balance changes.

See docs/dids.md for typed Voice DID discovery, ordering, E911/DLDA configuration, pagination, fraud validation, and destructive-operation safeguards.

See docs/international-dids.md for country/city discovery, international inventory pagination, ordering, routing updates, and release safeguards.

See docs/sip-trunks.md for registration/static trunks, routing controls, status troubleshooting, channel options, and blocked callers.

See docs/sms.md for SMS/MMS sending, inbound settings, delivery and history, off-net service, carrier lookup, PII-safe diagnostics, and compliance safeguards.

See docs/dlc.md for 10DLC brand and campaign registration, lifecycle states, upstream rejection detail, protected registration data, and compliance safeguards.

See docs/fax.md for Fax.Pro discovery, inventory lifecycle, validated document sending, email permissions, migration safeguards, and executable examples.

See docs/enterprise-fax.md for typed iFax Enterprise account, group, user, permission, upload, multi-file send, and lifecycle workflows.

See docs/reports.md for typed voice and fax history, large-result iteration, incremental fax downloads, and CSV/pandas-friendly exports.

See docs/lnp.md for typed portability checks, LNP lifecycle operations, validated bill uploads, sensitive-data handling, and production-only safeguards.

See docs/servers.md for typed server provisioning, IP allowlists, upgrades, backup schedules, restoration, and destructive/billable safeguards.

See docs/contract-testing.md for sanitized recorded fixtures, production risk classes, explicit live-test gates, and the verification matrix.

See docs/integrations.md for inbound messaging webhooks, FastAPI and Django adapters, safe observability, and white-label integration boundaries.

See docs/compatibility.md, SUPPORT.md, and SECURITY.md for supported platforms, SemVer and deprecation guarantees, the release process, support boundaries, and private vulnerability reporting.

Every resource method accepts the parameter names from QuestBlue's API documentation. List values are serialized as comma-separated values, matching QuestBlue's generated Node client. For an API addition that has not yet received a convenience method, the authenticated transport remains usable:

result = qb.request("GET", "/new-endpoint", params={"example": "value"})

Resource map

SDK resource QuestBlue areas
qb.account balance, details, rates, refill, alerts, callbacks
qb.dids inventory, availability, ordering, configuration, fraud validation
qb.international_dids countries, cities, inventory, ordering
qb.sip_trunks trunks, registration status, blocked callers
qb.sms SMS/MMS, settings, history, delivery, off-net orders, carrier checks
qb.dlc 10DLC brands and campaigns
qb.fax Fax.Pro inventory, sending, email permissions
qb.enterprise_fax iFax Enterprise accounts, groups, users, permissions, files
qb.reports voice CDRs, fax history, fax downloads
qb.lnp portability checks and LNP request lifecycle
qb.servers server inventory, IPs, upgrades, backup lifecycle

API coverage contract

The normalized QuestBlue OpenAPI 2.3.2 contract is pinned under spec/. A deterministic coverage report under coverage/ maps every upstream HTTP operation to its SDK method, sync/async availability, request/response model status, unit tests, and documentation. CI rejects missing or extra operations, broken sync/async parity, or a stale report.

python scripts/api_coverage.py --check
python scripts/update_openapi.py --check  # compares against the live QuestBlue contract

Errors and retries

The client retries safe reads after connection failures, HTTP 408/409/429 responses, and server errors with bounded exponential backoff. Mutating and potentially billable requests are never retried automatically. QuestBlue's documented HTTP 206 error responses are raised as exceptions. Catch QuestBlueAPIError for API failures or a narrower transport class. The complete contract is documented in docs/transport.md.

Publishing

  • Every push and pull request is tested on Python 3.10 through 3.14.
  • Publishing a GitHub Release triggers Publish to PyPI.
  • Publishing uses a PyPI API token stored as an encrypted secret in the protected pypi GitHub environment. Build-provenance attestations continue to use GitHub OIDC.

Before the first release, add PYPI_API_TOKEN to the pypi GitHub environment. Never place the token in source, workflow files, command-line arguments, issue comments, or chat messages.

White-label platform direction

The SDK is intentionally UI-framework neutral so it can power a fully rebranded customer portal. That portal should sit behind your own backend rather than exposing QuestBlue credentials in a browser. The major platform layers will be tenant/customer mapping, roles and permissions, branded catalog and pricing, ordering/provisioning workflows, usage and billing, audit logs, webhook/event processing, and support tooling. The evidence-backed white-label capability analysis, tenant-isolation ADR, and follow-on backlog define what belongs in the SDK, an optional control plane, or the application. See ROADMAP.md for the staged build-out.

Security

Never expose QuestBlue credentials to frontend code or commit them to source control. Use scoped secrets in a backend service and rotate them if they are disclosed. Please report SDK security issues privately to the repository owner.

License

MIT

Download files

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

Source Distribution

pyquestblue-1.0.0.tar.gz (253.0 kB view details)

Uploaded Source

Built Distribution

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

pyquestblue-1.0.0-py3-none-any.whl (54.6 kB view details)

Uploaded Python 3

File details

Details for the file pyquestblue-1.0.0.tar.gz.

File metadata

  • Download URL: pyquestblue-1.0.0.tar.gz
  • Upload date:
  • Size: 253.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pyquestblue-1.0.0.tar.gz
Algorithm Hash digest
SHA256 849be7bae30bff7618bc55f172c48c5d8e1194eece682c3b8ef4b0877baae7fc
MD5 636503fd374ef53f0d6501c0a874b9b0
BLAKE2b-256 3b9fa9cceccc11f3d68e6c196ebc3def2516244924f3f81c040280963bbe58c7

See more details on using hashes here.

File details

Details for the file pyquestblue-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pyquestblue-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 54.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pyquestblue-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b73b674ac080d242ab5a87ca2879773f1dd13a08394cad4631edcc8d60520594
MD5 6df998d0a01d34286f82cc8b76d89e66
BLAKE2b-256 e00cc5834dde7364ff6c3c60eb3f146182bc442e9f3fff0268f095b81bcbd0b8

See more details on using hashes here.

Release history Release notifications | RSS feed

1.1.0

2 files

This release

1.0.0 This release

2 files

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