Skip to main content
KnoxCall ships first-party SDKs for five server languages, a Terraform provider, and browser Elements packages. The five core SDKs implement the same behavioral standard, adapted to each language’s idiom — switching languages (or running a polyglot stack) never changes semantics.

Language support

PackageRuntimeSurface
@knoxcall/sdkNode.js ≥ 18, TypeScript-firstFull management + data plane
knoxcallPython ≥ 3.10, sync and asyncFull management + data plane
knoxcall-goGo, stdlib only (zero dependencies)Full management + data plane
knoxcall/knoxcall-phpPHP ≥ 8.1, ext-curl + ext-json onlyFull management + data plane
knoxcallRuby ≥ 3.1, stdlib onlyFull management + data plane
terraform-provider-knoxcallTerraform (Plugin Framework)Routes, secrets, clients, webhooks as code
@knoxcall/browser + @knoxcall/reactAny modern browser / React ≥ 18Client-side sealing + iframe Elements
The SDK packages are not yet published to npm, PyPI, Packagist, or RubyGems. Until they are, install from the KnoxCall monorepo by path or git — each language page shows the exact command. The code and APIs on these pages are final; only the registry publish is pending.

What every SDK guarantees

The core SDKs are held to a single parity spec (sdk/PARITY.md in the monorepo), with test coverage required for each behavior:
  • Automatic retries — HTTP 408, 429, 500, 502, 503, 504 retried with exponential half-jitter backoff; Retry-After honored 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-Key generated 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) — Node.js and Python auto-upgrade to DPoP when the OAuth client requires it (dpop: "auto", the default) and support "always". Go, PHP, and Ruby do not sign DPoP proofs yet: they fail fast with a clear typed error rather than mis-authenticating — use a Bearer OAuth client with those SDKs.
  • 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 return data unwrapped; paginated lists take page / 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; legacy tk_… / AKE… keys automatically travel as x-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 sandbox constructor option targets the isolated Test environment (sandbox.knoxcall.com management host, sandbox-{tenant}.knoxcall.com proxy host) with a tk_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. Set the environment once and construct with zero arguments:
# OAuth client-credentials grant (recommended for servers)
export KNOXCALL_CLIENT_ID="tk_xxxxxxxx"
export KNOXCALL_CLIENT_SECRET="..."

# — or — a single pre-acquired key/token (kc_…, tk_…, or AKE…)
export KNOXCALL_API_KEY="tk_live_..."
import { KnoxCall } from "@knoxcall/sdk";

const client = new KnoxCall(); // credentials from the environment
You do not need to configure a tenant: management calls resolve it server-side from the credential, and the data-plane hostname is auto-discovered on first proxy call. Passing tenant (or setting KNOXCALL_TENANT) just skips the discovery lookup.

Canonical environment variables

VariableMeaning
KNOXCALL_CLIENT_ID / KNOXCALL_CLIENT_SECRETOAuth client-credentials grant
KNOXCALL_API_KEYpre-acquired key or token (KNOXCALL_ACCESS_TOKEN is an equivalent spelling and wins when both are set)
KNOXCALL_TENANTtenant slug (optional — auto-discovered when unset)
KNOXCALL_ENVIRONMENTdefault environment for data-plane calls
KNOXCALL_BASE_URLmanagement API base override
KNOXCALL_PROXY_BASE_URLdata-plane base override
Node.js and Python additionally auto-detect workload identity (GitHub Actions, GCP, AWS IRSA, Azure Managed Identity, Vercel, and other CI OIDC issuers) when no explicit credentials are present — zero stored secrets in CI.

Pick your language

Node.js / TypeScript

@knoxcall/sdk — fully typed, DPoP, workload identity, token stores

Python

knoxcall — one import, sync or async, thread- and fork-safe

Go

knoxcall-go — stdlib only, context-first, goroutine-safe

PHP

knoxcall/knoxcall-php — PHP-FPM aware token handling

Ruby

knoxcall gem — Mutex-safe for Puma and Sidekiq

Terraform

Routes, secrets, clients, and webhooks as code

Browser Elements

Seal PANs and PII in the page; reveal with single-use capability tokens