Skip to main content

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:

TierWhat it guaranteesCoverage
standard (default)Never routed to a provider that trains on your prompts. Providers may still retain them.Every model
zdrOnly providers that retain nothing.Subset — see the ZDR filter in the model catalog
privateRuns 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. Chat, messages and image responses carry an X-Privacy-Tier header (standard, zdr or private) naming the tier the request was resolved to — including a request that then fails at that tier.

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.3-flash",
"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.3-flash:zdr
glm-5.3-flash: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; --zdr or --private lists only those.

4. The account setting​

Turn on zero data retention for every request on the account, from every client, under Settings on the LLM Gateway page. 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.

Applies within ~60s

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:

LegacyEquivalent
"zdr": true"privacy": "zdr"
"private": true"privacy": "private"
:private suffix:private suffix (unchanged)

Errors​

StatusCodeMeaning
400privacy_conflictThe 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.
400invalid_privacyprivacy isn't one of standard, zdr, private, or zdr / private isn't a boolean. Rejected rather than served at a weaker tier.
422zdr_unavailableNo provider for this model can guarantee zero retention. Pick a model with the ZDR badge.
422confidential_unavailableThe model has no TEE slot — or, on /v1/images/generations, image generation has no confidential route at all.
503attestation_unverifiedThe enclave's attestation couldn't be verified, so the request wasn't sent. Retry shortly.

Next steps​