knoxcall is the official KnoxCall client for Python. One import gives you a sync client (thread- and fork-safe, share it as a module-level singleton) or an async client for FastAPI and friends. Every method’s return shape is a TypedDict in knoxcall.types, so IDEs and mypy see the exact server fields.
Install
Not yet published to PyPI — install from the monorepo path or via git. Requires Python 3.10+.
Create a client
KNOXCALL_ACCESS_TOKEN / KNOXCALL_API_KEY), the credentials file written by knoxcall login (~/.knoxcall/credentials.json), workload identity (GitHub Actions, GCP, AWS IRSA, Azure Managed Identity, Vercel, CircleCI — no stored secrets in CI), then KNOXCALL_CLIENT_ID + KNOXCALL_CLIENT_SECRET.
Log in once with the CLI
The package ships theknoxcall command. Sign in once in your browser and every script, notebook, and agent on the machine picks the credential up automatically — no env vars, no keys in code:
~/.knoxcall/credentials.json (file mode 0600). The stored tenant and base URL seed the client automatically; explicit constructor arguments or env vars always win. Access tokens refresh themselves, and refreshes are cross-process safe (file lock + atomic rotation of the single-use refresh token). If a refresh fails because the credential was revoked or expired, the SDK raises AuthenticationError telling you to run knoxcall login again. Select a non-default profile with KNOXCALL_PROFILE (or StoredCredentials(profile=...)). The same file is picked up by all five SDKs — log in once, use any language.
Manage resources
Create a route, then list with pagination — single-object methods returndata unwrapped; paginated lists return the full {"data": [...], "meta": {...}} page; iterate() walks every page:
await. The same pattern covers every resource: secrets, webhooks, clients, oauth_clients, environments, api_keys, account, audit_logs, agents, crypto, pki, vaults, and dynamic_db.
Call routes through the proxy
client.call() proxies a request through a KnoxCall route to your upstream and returns the raw httpx.Response — the upstream’s HTTP status belongs to you; the SDK never turns it into an error. Reference routes by slug (write-once, rename-proof); UUIDs also work.
Bound routes
State the route (and optional defaults) once withclient.route(), then use plain HTTP verbs:
await printnode.get(...)). The handle holds no state beyond the defaults — retries, token refresh, and 401 re-mint behave exactly as on call().
Verify webhooks
construct_webhook_event verifies a delivery AND returns the parsed, typed event in one step. Pass the RAW request body (never re-serialized JSON):
format= matches the webhook’s configured hmac_format: "legacy" (default), "stripe", "github", "slack", "aws-sns", or "custom" (pass header_name=). tolerance_seconds (default 300) bounds replay; pass None to disable. Also available as client.webhooks.construct_event() on both facades.
Handle errors
PermissionDeniedError. Transport failures map to APIConnectionError / APIConnectionTimeoutError. Every API error carries the server’s request_id — quote it when contacting support.
Retries and idempotency
Management requests retry automatically on 408/429/500/502/503/504 with exponential backoff + jitter (3 attempts by default; never 409;Retry-After honored on 429, capped at 30s). Mutating requests get an auto-generated ULID idempotency key so retries are safe. A 401 triggers one transparent token re-mint. Data-plane transport failures retry only when safe: connection-refused always, later failures (read timeout, keepalive reset) only for GET/HEAD — a mutating request is never replayed.
DPoP
cnf.jkt, and signs a fresh proof on every request — both management calls and proxy call() requests. In the default "auto" mode it upgrades automatically when the OAuth client requires DPoP.
Full reference
The package README documents every resource method, the ephemeral proxy, Redis token store, request-body encoding (datetime / Decimal / UUID / set out of the box), thread-safety details, and credential-less signup() / signup_sync(): sdk/knoxcall-python/README.md in the monorepo.