> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDKs Overview

> Official KnoxCall SDKs for Node.js, Python, Go, PHP, and Ruby — plus a Terraform provider and browser Elements — all held to one behavioral standard.

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

| Package                                                   | Runtime                                 | Surface                                    |
| --------------------------------------------------------- | --------------------------------------- | ------------------------------------------ |
| [`@knoxcall/sdk`](/sdks/node)                             | Node.js ≥ 18, TypeScript-first          | Full management + data plane               |
| [`knoxcall`](/sdks/python)                                | Python ≥ 3.10, sync **and** async       | Full management + data plane               |
| [`knoxcall-go`](/sdks/go)                                 | Go, stdlib only (zero dependencies)     | Full management + data plane               |
| [`knoxcall/knoxcall-php`](/sdks/php)                      | PHP ≥ 8.1, `ext-curl` + `ext-json` only | Full management + data plane               |
| [`knoxcall`](/sdks/ruby)                                  | Ruby ≥ 3.1, stdlib only                 | Full management + data plane               |
| [`terraform-provider-knoxcall`](/sdks/terraform)          | Terraform (Plugin Framework)            | Routes, secrets, clients, webhooks as code |
| [`@knoxcall/browser` + `@knoxcall/react`](/sdks/elements) | Any modern browser / React ≥ 18         | Client-side sealing + iframe Elements      |

<Warning>
  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.
</Warning>

## 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](/getting-started/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:

```bash theme={"dark"}
# 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_..."
```

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { KnoxCall } from "@knoxcall/sdk";

  const client = new KnoxCall(); // credentials from the environment
  ```

  ```python Python theme={"dark"}
  from knoxcall import KnoxCall

  client = KnoxCall()  # credentials from the environment
  ```

  ```go Go theme={"dark"}
  import "github.com/knoxcall/knoxcall-go/knoxcall"

  client, err := knoxcall.New(knoxcall.Options{}) // credentials from the environment
  ```

  ```php PHP theme={"dark"}
  use KnoxCall\KnoxCall;

  $client = new KnoxCall(); // credentials from the environment
  ```

  ```ruby Ruby theme={"dark"}
  require "knoxcall"

  client = KnoxCall::Client.new # credentials from the environment
  ```
</CodeGroup>

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

| Variable                                        | Meaning                                                                                                  |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `KNOXCALL_CLIENT_ID` / `KNOXCALL_CLIENT_SECRET` | OAuth client-credentials grant                                                                           |
| `KNOXCALL_API_KEY`                              | pre-acquired key or token (`KNOXCALL_ACCESS_TOKEN` is an equivalent spelling and wins when both are set) |
| `KNOXCALL_TENANT`                               | tenant slug (optional — auto-discovered when unset)                                                      |
| `KNOXCALL_ENVIRONMENT`                          | default environment for data-plane calls                                                                 |
| `KNOXCALL_BASE_URL`                             | management API base override                                                                             |
| `KNOXCALL_PROXY_BASE_URL`                       | data-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

<CardGroup cols={2}>
  <Card title="Node.js / TypeScript" icon="hexagon" href="/sdks/node">
    `@knoxcall/sdk` — fully typed, DPoP, workload identity, token stores
  </Card>

  <Card title="Python" icon="worm" href="/sdks/python">
    `knoxcall` — one import, sync or async, thread- and fork-safe
  </Card>

  <Card title="Go" icon="zap" href="/sdks/go">
    `knoxcall-go` — stdlib only, context-first, goroutine-safe
  </Card>

  <Card title="PHP" icon="server" href="/sdks/php">
    `knoxcall/knoxcall-php` — PHP-FPM aware token handling
  </Card>

  <Card title="Ruby" icon="gem" href="/sdks/ruby">
    `knoxcall` gem — Mutex-safe for Puma and Sidekiq
  </Card>

  <Card title="Terraform" icon="layers" href="/sdks/terraform">
    Routes, secrets, clients, and webhooks as code
  </Card>

  <Card title="Browser Elements" icon="app-window" href="/sdks/elements">
    Seal PANs and PII in the page; reveal with single-use capability tokens
  </Card>
</CardGroup>
