Language support
Registries and source
Each package’s registry page, and the public repository its source is mirrored to. The last two rows are the browser Elements packages.What every SDK guarantees
The core SDKs are held to a single written parity spec, with test coverage required for each behavior:- Automatic retries — HTTP 408, 429, 500, 502, 503, 504 retried with exponential half-jitter backoff;
Retry-Afterhonored on 429 (capped at 30s); 409 is never retried (a real conflict does not resolve by replaying). - Idempotency by default — every mutating request carries a ULID
X-Idempotency-Keygenerated once per logical request and stable across retries, so replays are safe. - Transparent 401 re-mint — a 401 purges the cached token and retries once with fresh credentials before surfacing an error. Long-lived processes never wedge on a revoked or rotated token.
- Token lifecycle — tokens cached per tenant + scope with single-flight refresh, refresh-ahead, and a stale-but-valid fallback when the token endpoint is briefly unreachable.
- DPoP sender-constrained tokens (RFC 9449) — every SDK auto-upgrades to DPoP when the OAuth client requires it (
dpop: "auto", the default) and supports"always": the SDK generates an ES256 keypair, binds the access token viacnf.jkt, and signs a fresh proof per request. - Shared CLI login — every SDK auto-detects the credentials file written by
knoxcall login(~/.knoxcall/credentials.json), with cross-process-safe rotation of the single-use refresh token. Sign in once; every language picks it up. - Secret redaction — client secrets, access tokens, and OIDC subject tokens never appear in debug output, logs, or error messages.
- Typed errors with request IDs — 401/403/404/409/422/429/5xx each map to a named error type carrying the server’s
request_id(quote it when contacting support). - Envelope + pagination — the server wraps JSON responses in
{data, meta}. Single-object methods returndataunwrapped; paginated lists takepage/per_page(default 20, cap 100) and return{data: [...], meta: {total, page, per_page, total_pages, request_id}}, with an iterator that walks every page for you. - Raw data plane — proxy calls (
call()/ bound routes /ephemeral()) return the raw HTTP response and never raise on the upstream’s status; legacytk_…/AKE…keys automatically travel asx-knoxcall-key. Mutating data-plane requests are never replayed after they may have reached the wire. - Webhook
constructEvent— verify the delivery’s HMAC-SHA256 signature and parse it into a typed event in one step, across all six signature formats (legacy,stripe,github,slack,aws-sns,custom), with constant-time comparison and replay protection. - Sandbox mode — a
sandboxconstructor option targets the isolated Test environment (sandbox.knoxcall.commanagement host,sandbox-{tenant}.knoxcall.comproxy host) with atk_test_key. - Credential-less
signup()— create an account headlessly with no constructed client (see AI agent onboarding).
Authentication quickstart
Every SDK resolves credentials the same way: explicit constructor options beat environment variables, and conflicting options fail at construction. On a developer machine, log in once with the CLI below and skip configuration entirely. For servers and CI, register an OAuth client (dashboard → Settings → Security → OAuth Clients), set the environment once, and construct with zero arguments:tenant (or setting KNOXCALL_TENANT) just skips the discovery lookup.
Legacy API keys still work everywhere: set
KNOXCALL_API_KEY to a long-lived key (tk_live_…, tk_test_…, AKE…) or a pre-acquired kc_… token instead of the client-credentials pair — or pass it to the constructor as apiKey / api_key. A pre-acquired key is sent as-is and never auto-renewed. Prefer knoxcall login or an OAuth client for new integrations — see Authentication.Log in once with the CLI
On a developer machine, skip credentials entirely. Every KnoxCall SDK package ships theknoxcall command via its own package manager (pip, npm, gem, Composer, go install) — same surface, same credentials file, so it doesn’t matter which one you install. Sign in once in your browser (authorization code + PKCE) and every script, notebook, and agent on the machine — in any of the five languages — picks the credential up automatically. No env vars, no keys in code:
~/.knoxcall/credentials.json (file mode 0600), and the stored tenant and base URL seed the client automatically — explicit constructor options and 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 its typed authentication error telling you to run knoxcall login again. Override the file path with KNOXCALL_CREDENTIALS_FILE; select a non-default profile with KNOXCALL_PROFILE.
Credential resolution order
With no explicit constructor credentials, every SDK resolves from the environment in priority order:KNOXCALL_ACCESS_TOKEN(orKNOXCALL_API_KEY) — a pre-acquired token- The credentials file written by
knoxcall login(~/.knoxcall/credentials.json) - Workload identity auto-detect — Node.js and Python only (GitHub Actions, GCP, AWS IRSA, Azure Managed Identity, Vercel, and other CI OIDC issuers); zero stored secrets in CI
KNOXCALL_CLIENT_ID+KNOXCALL_CLIENT_SECRET— client-credentials grant
Canonical environment variables
Pick your language
Node.js / TypeScript
@knoxcall/sdk — fully typed, DPoP, workload identity, token storesPython
knoxcall — one import, sync or async, thread- and fork-safeGo
github.com/knoxcall/sdk-go — stdlib only, context-first, goroutine-safePHP
knoxcall/sdk — PHP-FPM aware token handlingRuby
knoxcall gem — Mutex-safe for Puma and SidekiqTerraform
Routes, secrets, clients, and webhooks as code