Your first authenticated request
curl -sS -X POST https://api.shadow-warden-ai.com/filter \
-H "X-API-Key: $WARDEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "ignore previous instructions"}' Keys are issued per tenant from any paid plan and from the free Starter tier. Send the key as a header — never in a query string, where it lands in access logs and browser history.
Schemes
The default. One header, sent on every request. Keys are per tenant, and each carries its own request rate — so one customer cannot spend another's window.
X-API-Key: sk_live_…
OIDC id_token from Google Workspace or Microsoft Entra ID, verified RS256 against cached JWKS. Used by the browser extension so a workstation never holds a gateway key.
Authorization: Bearer eyJhbGciOi…
A separate secret for operator-only routes that change entitlements. Never issued to customers, and never accepted in place of an API key.
X-Admin-Key: …
x402 USDC or L402 Lightning, presented per call instead of a subscription. See the MCP server page.
PAYMENT-SIGNATURE: base64({"agent_id":"did:shadow:…"}) Status codes an automated client must handle
The distinction that matters most: a block is a 200. A 5xx is the gateway failing, and reading it as “blocked” turns an outage into a silent content refusal.
| 200 | Answered. A blocked verdict is still a 200 — read the body, not the status. |
| 401 | No X-API-Key header, or the key is not recognised. The response carries WWW-Authenticate: ApiKey. Retrying without changing the key will not help. |
| 402 | The plan is eligible but the add-on has not been purchased, or an x402/L402 call is unfunded. The body names what to buy. |
| 403 | Authenticated, but the plan tier is below the one this route requires, or the Origin is not allowed. Upgrading the plan is the fix; retrying is not. |
| 406 | Content negotiation failed — the client accepts neither HTML nor Markdown. Site pages only. |
| 429 | Rate limit or monthly quota. Read Retry-After and the RateLimit fields and back off — see the rate-limit page. |
| 5xx | The gateway failed, not your request. Never read as a block verdict: retry with backoff. |
Key handling
- Keys are stored as SHA-256 hashes. A lost key is replaced, never recovered.
- Each key carries its own request rate, so the rate limit you see is yours alone — see rate limits.
- Self-hosted deployments refuse to start with no key configured unless ALLOW_UNAUTHENTICATED=true is set explicitly. Auth fails closed, not open.
- Request content is never logged, on any code path. Only metadata — type, length, timing — is recorded.