Docs
Open App

Compatibility mode

Point an OpenAI SDK at AnonRouter with a static key and no ticket.

Compatibility mode lets an off-the-shelf OpenAI client talk to AnonRouter with a plain Authorization: Bearer key and no ticket step. A dedicated broker accepts the key, mints a single-use ticket internally, and forwards the request. It is the simplest way to integrate, at a cost to unlinkability.

Privacy tradeoff

Compatibility mode moves the ticket exchange inside the confidential broker. The broker receives your API-key identity and plaintext request together in memory, then mints and redeems the one-use authorization on your behalf. It logs metadata only and holds no database or provider credentials, but this flow is not unlinkable like the private ticket flow.

Key setting

Compatibility mode is gated two ways:

  1. The operator must enable it on the deployment. Check GET /v1/auth/capabilities, which reports compat.enabled.
  2. The individual inference key must be marked for OpenAI-compatible access. The dashboard selects this by default when you create a key, and lets you turn it off for a ticket-only credential.

A key created with the setting off receives a permission_error telling you to use the ticket flow or create a compatibility-enabled key.

Use the OpenAI SDK

Point the SDK at the router base URL and pass your key. Do not send a ticket header. Sending both a key and a ticket is rejected.

from openai import OpenAI

client = OpenAI(
    api_key="ar_your-compat-enabled-key",
    base_url="https://api.anonrouter.ai/v1",
    max_retries=0,
)

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

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

Disable automatic SDK retries (max_retries=0 in Python, maxRetries: 0 in JavaScript). An ambiguous disconnect can follow a paid generation; automatically repeating it can create another charge. A ticket is single-use and cannot be replayed as an idempotency key.

Streaming works normally. The stream ends with data: [DONE] only after billing has settled. If a stream fails, the broker closes the connection without a final [DONE], so treat an early end as an incomplete response.

What works in compatibility mode

EndpointSupported
POST /v1/chat/completionsYes, streaming and non-streaming
POST /v1/embeddingsYes
GET /v1/modelsYes, as a plain bearer call to the control plane
POST /v1/completionsNo, returns 404. Use chat completions.
POST /v1/images/generationsNo, use the Studio flow
POST /v1/audio/speechNo, use the Studio flow

OpenAI-compatible, not Anthropic

AnonRouter exposes the OpenAI Chat Completions surface. There is no Anthropic Messages endpoint. Models from any creator, including Claude-family routes, are reached by their model id through POST /v1/chat/completions.

Request restrictions

The compatibility broker forwards requests through the same strict chat and embeddings contract as the ticket flow:

  • Chat accepts text strings or arrays of text and image_url parts. Image parts belong on user messages and require a vision-capable model and route.
  • Images may use HTTPS URLs or base64 data: URLs containing PNG, JPEG, WebP, or GIF. E2EE requests do not support image content.
  • Unknown top-level chat fields are stripped rather than forwarded. Fields such as n, logprobs, and logit_bias are not honored. Embeddings has its own strict schema.
  • Legacy functions and function_call are stripped. Use tools and tool_choice; your client executes tools and sends their results back.
  • response_format supports JSON object and JSON Schema shapes where the provider supports them; the provider, rather than AnonRouter, enforces the requested output schema.
  • The model must be enabled and support the operation. A catalog listing does not imply every provider route supports images, tools, or reasoning controls.

Image input example

This uses the client configured above and a local image. Choose a currently callable vision-capable model from the catalog and set its id in ANONROUTER_VISION_MODEL.

import base64
import os
from pathlib import Path

image = base64.b64encode(Path("image.png").read_bytes()).decode("ascii")
completion = client.chat.completions.create(
    model=os.environ["ANONROUTER_VISION_MODEL"],
    max_completion_tokens=256,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Describe this image."},
            {"type": "image_url", "image_url": {
                "url": f"data:image/png;base64,{image}",
                "detail": "auto",
            }},
        ],
    }],
)
print(completion.choices[0].message.content)

Keep images within the selected provider's limits. AnonRouter accepts at most 10 image parts per message, HTTPS URLs up to 2,048 characters, and data URLs up to 7,000,000 characters, subject to the deployment's overall request size limit. Image bytes are request content; they are forwarded to the provider without being logged or persisted.

Error format

Errors use the OpenAI error envelope:

{
  "error": {
    "message": "This API key is not enabled for OpenAI-compatible access.",
    "type": "permission_error",
    "param": null,
    "code": "compat_scope_required"
  }
}

The type is one of authentication_error, permission_error, invalid_request_error, insufficient_quota, rate_limit_error, or api_error. The HTTP status code is authoritative. Server-class errors carry a generic message so no internal detail leaks.

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.

On this page