Claude Code through zer0pii (API-key mode)

Rendered from docs/dev-tools/claude-code.md. Documents are rendered as written in the repository.

Claude Code can be pointed at any gateway that speaks the Anthropic Messages format. zer0pii's POST /v1/messages route is that format (source: apps/gateway/api/v1/proxy.py), so the setup is two environment variables plus, optionally, a third for your Anthropic key.

Coverage boundary, stated first

This works only in API-key mode. If you use Claude Code with a claude.ai subscription login (Pro, Max, or a Team seat), the gateway is not in the path in any meaningful sense:

When a gateway credential is set, the subscription is not used: "the credential replaces the subscription login for that session, and the subscription's usage limits don't apply. That traffic is billed per token to whoever owns the credential the gateway forwards" (same page). So the zer0pii path is for teams whose Claude Code usage is billed to an Anthropic Console (API) account, or who are willing to move to that.

Setup

Variable names below are from code.claude.com/docs/en/llm-gateway-connect (read 2026-09-22).

1. Get a zer0pii key

Console, API keys (/console/keys), Issue key. Copy it now; it is shown once.

2. Pick the credential variable

Claude Code offers two, and they land in different headers:

Variable Sent as Use with zer0pii?
ANTHROPIC_AUTH_TOKEN Authorization: Bearer <value> Yes. zer0pii reads its key from Authorization: Bearer zpii_... (source: apps/gateway/core/auth.py).
ANTHROPIC_API_KEY x-api-key: <value> No. The gateway does not read its own key from x-api-key; you would get 401 INVALID_API_KEY.

The doc's own rule of thumb matches: "Your gateway team said 'bearer token' or 'Authorization header'" means ANTHROPIC_AUTH_TOKEN.

3. Set the base URL and the credential

The base URL is the gateway root without /v1. Claude Code appends /v1/messages itself (the connect page's verification command posts to $ANTHROPIC_BASE_URL/v1/messages).

macOS / Linux:

export ANTHROPIC_BASE_URL=https://api.zer0pii.com
export ANTHROPIC_AUTH_TOKEN=zpii_...

Windows PowerShell:

$env:ANTHROPIC_BASE_URL = "https://api.zer0pii.com"
$env:ANTHROPIC_AUTH_TOKEN = "zpii_..."

Or persistently, in ~/.claude/settings.json (the doc says a settings-file env value wins over a shell export):

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.zer0pii.com",
    "ANTHROPIC_AUTH_TOKEN": "zpii_..."
  }
}

Self-hosted: replace https://api.zer0pii.com with your gateway's origin.

4. Give the gateway your Anthropic key

Two options; pick one.

a. The gateway holds it (recommended for teams). Your admin sets UPSTREAM_ANTHROPIC_API_KEY in the gateway's .env (source: .env.example, apps/gateway/core/providers.py). Developers never handle the Anthropic key. Nothing more to set on the developer's machine.

b. Per developer, per request. Claude Code can attach extra headers with ANTHROPIC_CUSTOM_HEADERS (one Name: Value per line; documented on the same connect page). zer0pii reads the provider key from X-zer0pii-Upstream-Key (source: proxy.py):

export ANTHROPIC_CUSTOM_HEADERS="X-zer0pii-Upstream-Key: sk-ant-..."

In settings.json, separate multiple headers with \n inside the string. The same variable is where you would add X-zer0pii-Conversation-ID or X-zer0pii-Policy-Group if you use them.

5. Verify

Start claude from the same shell, send any prompt, then run /status. On the Status tab the doc says to check two lines: Anthropic base URL should show the gateway, and an Auth token line naming ANTHROPIC_AUTH_TOKEN confirms the gateway credential is active "rather than a saved claude.ai login". If a Login method line names a claude.ai account instead, you are still on the subscription and nothing is masked: run /logout to clear the saved login, as the doc advises.

Then follow verify.md to prove masking end to end.

Known limits of this path

Read before rolling out; each is a fact about today's gateway, not a promise.