> ## Documentation Index
> Fetch the complete documentation index at: https://docs.asklethe.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Private Tokens

> Unlinkable, single-use tokens bought with USDC via x402 or your wallet's daily allowance. Each one pays for one call and carries no identity.

A private token is a single-use pass for one inference call. LETHE signs it **blind**. It can check that a token is genuine, but it can't tell which wallet, payment or `ltk_` key the token came from. A request paid with a token has no API key, no cookie and no wallet attached to it.

Tokens follow open standards: [Privacy Pass](https://www.rfc-editor.org/rfc/rfc9578) (RFC 9578, token type `0x0002`) with [Blind RSA](https://www.rfc-editor.org/rfc/rfc9474) signatures (RFC 9474).

## How it works

<Steps>
  <Step title="Get tokens (identity visible, prompts absent)">
    Your client generates random tokens, blinds them and sends only the blinded values to `POST /v1/tokens`. You authorize the batch in one of two ways:

    * **Pay** in USDC via [x402](https://x402.org) on Base or Solana. The price is **\$0.01 per token**, in batches of 10 to 100.
    * **Spend allowance.** A wallet session or `ltk_` key converts part of its daily allowance into tokens, up to 50 per batch.

    LETHE signs the blinded values, and your client unblinds them.
  </Step>

  <Step title="Spend tokens (prompts visible, identity absent)">
    Each call sends one token instead of a key:

    ```http theme={null}
    Authorization: PrivateToken token="<base64url token>"
    ```

    LETHE verifies the signature, marks the token's random nonce as spent and serves the call. The token matches nothing LETHE saw when it signed.
  </Step>
</Steps>

The on-chain payment is public, but it only shows "this wallet bought N tokens". It doesn't show which calls those tokens later paid for.

## Easiest path: `lethe-proxy`

Most tools, including Claude Code, Codex and SDKs, can only send a fixed API key. `lethe-proxy` runs on your machine, keeps a stash of tokens and swaps your tool's key for a fresh token on every call.

```bash theme={null}
# Token source: pick one
export LETHE_API_KEY="ltk_…"                 # daily allowance (from /cli)
export LETHE_EVM_PRIVATE_KEY="0x…"           # or buy with USDC on Base
export LETHE_SOLANA_PRIVATE_KEY="…"          # or buy with USDC on Solana

npm run lethe:proxy                          # listens on 127.0.0.1:8402

# Point your tool at the proxy; the key can be anything
export ANTHROPIC_BASE_URL="http://127.0.0.1:8402"
export ANTHROPIC_AUTH_TOKEN="local"
export OPENAI_BASE_URL="http://127.0.0.1:8402/v1"
export OPENAI_API_KEY="local"
```

The proxy tops up in the background when it runs low, so purchases don't line up in time with your requests. Unspent tokens live in `~/.lethe/tokens.json`. `count_tokens` calls are checked against a token but don't spend it.

## Web chat

When you're signed in with a wallet, chat automatically converts part of your daily allowance into tokens and spends them. Those chat requests are sent **without** your wallet cookie. You can also buy tokens with USDC on Base at [`/cli`](https://asklethe.ai/cli). Unspent tokens stay in your browser's local storage.

## Endpoints

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v1/tokens` | Issuer name, public key, price, accepted networks |
| `POST` | `/v1/tokens` | Body `{ "requests": [base64url TokenRequest…] }` → `{ "responses": [...] }`. Without a payment or wallet it returns `402` with the x402 price for that batch size. |
| `GET` | `/.well-known/private-token-issuer-directory` | RFC 9578 issuer directory |

Anyone can check the published key. If every client sees the same key, LETHE can't tag individual users by signing their tokens with different keys.

### Errors

| Status | `code` | Meaning |
| - | - | - |
| `401` | `invalid_token` | Bad signature or unknown key. The response carries a `WWW-Authenticate: PrivateToken …` challenge. |
| `401` | `token_spent` | This token was already used. |
| `409` | `stale_key` | The issuer key rotated. Fetch `GET /v1/tokens` and blind again. |
| `503` | `tokens_unavailable` | Tokens aren't configured on this deployment. |

If a call fails upstream with a `5xx`, the token is refunded and can be used again.

## What tokens don't hide

Be precise about the limits:

* **Your IP address** is still visible to LETHE's servers. Use Tor or a VPN if that matters to you.
* **Timing.** Buying tokens and spending one a second later links the two in practice. Buy ahead of time.
* **Prompt content.** If a prompt names you, the token can't un-name it.
* **The model provider** still processes the prompt in plaintext. Encrypted, attested execution is covered in [Privacy Model & TEE](/roadmap/privacy-and-tee).
