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/messages | Anthropic Messages (streaming, thinking, tools, cache_control) |
| POST | /v1/messages/count_tokens | Anthropic token counting (free) |
| POST | /v1/chat/completions | OpenAI Chat Completions |
| POST | /v1beta/models/{model}:generateContent | Gemini (also :streamGenerateContent, :countTokens) |
| GET | /v1/models | Model 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)