knoxcall/knoxcall-php is the official KnoxCall client for PHP. Requires PHP >= 8.1 with ext-curl + ext-json — no other runtime dependencies.
Install
Not yet published to Packagist — install from the monorepo via a Composer path repository or a git checkout.
Create a client
'sandbox' => true (uses https://sandbox.knoxcall.com + https://sandbox-{tenant}.knoxcall.com; requires a tk_test_… key). Conflicting explicit options (e.g. api_key + client_id) throw at construction.
Token caching under PHP-FPM: typical deployments are per-request processes, so under
client_credentials each request mints one token. If that matters, mint out of band, cache it yourself (APCu/Redis), and construct with ['access_token' => $cached]. Long-running workers (CLI, queues, Octane) get in-process caching with refresh-ahead automatically. DPoP-bound OAuth clients are not supported — the SDK fails fast with a clear error; use a Bearer client or the Node.js / Python SDK.Manage resources
Create a route, then list with pagination — single-object methods returndata unwrapped; paginated list() methods return the {data, meta} envelope; iterate() walks all pages:
secrets, webhooks, clients, oauthClients, environments, apiKeys, account, auditLogs, agents, crypto, pki, vaults, and dynamicDb.
Call routes through the proxy
call() proxies a request through a KnoxCall route to your upstream and returns the raw response (['status', 'headers', 'body']) — upstream HTTP errors are never thrown; they belong to you. Reference routes by slug (write-once, rename-proof); UUIDs also work.
kc_) keys automatically travel as the x-knoxcall-key header instead of Authorization: Bearer.
Bound routes
State the route (and optional defaults) once, then use plain HTTP verbs:Verify webhooks
constructEvent() verifies the delivery AND parses it in one step — use it in your webhook endpoint with the RAW request body:
legacy, stripe, github, slack, aws-sns, and custom (pass header_name). All are HMAC-SHA256 with constant-time comparison.
Handle errors
KnoxCallException (base) → ApiException (with ->statusCode, ->errorCode, ->requestId, ->responseHeaders, ->responseBody) → AuthenticationException (401), PermissionDeniedException (403), NotFoundException (404), ConflictException (409), ValidationException (422, with ->fields), RateLimitException (429, with ->retryAfter), ServerException (5xx), SignupException; plus ConnectionException / ConnectionTimeoutException (transport) and WebhookSignatureVerificationException. Every ApiException carries the server’s request_id — include it when contacting support.
Retries and idempotency
Management requests retry HTTP 408/429/500/502/503/504 (never 409) with half-jitter exponential backoff, honoringRetry-After up to 30s; a 401 purges the cached token and re-auths once. Every mutating request carries a ULID X-Idempotency-Key that stays stable across retries. Data-plane calls never replay a mutation that may have reached the upstream. Configure with retry_max_attempts, retry_base_delay_ms, retry_max_delay_ms, timeout_ms.
Full reference
The package README documents every resource method, the ephemeral proxy, crypto/PKI/vault operations, and credential-lessKnoxCall::signup(): sdk/knoxcall-php/README.md in the monorepo.