Skip to main content

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.

The Ephemeral Proxy is a single endpoint — ANY /v1/proxy — that accepts any HTTP method and forwards the request to the URL you supply in the X-Knox-Proxy-URL header. References of the form {{ token: ... }} in the body or query string are resolved against your tenant’s vaults before the request reaches the upstream. For a conceptual overview see the Ephemeral Proxy guide.
Unlike the Routes endpoints — which manage proxy configuration — this endpoint executes a one-shot proxy call. There is no id to look up, no row to list, and no environment overrides.

Invoke

ANY /v1/proxy
Forwards the request to the URL in X-Knox-Proxy-URL. Body and query-string {{ token: ... }} references are resolved against your tenant’s vaults before the upstream call is made. The upstream response is streamed back unchanged.

Request Headers

HeaderRequiredDescription
AuthorizationYesBearer tk_live_... — your KnoxCall API key.
X-Knox-Proxy-URLYesThe upstream URL. Must be https://, must use a DNS hostname (no IP literals), must pass SSRF validation.
Content-TypeNoDefaults to application/json if omitted. Non-JSON bodies are sent as-is for string content.
X-Knox-EncryptedNoBase64-encoded JSON payload addressable from templates via {{ encrypted | json: $.path }}. v1 is opaque base64-JSON; full JWE support is on the roadmap.
X-Knox-Timeout-MsNoPer-request upstream timeout. Positive integer ≤ 30000. Defaults to 25000.
All other headers you send are forwarded to the upstream except for hop-by-hop headers (Connection, Keep-Alive, TE, Trailers, Transfer-Encoding, Upgrade, Proxy-Authorization, Proxy-Authenticate), the Authorization and Host headers, and any header beginning with X-Knox-.

Request Body

Optional. Sent to the upstream after token substitution. The body is scanned recursively for two template forms:
TemplateResolves to
{{ token: tok_xxx }}The raw value stored under token tok_xxx in any of your tenant’s vaults.
{{ encrypted | json: $.path }}The value at JSONPath $.path inside the decoded X-Knox-Encrypted payload.
Maximum 20 distinct token references per request.

Response

The upstream’s response is streamed back unchanged: same status code, same headers (minus hop-by-hop and Content-Length), same body bytes. KnoxCall adds two correlation headers:
Response HeaderDescription
X-Knox-Request-IdThe KnoxCall request ID. Use it to look up the audit log entry.
X-Knox-Destination-StatusThe upstream’s status code, echoed in case an intermediate CDN rewrites it.
curl -X POST https://api.knoxcall.com/v1/proxy \
  -H "Authorization: Bearer tk_live_abc123..." \
  -H "X-Knox-Proxy-URL: https://api.stripe.com/v1/charges" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "usd",
    "source": "{{ token: tok_01HZX... }}"
  }'

Errors

StatusTypeDescription
400validation_errorMissing or malformed X-Knox-Proxy-URL, invalid X-Knox-Timeout-Ms, malformed X-Knox-Encrypted, or more than 20 token references.
400token_not_foundA {{ token: ... }} reference does not exist in any of your tenant’s vaults.
400template_errorA template expression failed to render (malformed JSONPath, missing key in encrypted payload, etc.).
402plan_limitEphemeral Proxy requires the Starter plan or above.
403forbiddenThe upstream URL failed SSRF validation (private IP range, metadata endpoint, non-HTTPS, etc.).
502upstream_errorThe upstream did not respond, returned an unrecoverable transport error, or timed out.

Templates

{{ token: <token-id> }}

Substituted with the raw value of the matching vault token. Tokens are tenant-globally unique — you do not need to specify the vault.
{
  "card_number": "{{ token: tok_01HZX0M... }}",
  "exp_month": 12
}
If the token doesn’t exist or you lack vault:detokenize permission for the vault that owns it, the request fails with 400 token_not_found.

{{ encrypted | json: $.path }}

Reads a value from the decoded X-Knox-Encrypted payload using JSONPath. Useful when you want to keep ad-hoc sensitive values out of your application’s heap.
# Encode the payload your application would otherwise put directly in the body
PAYLOAD=$(echo -n '{"customer_id":"cus_123","cvc":"492"}' | base64)

curl -X POST https://api.knoxcall.com/v1/proxy \
  -H "Authorization: Bearer tk_live_abc123..." \
  -H "X-Knox-Proxy-URL: https://api.stripe.com/v1/payment_methods" \
  -H "X-Knox-Encrypted: $PAYLOAD" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "{{ encrypted | json: $.customer_id }}",
    "card": { "cvc": "{{ encrypted | json: $.cvc }}" }
  }'
In v1 the payload is opaque base64-encoded JSON; full JWE with per-tenant frontend keypairs is on the roadmap.

Permissions

Each invocation evaluates two permissions:
ResourceActionWhen evaluated
ephemeral_proxyinvokeOnce per request, before URL validation.
vaultdetokenizePer token reference, scoped to the vault that owns the token.
The vault:detokenize check is currently advisory (logged, not enforced) — enforcement lands when the per-vault permissions stage ships.

Audit

Every invocation writes:
  • An api_requests row with proxy_mode = 'ephemeral', status code, latency, upstream host, source IP, and token count. The body, headers, and resolved token values are never stored.
  • An audit_log entry tagged ephemeral_proxy.invoke (Audit Logs).
  • A Fleet Graph signal carrying method, upstream host, status code, and latency. The customer’s path is recorded as /proxy — never the raw upstream path.