Execute AI Request
Proxy an AI request through the gateway with phantom-token auth, streaming PII redaction, prompt firewall, budget enforcement, and shape translation.
curl --request POST \
--url https://{tenant}.knoxcall.com/v1/ai/{agentSlug}/{upstreamPath} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Summarise this ticket."
}
]
}
'{}AI Gateway
The AI Gateway is KnoxCall’s AI-native proxy layer. It sits between your applications and upstream AI providers (Anthropic and OpenAI are the configurable providers; Bedrock is supported only as a shape-translation target), providing:- Phantom tokens — short-lived DPoP-bound capability tokens; your application never holds a raw provider API key.
- Streaming PII redaction — Aho-Corasick + Presidio detector stack with a configurable hold-back buffer.
- Prompt injection firewall — built-in heuristic patterns + tenant-supplied regex/keyword rules; optional canary token injection detects system-prompt extraction.
- Budget enforcement — per-agent daily/monthly USD caps with configurable overage actions.
- Shape translation — automatic Anthropic ↔ OpenAI request/response translation when routes target a different provider format.
- Compliance packs — HIPAA Safe Harbor, GDPR, PCI-DSS, and SOC 2 packs install recognizers and audit-log alert rules in one operation.
Authentication
All AI Gateway proxy endpoints authenticate via phantom tokens — capability tokens minted for a specific agent. Send the token via any of the three accepted header schemes:Authorization: Bearer kp_live_a_...
x-api-key: kp_live_a_...
x-knox-ai-key: kp_live_a_...
DPoP header on every request.
Gateway and agent CRUD, token minting, firewall policies, MCP servers and usage are control-plane operations and are served on two different surfaces:
| Surface | Base | Credential |
|---|---|---|
| Public Management API (use this) | https://api.knoxcall.com/v1/ai-gateway | An OAuth 2.1 access token (Authorization: Bearer kc_live_…), or a legacy tk_… / AKE… API key. Covered by all five SDKs and the control-plane overview. |
| Dashboard admin API | /admin/ai-gateway on the admin host | A session-authenticated request with the X-Tenant-ID header and an owner/admin role. This is what the dashboard itself calls; a few operations exist only here (they are called out where that is the case). |
/v1/ai-gateway/* shipped: the /v1 surface authenticates with the same credentials as the rest of the Management API.
Execute AI request
POST https://{slug}.knoxcall.com/v1/ai/{agent-slug}/{...path}
https://{slug}.knoxcall.com (sandbox: https://sandbox-{slug}.knoxcall.com), not api.knoxcall.com. Use the agent_url returned when the agent was created as the base URL.
Forwards the request to the agent’s configured primary route. The request body must be a valid JSON body for the upstream provider (Anthropic Messages API, OpenAI Chat Completions API, etc.).
If the agent has streaming_enabled and the request asks the provider to stream — "stream": true in the body, or Gemini’s :streamGenerateContent endpoint — the response is streamed as SSE. An Accept: text/event-stream header on its own does not stream: it asks nothing of the provider, so the response is served buffered (and fully redacted). Streaming is available on the endpoints whose event stream KnoxCall redacts mid-stream — Anthropic /v1/messages, OpenAI-compatible /chat/completions, Gemini :streamGenerateContent — and is refused with 400 streaming_redaction_unsupported elsewhere (for example the OpenAI Responses API); send those requests without stream: true.
Request headers
| Header | Description |
|---|---|
Authorization: Bearer kp_live_a_... | Phantom token for this agent. May alternatively be sent via the x-api-key or x-knox-ai-key header. |
DPoP | DPoP proof JWT (required when the token has dpop_required: true). |
X-KC-User | Optional. The person’s workspace-directory key, for per-user cost attribution: their SCIM externalId (or userName when the IdP sends none), otherwise a member’s KnoxCall email. Resolves only while that person is a member; otherwise the response carries X-Knox-AI-Attribution: user_unregistered. |
X-KC-Conversation-Id | Optional. Conversation identifier for PII token-map scoping across turns. |
Response headers
| Header | Description |
|---|---|
X-Request-Id | UUID identifying this proxy call (appears in audit logs). |
X-Knox-AI-Budget-Pct | Current budget utilization percentage (when budget is configured). |
X-Knox-AI-Budget-Warning | Present when utilization exceeds the warn threshold. |
X-Knox-AI-Tools-Stripped | Comma-separated names of tools removed by the agent’s tool allowlist. |
X-Knox-AI-Output-Warning | Present when the response fails output schema validation but output_validation_action is warn. |
X-Knox-AI-Retry | Set to output_schema when the response was automatically retried due to schema violation. |
Firewall responses
When the prompt injection firewall blocks a request,HTTP 400 in the data
plane’s one error envelope:
{
"error": "firewall_block",
"error_description": "Request blocked by firewall policy: ignore_previous_instructions, dan_jailbreak",
"code": "firewall_block"
}
error and code always carry the same identifier — branch on either. Every
refusal this endpoint can return, and whether to retry it, is on the
errors page.
The firewall always runs — the built-in heuristics cannot be disabled and they scan every request. What a policy decides is the outcome. With no firewall policy attached to the agent, the outcome is capped at warn: a match is recorded and the request still reaches the upstream. block requires a firewall policy attached to the agent with action: "block". Create one via POST /v1/ai-gateway/firewall-policies and set the agent’s firewall_policy_id.
Shape translation
When the caller’s provider format differs from the route’s target provider format, the AI Gateway translates automatically:| From | To | What changes |
|---|---|---|
| Anthropic | OpenAI | system field → system message; input_schema → parameters; tool choice shape |
| OpenAI | Anthropic | Leading system message → system field; parameters → input_schema |
| Any | Bedrock | Strips model from body; adds anthropic_version: "bedrock-2023-05-31" |
target_base_url (e.g. api.anthropic.com → Anthropic format). Response shapes are translated back to match the caller’s expected format on the buffered path.
Canary token injection
When a firewall policy hascanary_enabled: true, the gateway injects a kc_canary_<16hex> token into every system prompt before forwarding upstream. If the model echoes the token verbatim in its response (a sign of system-prompt extraction via prompt injection), the gateway:
- Emits an
ai_gateway.canary_leakaudit log entry atcriticalseverity. - Records the policy’s own action as
firewall_outcomeon the usage record —blockwhen the attached policy’s action isblock, otherwisewarn. (Before AIGW-171 this was hard-coded towarn, so a tenant who had configuredblockread their own firewall report as saying the control had held.) - On a
blockpolicy, refuses the response rather than serving it. A canary echo is not a heuristic guess about intent: the token is a value KnoxCall generated, put in the system prompt, and never gave the caller. Buffered, that is400 canary_leak. Streamed, the200has already gone out, so the stream stops at the frame carrying the leak and ends with anevent: errorframe whosecodeiscanary_leak— nothing after the leak is delivered, and anything sent before it contained no canary. The refusal reports amatched_count, never the token itself. - Fires any compliance-pack alert rules listening on
audit_action = 'ai_gateway.canary_leak'.
[REDACTED:CANARY]), on the buffered path and mid-stream — except in the
monitor streaming mode, which passes the response through unredacted by
design and only inspects it once it has finished.
Compliance packs
Install compliance packs via the Packs API or from the Admin UI. Each pack installs:- PII recognizers — entity-type patterns for the detector stack.
- Alert rules —
ai_gateway_eventalerts that fire when specific audit actions appear.
hipaa-safe-harbor, gdpr, pci-dss, soc2.
OpenTelemetry export
SetOTEL_EXPORTER_OTLP_ENDPOINT to enable per-request span export with GenAI semantic conventions:
| Attribute | Value |
|---|---|
gen_ai.system | Provider (e.g. anthropic) |
gen_ai.request.model | Requested model |
gen_ai.usage.input_tokens | Input token count |
gen_ai.usage.output_tokens | Output token count |
knoxcall.ai_gateway.firewall_outcome | pass / warn / block / tag |
knoxcall.ai_gateway.pii_tokens_swapped | Count of PII redactions |
knoxcall.ai_gateway.cost_usd | Estimated cost in USD |
Authorizations
The AI data plane credential — a kp_-prefixed capability token, not a
Management API credential. It is minted per agent (or per MCP resource) at
POST /v1/ai-gateway/agents/{agentId}/tokens, or exchanged from a CI workload's
OIDC token at POST /v1/oauth/token, and it is the ONLY credential /v1/ai/*
accepts: an OAuth kc_ access token or a tk_ API key is refused there, and a
kp_ token is refused on api.knoxcall.com.
Three header spellings are accepted, so an existing provider SDK can be pointed at the agent URL without rewriting its auth:
Authorization: Bearer kp_live_a_...
x-api-key: kp_live_a_...
x-knox-ai-key: kp_live_a_...
kp_live_ is refused on the sandbox host and kp_test_ on the Live host — the env
segment is enforced, not cosmetic. DPoP-bound tokens additionally require a valid
DPoP proof header on every request, signed over the canonical public URL rather
than a rewritten Host.
A rejected credential answers 401/403 in the data-plane error envelope with the
cause in code and in the X-Auth-Failure response header.
Path Parameters
The agent's slug. Selects the upstream route, the policies and the budget.
^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$The provider's own path, forwarded verbatim — including its slashes, which
OpenAPI cannot express as a single path segment. v1/messages for Anthropic,
v1/chat/completions for OpenAI-shaped providers, v1beta/models/{model}:generateContent
for Gemini. Everything after /v1/ai/{agentSlug}/ is the upstream path
(src/ai-gateway/route-matcher.ts), so the gateway adds no path of its own.
Body
The upstream provider's own request body, forwarded after screening.
The body is of type object.
Response
The provider's own response, passed through after response-side screening.
text/event-stream when the call was streamed.
The response is of type object.
Was this page helpful?
curl --request POST \
--url https://{tenant}.knoxcall.com/v1/ai/{agentSlug}/{upstreamPath} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Summarise this ticket."
}
]
}
'{}