Privacy Tiers
Three levels of data-handling guarantee, requested the same way on every endpoint.
The tiers strictly nest — each one contains the guarantees of the one below it:
| Tier | What it guarantees | Coverage |
|---|---|---|
standard (default) | Never routed to a provider that trains on your prompts. Providers may still retain them. | Every model |
zdr | Only providers that retain nothing. | Subset — see the ZDR filter in the model catalog |
private | Runs inside a hardware-secured enclave (TEE), attestation verified per request. Zero-retention by construction. | Open-weight models only |
Every tier fails closed. If no provider can serve your model at the tier you asked for, the request is rejected — it is never quietly downgraded to a weaker one.
Requesting a tier
There are four ways to ask, so that any client can reach any tier.
The account setting and a per-request ask combine strongest-wins — a request can tighten beyond the account setting, but nothing in a request can drop below it.
A tier endpoint is authoritative. If you send a request naming a different tier to /zdr or /private, it is rejected with 400 privacy_conflict rather than merged — in either direction. An integration pinned to a tier endpoint means exactly that tier, so it stays usable as an audit point. Sending no privacy option, or one that matches the endpoint, is fine.
1. The privacy request field
The documented form for anything that builds its own request body:
curl -X POST https://llm.bankr.bot/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-Key: bk_YOUR_API_KEY" \
-d '{
"model": "glm-5.2",
"privacy": "zdr",
"messages": [{"role": "user", "content": "Hello!"}]
}'
Accepted values: "standard", "zdr", "private". Works on /v1/chat/completions, /v1/messages, and /v1/images/generations.
2. A base-path prefix
For tools that let you set a base URL, an API key and a model — and nothing else. Put the tier in front of the path:
# OpenAI-compatible clients (base URL ends in /v1)
OPENAI_BASE_URL=https://llm.bankr.bot/zdr/v1
# Anthropic-compatible clients (Claude Code, OpenClaw — they append /v1/messages)
ANTHROPIC_BASE_URL=https://llm.bankr.bot/zdr
Every request through that base URL is served at the tier, with no per-request configuration. /private works the same way.
Requests to a tier endpoint must not also name a different tier — see privacy_conflict below. To mix tiers, use the privacy field against the default endpoint instead of a prefixed one.
3. A model-ID suffix
Also for clients you can't add a body field to, when you want the tier per model rather than per base URL:
glm-5.2:zdr
glm-5.2:private
Only a trailing tier token is treated as the opt-in, so unrelated model IDs are unaffected. Matching is case-insensitive — :ZDR and :Private work.
bankr llm setup <tool> --install writes these variants into the tool's model list for you, so they appear in the model picker alongside the plain ID. bankr llm models marks which models support which tier.
4. The account setting
Turn on zero data retention for every request on the account, from every client, under Settings in the LLM Gateway terminal. This is the only option that needs no client configuration at all.
The account setting can only tighten. Sending "privacy": "standard" against a ZDR-enabled account does not downgrade it.
The gateway caches authentication for about a minute, so a change can take up to 60 seconds to affect new requests. The toggle tells you this when you save it.
Legacy spellings
These predate the privacy field and remain fully supported:
| Legacy | Equivalent |
|---|---|
"zdr": true | "privacy": "zdr" |
"private": true | "privacy": "private" |
:private suffix | :private suffix (unchanged) |
Errors
| Status | Code | Meaning |
|---|---|---|
400 | privacy_conflict | The endpoint already selects a tier and the request asked for a different one. Drop the privacy option, or use the endpoint for the tier you want. |
422 | zdr_unavailable | No provider for this model can guarantee zero retention. Pick a model with the ZDR badge. |
422 | confidential_unavailable | The model has no TEE slot — or, on /v1/images/generations, image generation has no confidential route at all. |
503 | attestation_unverified | A TEE provider served the request but its attestation could not be verified. |
Next steps
- Private Inference — attestation flow, response headers, and client-side verification
- API Reference — full endpoint documentation