API Documentation

OpenAI-compatible endpoints. Drop-in replacement for most AI tools.

Base URL

https://lumirouter.com/v1

Authentication

Preferred: Create an account (accepts Terms + Privacy) and save the lr_… key shown once. API clients use Authorization: Bearer YOUR_API_KEY. The site/dashboard also uses an HTTP-only lr_session cookie.

Authorization: Bearer YOUR_API_KEY

Legacy: POST /v1/keys still issues a one-shot email key without a password account (see below).

Accounts

Full account API under /v1/auth/*. Technical reference: repo docs/api.md.

Register

POST/v1/auth/register

Requires accepted_terms: true. Password min 8 characters. Returns api_key once and sets session cookie.

curl -X POST https://lumirouter.com/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"at-least-8","accepted_terms":true}'

Login / logout / me

POST/v1/auth/login
POST/v1/auth/logout
GET/v1/auth/me
curl -X POST https://lumirouter.com/v1/auth/login \
  -H "Content-Type: application/json" \
  -c cookies.txt -d '{"email":"you@example.com","password":"…"}'

Password reset

Forgot password → email link → reset-password.html?token=…. Valid emails get a generic 200 (anti-enumeration). Token is single-use, ~1 hour.

POST/v1/auth/forgot-password
POST/v1/auth/reset-password
curl -X POST https://lumirouter.com/v1/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com"}'

Rotate API key

POST/v1/auth/rotate-key

Session or Bearer required. Old key stops working immediately; BYOK stays with the new key. Dashboard: API Key → Rotate key. Limit: 5 / hour.

curl -X POST https://lumirouter.com/v1/auth/rotate-key \
  -H "Authorization: Bearer YOUR_LUMIROUTE_KEY"

Claim account (legacy key)

POST/v1/auth/claim-account

Already have a key from POST /v1/keys? Claim your account with email + key + password. Same lr_… key is kept. Requires accepted_terms: true.

curl -X POST https://lumirouter.com/v1/auth/claim-account \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","api_key":"lr_…","password":"at-least-8","accepted_terms":true}'

Issue API key (legacy)

POST/v1/keys

No auth. One key per email (shown once). IP limit: 5 / hour. Prefer register for new users. To rotate an account key, use rotate-key.

curl -X POST https://lumirouter.com/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com"}'

Bring Your Own Key (BYOK)

Recommended. Register your Groq/DeepSeek/Gemini/OpenAI keys once, then use only the LumiRoute API key in Cursor/Cline. You keep provider billing and ToS; we add routing + an OpenAI-compatible gateway.

1. Register keys (KV)

curl -X POST https://lumirouter.com/v1/byok/keys \
  -H "Authorization: Bearer YOUR_LUMIROUTE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"groq":"gsk_...","deepseek":"sk_...","gemini":"AIza...","openai":"sk-..."}'

Check status (secrets never returned):

curl https://lumirouter.com/v1/byok/keys \
  -H "Authorization: Bearer YOUR_LUMIROUTE_KEY"
{ "configured": { "groq": true, "deepseek": false, "gemini": true, "openai": true } }

Omit a field to leave it unchanged; send "" to delete that provider key.

2. Cursor (~30 seconds)

  1. Settings → Models → OpenAI API Key = LumiRoute key only (not Groq/Gemini/OpenAI sk)
  2. Override OpenAI Base URL = https://lumirouter.com/v1
  3. Add custom model: auto, lr-gemini-2.5-flash, or byok/openai/gpt-6.1-sol
  4. Do not pick Cursor’s built-in Auto or built-in Gemini — those bypass LumiRoute
  5. Do not put image models (e.g. byok/openai/gpt-image-2) in Cursor chat — use Images instead

3. Cline

  1. API Provider = OpenAI Compatible
  2. Base URL = https://lumirouter.com/v1
  3. API Key = LumiRoute key
  4. Model = auto, lr-gemini-2.5-flash, or byok/openai/gpt-6.1-sol
  5. Optional: set X-LumiRoute-*-Key headers if you prefer not to use KV

4. Header override (curl)

Authorization: Bearer YOUR_LUMIROUTE_KEY
X-LumiRoute-Groq-Key: gsk_...
X-LumiRoute-DeepSeek-Key: sk_...
X-LumiRoute-Gemini-Key: AIza...
X-LumiRoute-OpenAI-Key: sk-...

Headers override KV for that request.

5. Free-route failover

On upstream 401 / 402 / 403 / 429 / 503, we try the next BYOK provider, then Cloudflare Workers AI: Groq → Gemini → DeepSeek → OpenAI → CF. Check lumiroute.route_reason in the JSON response.

Image generation (OpenAI BYOK)

LumiRoute Images API (JSON). Use POST /v1/images (alias: /v1/images/generations). Image models are not valid on /v1/chat/completions. Requires OpenAI BYOK.

POST/v1/images

Text → image (no references):

curl https://lumirouter.com/v1/images \
  -H "Authorization: Bearer YOUR_LUMIROUTE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "byok/openai/gpt-image-2",
    "prompt": "A product photo of a ceramic mug on a white table",
    "size": "1024x1024"
  }'

Image input → edit — same endpoint with input_references. We forward to OpenAI /v1/images/edits. Each ref is a data URL or https URL:

curl https://lumirouter.com/v1/images \
  -H "Authorization: Bearer YOUR_LUMIROUTE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "byok/openai/gpt-image-2",
    "prompt": "Keep the product; replace the background with a warm sunset",
    "input_references": [
      {
        "type": "image_url",
        "image_url": { "url": "data:image/png;base64,...." }
      }
    ]
  }'

Optional fields: n, quality, size, response_format, background, output_format, mask (data/https URL for edits). Up to 16 reference images (GPT Image models).

Image model ids:

In your app: POST https://lumirouter.com/v1/images with model + prompt; add input_references when you have a source image.

Health Check

GET/health

No auth. Returns Cloudflare availability, BYOK hint, and whether operator secrets exist (not used publicly).

curl https://lumirouter.com/health

Endpoints

POST/v1/keys

Legacy email key issue (see above). Prefer register + rotate-key for accounts.

POST/v1/auth/rotate-key

Rotate gateway key (see Accounts).

POST/v1/chat/completions

Send a chat completion request. Fully OpenAI-compatible. stream: true pipes live SSE from upstream (Groq/Gemini/DeepSeek/OpenAI/CF). Image models are rejected here — use Images.

POST/v1/images

OpenAI Images BYOK (generate + edit via input_references). Alias: /v1/images/generations. See Image generation.

GET/v1/models

List all available models including auto-routing options and image models.

POST/v1/byok/keys

Store or update your provider keys (see BYOK above).

GET/v1/byok/keys

Show which providers are configured (boolean only).

Auto-Router Models

ModelBehavior
autoSmart routing based on request content
auto-cheapAlways cheapest sufficient model
auto-codeCode-focused model (DeepSeek Coder)
auto-qualityHighest quality model available

Available Models

ModelProvider
deepseek-chatDeepSeek
deepseek-coderDeepSeek
deepseek-reasonerDeepSeek
openai/gpt-oss-20bGroq
openai/gpt-oss-120bGroq
lr-gemini-2.5-flashGemini (use this in Cursor, not built-in Gemini)
lr-gemini-3.6-flashGemini
byok/openai/gpt-6-lunaOpenAI chat (BYOK)
byok/openai/gpt-6.1-solOpenAI chat (BYOK)
byok/openai/gpt-6-astraOpenAI chat (BYOK)
byok/openai/o4-miniOpenAI reasoning (BYOK)
byok/openai/o3OpenAI reasoning (BYOK)
byok/openai/gpt-4.1 / gpt-4.1-miniOpenAI chat (BYOK)
byok/openai/gpt-4o / gpt-4o-miniOpenAI chat (BYOK)
byok/openai/gpt-image-2OpenAI Images — use /v1/images/generations
byok/openai/gpt-image-1.5 / gpt-image-1 / gpt-image-1-miniOpenAI Images
byok/openai/dall-e-3 / dall-e-2OpenAI Images
cf-granite-microCloudflare
cf-llama-3.2-1bCloudflare
cf-llama-3.2-3bCloudflare
cf-gpt-oss-20bCloudflare
cf-gpt-oss-120bCloudflare
cf-mistral-small-24bCloudflare
cf-qwen3-30bCloudflare
cf-qwen2.5-coder-32bCloudflare
cf-qwq-32bCloudflare
cf-deepseek-r1-32bCloudflare
cf-llama-4-scoutCloudflare
cf-llama-3.3-70bCloudflare

Example Request

curl https://lumirouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [
      {"role": "user", "content": "Write a Python function to reverse a string"}
    ]
  }'

Routing Info in Response

When using auto models, the response includes a lumiroute field:

{
  "model": "deepseek-coder",
  "choices": [...],
  "lumiroute": {
    "requested_model": "auto",
    "routed_model": "deepseek-coder",
    "provider": "deepseek",
    "route_reason": "code keywords detected"
  }
}

Tool Compatibility

Works with any tool that supports custom OpenAI-compatible endpoints:

Set base URL to https://lumirouter.com/v1 and use your LumiRoute API key.