Documentation

Lovely Router serves the native Anthropic, OpenAI and Gemini APIs. Point your SDK's base URL at https://lovelyrouter.com and use a key from the dashboard.

curl https://lovelyrouter.com/v1/messages \
  -H "x-api-key: $LOVELY_KEY" -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-sonnet-4.6","max_tokens":256,"messages":[{"role":"user","content":"Hi"}]}'

Endpoints

POST/v1/messagesAnthropic Messages (streaming, thinking, tools, cache_control)
POST/v1/messages/count_tokensAnthropic token counting (free)
POST/v1/chat/completionsOpenAI Chat Completions
POST/v1beta/models/{model}:generateContentGemini (also :streamGenerateContent, :countTokens)
GET/v1/modelsModel list with prices and groups (OpenAI + Anthropic shape)

Auth: Authorization: Bearer, x-api-key, or x-goog-api-key — whatever your SDK sends. Model names are forgiving: claude-sonnet-4.6, claude-sonnet-4-6 and anthropic/claude-sonnet-4.6 all resolve.

A request is only sent to upstreams that natively speak its dialect — there is no format translation. The only edits we make are the upstream model id and the channel pin, plus asking OpenAI-format streams to include usage.

Channel groups

Every route belongs to a group with an explicit channel source (Anthropic official, AWS Bedrock, Vertex, Azure, vendor-official China APIs…). Bind a key to a group when creating it and every request on that key is served from that channel only — failover stays inside the group. Unbound keys can pick per request with x-lovely-group: claude-bedrock, or let us choose (official channels first).

Conversation affinity

Prompt caches live on a specific upstream. We fingerprint each conversation (system prompt + first user turn, or your explicit session id) and pin it to the route that served it for an hour, so follow-up turns read the cache instead of re-writing it elsewhere. To control this explicitly send x-session-id, Anthropic metadata.user_id, or OpenAI prompt_cache_key.

Billing & usage

Prepaid. Each call is billed from the usage the upstream returns — uncached input, output (incl. reasoning), cache reads and cache writes at their own rates — times the group multiplier. Requests are refused with 402 once your balance reaches zero. Streams cancelled mid-way are billed for what was generated. Every call appears in Logs with its tokens, cost, TTFT and throughput.

Response headers

x-lovely-request-id: req_…      # quote this in support requests
x-lovely-group:      claude-bedrock
x-lovely-channel:    AWS%20Bedrock
x-lovely-route:      claude-bedrock:claude-sonnet-4.6:openrouter

Errors

Errors come back in your SDK's own error shape. Upstream errors are passed through verbatim.

401  invalid or revoked key
402  insufficient balance / key spend limit reached
404  unknown model, or model not served in this dialect/group
429  upstream rate limit (after failover within the group)
5xx  upstream unavailable (after failover within the group)