anonrouterdocs

Quickstart

Make your first ticketed chat completion with AnonRouter.

Before you begin

You need an AnonRouter inference API key. Create one in the dashboard, keep it on a trusted server, and load it from an environment variable. Inference keys are prefixed ar_ and are shown only once at creation.

Create an API key
export ANONROUTER_API_KEY="ar_..."
export ANONROUTER_BASE_URL="https://api.anonrouter.ai/v1"

Do not expose API keys in browsers

The examples below are for trusted server-side environments. A browser client should call your own backend, which holds the key.

1. Request a single-use ticket

The ticket binds the request to its model and output limit. Issue a new ticket for every inference request. Tickets are valid for 30 seconds, so issue one and send the completion promptly.

TICKET=$(curl -s "$ANONROUTER_BASE_URL/inference/tickets" \
  -H "Authorization: Bearer $ANONROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/llama-3.3-70b",
    "max_completion_tokens": 256
  }' | jq -r .ticket)

The response contains an opaque ticket string plus the constraints it was bound to (model, max_output_tokens, operation, privacy_class, reasoning, and expires_in).

2. Send the completion

Present the ticket to the relay in the x-anonrouter-ticket header. The relay does not need your API key. The model and output limit must match the ticket.

curl "$ANONROUTER_BASE_URL/chat/completions" \
  -H "Content-Type: application/json" \
  -H "x-anonrouter-ticket: $TICKET" \
  -d '{
    "model": "meta-llama/llama-3.3-70b",
    "max_tokens": 256,
    "messages": [
      {
        "role": "user",
        "content": "Explain private model routing in one paragraph."
      }
    ]
  }'

The response is a standard OpenAI chat completion object. Two headers report the selection: x-anonrouter-selected-model and x-anonrouter-routing.

With the OpenAI SDK

The OpenAI SDKs work against the same base URL. Issue the ticket with a plain HTTP call, then pass it as an extra header on the completion. The SDK still sends your key as a bearer token, which the relay ignores in favor of the ticket.

import os
import httpx
from openai import OpenAI

base_url = os.environ.get(
    "ANONROUTER_BASE_URL",
    "https://api.anonrouter.ai/v1",
).rstrip("/")
api_key = os.environ["ANONROUTER_API_KEY"]

ticket_response = httpx.post(
    f"{base_url}/inference/tickets",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "meta-llama/llama-3.3-70b",
        "max_completion_tokens": 256,
    },
)
ticket_response.raise_for_status()
ticket = ticket_response.json()["ticket"]

client = OpenAI(api_key=api_key, base_url=base_url, max_retries=0)

completion = client.chat.completions.create(
    model="meta-llama/llama-3.3-70b",
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello from AnonRouter"}],
    extra_headers={"x-anonrouter-ticket": ticket},
)

print(completion.choices[0].message.content)

Prefer a static key?

If your client cannot perform the ticket step, enable compatibility mode on the key and point the OpenAI SDK straight at https://api.anonrouter.ai/v1 with no ticket. Review the privacy tradeoff first.

Next steps

On this page