Lovely RouterDocs
Get a key
API reference

API reference

Base URLs, authentication, request conventions, limits and retry guidance that apply to every Lovely Router endpoint.

Lovely Router serves two kinds of API from one host, with one key and one balance:

  • Model APIs in the vendors' own formats: Anthropic Messages, OpenAI Chat Completions and Gemini. Requests and responses follow the vendor's API reference, so the official SDKs work unchanged. Lovely Router adds a few response headers.
  • Lovely Router APIs for data tools (/v1/tools) and the browser agent (/v1/browser): JSON APIs with the conventions described below.

Base URLs#

All endpoints are served over HTTPS from https://lovelyrouter.com.

APISDK base URLEndpoints
Anthropic Messageshttps://lovelyrouter.comPOST /v1/messages, POST /v1/messages/count_tokens
OpenAI Chat Completionshttps://lovelyrouter.com/v1POST /v1/chat/completions
Geminihttps://lovelyrouter.comPOST /v1beta/models/{model}:generateContent, :streamGenerateContent, :countTokens
Model list—GET /v1/models, GET /v1beta/models
Data toolshttps://lovelyrouter.com/v1/v1/tools/...
Browser agenthttps://lovelyrouter.com/v1/v1/browser/...
Music videoshttps://lovelyrouter.com/v1/v1/videos/music/...
MCP server—POST /mcp

Endpoints not listed here, such as OpenAI's Responses, Embeddings and Images APIs, return 404.

Authentication#

Send your API key as a bearer token. The model endpoints also accept the vendors' own headers, so each SDK works with its defaults.

HTTP
Authorization: Bearer lr-...
HeaderTypical use
Authorization: Bearer lr-...OpenAI SDK, data tools, browser agent, MCP
x-api-key: lr-...Anthropic SDK
x-goog-api-key: lr-...Google Gen AI SDK

The model list and the tool catalog need no key. Everything else does. See Authentication.

Requests and responses#

  • JSON in, JSON out. Send request bodies as JSON with content-type: application/json. The exceptions are file uploads to the browser agent, which take the raw file or multipart/form-data, and run screenshots, which return image/jpeg.
  • Streaming. Anthropic and OpenAI requests with "stream": true return server-sent events (text/event-stream). Gemini's :streamGenerateContent streams a JSON array, or server-sent events with ?alt=sse, as Google's API does. See Streaming.
  • Cross-origin requests are allowed from any origin. That doesn't make it safe to call the API from a browser: anyone can read a key shipped in front-end code.

Lovely Router's own APIs follow these conventions:

ConventionExample
Ids carry a type prefixrun_… for tool runs, brun_… for browser runs
Timestamps are ISO 8601 in UTC"created_at": "2026-10-11T09:30:00.000Z"
Money is in US dollars, as numbers"charge_usd": 0.042, "reserved_usd": 0.3
Lists are wrapped in an object{"object": "list", "data": [...]}
Long-running work returns 202The body includes a poll path to check on it
Waiting is a query parameterGET /v1/tools/runs/{id}?wait=60 holds the request until the run finishes or the time is up

Response headers#

Model responses carry these headers in addition to the vendor's:

HeaderMeaning
x-lovely-request-idUnique id of the request, also shown in Logs. Include it when you contact support.
x-lovely-groupThe channel group that served the request
x-lovely-channelA short, URL-encoded description of that channel group
x-lovely-queued-msMilliseconds the request waited for capacity, when it had to wait
retry-afterOn 429 responses: seconds to wait before retrying

Versioning#

Model APIs follow the vendor's versioning. Send the headers your SDK sends: anthropic-version and anthropic-beta for Anthropic, and openai-beta for OpenAI. Gemini requests use the /v1beta path, as Google's API does. Lovely Router forwards these headers and no others, so features that depend on a different vendor header aren't available.

Lovely Router APIs are versioned by path and live under /v1. New fields can appear in responses, so write clients that ignore fields they don't recognise.

Rate limits#

These limits apply to your requests:

LimitApplies toWhen exceeded
Requests per minute and concurrency you set on a keyModel requests from that key429 with retry-after
Model capacityModel requests. Short bursts wait in a queue for a few seconds first.429, usually with retry-after
10 runs in progress per accountData tool and browser runs429
100 requests per minute per key; 100 per minute shared by all callers without a keyPOST /v1/tools/suggest429 with retry-after

See Rate limits & failover and API keys.

Retries and idempotency#

Lovely Router retries failed model requests on other channels before it returns an error, so a 5xx you receive has already been retried. It's still worth retrying 429 and 5xx responses yourself with exponential backoff, honouring retry-after. Don't retry other 4xx errors without changing the request. The official OpenAI and Anthropic SDKs retry twice by default; raise max_retries (maxRetries in Node.js) for batch jobs.

The API doesn't take idempotency keys. Plan for these cases:

  • A model request that times out on your side may still have completed and been charged. If you retry, you may pay twice. Use generous client timeouts for long generations, or stream.
  • Starting a tool or browser run is not idempotent. If POST /v1/tools/{id}/run or POST /v1/browser/runs times out, list your recent runs with GET /v1/tools/runs or GET /v1/browser/runs before starting another.
  • Reading is always safe to repeat. Polling a run, listing runs and fetching results never charge.

Retry code in Python and Node.js is in Retry failed requests.

Errors#

Model endpoints return errors in the vendor's format, so SDKs raise their usual exceptions. Lovely Router's own APIs return:

JSON
{"error": {"type": "invalid_request_error", "message": "\"goal\" is required (max 4,000 characters)"}}

Every status code, with sample bodies for each format, is in Errors.