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.
export ANONROUTER_API_KEY="ar_..."
export ANONROUTER_API_URL="https://api.anonrouter.ai/v1"
export ANONROUTER_CONTROL_URL="https://control.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_CONTROL_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_API_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
api_url = os.environ.get("ANONROUTER_API_URL", "https://api.anonrouter.ai/v1").rstrip("/")
control_url = os.environ.get(
"ANONROUTER_CONTROL_URL",
"https://control.anonrouter.ai/v1",
).rstrip("/")
api_key = os.environ["ANONROUTER_API_KEY"]
ticket_response = httpx.post(
f"{control_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"]
# The real key was used only for the content-free ticket request. The OpenAI
# client requires a non-empty api_key, so use a non-secret placeholder here.
client = OpenAI(api_key="ticket-only", base_url=api_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, use a key with
compatibility mode enabled and point the OpenAI SDK straight
at https://api.anonrouter.ai/v1 with no ticket. New keys enable compatibility
by default. Review the privacy tradeoff first.
Next steps
- Read authentication to understand keys and tickets.
- Browse the model catalog and privacy labels.
- Use
/autorouting to let AnonRouter pick a model. - Control reasoning effort per request.
Or hand the whole thing to your agent
One prompt carries the entire setup. Give it to your agent, review what it configures, and you are done.