Documentation
Use one WLRouter API Key for connected chat, Responses, image, video, audio, embedding, and rerank models.
Get started
Quickstart
Create an API Key in Console, set it as a server-side environment variable, then call the OpenAI-compatible endpoint. Never put API Keys in browser code.
export WLROUTER_API_KEY="wlrouter_..."import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["WLROUTER_API_KEY"],
base_url="https://api.wlrouter.com/v1",
)
response = client.chat.completions.create(
model="anthropic.claude-sonnet-4.6",
stream=False,
messages=[{"role": "user", "content": "Write a one sentence product summary."}],
)
print(response.choices[0].message.content)Keys
Authentication
Send a WLRouter API Key with every request. API Keys are scoped to a workspace and can be disabled or deleted from Console.
- Base URL
- https://api.wlrouter.com/v1
- Authentication
- Send Authorization: Bearer <wlrouter_api_key> with every request.
- Model IDs
- Use a model ID that appears in Models or in your console model list.
- Compatibility
- Use the OpenAI SDK by changing the base URL, API key, and model ID.
Reference
Endpoints
One API Key gives access to every enabled endpoint. Model support depends on your workspace configuration.
| GET | /v1/models | List model IDs discoverable through the OpenAI-compatible API. Use Models for full catalog, modality, pricing, and task details. |
| POST | /v1/chat/completions | Create chat or multimodal text responses with enabled chat models. |
| POST | /v1/responses | Use extended text-model capabilities when the selected model supports them. |
| POST | /v1/images/generations | Create image tasks with enabled image models. |
| GET | /v1/images/generations/{task_id} | Poll an image task until it succeeds or fails. |
| POST | /v1/video/generations | Create async video tasks with model-specific input media. |
| GET | /v1/video/generations/{task_id} | Poll a video task until it succeeds or fails. |
| POST | /v1/audio/speech | Create speech audio with enabled audio models. |
| POST | /v1/embeddings | Create embeddings for text inputs. |
| POST | /v1/rerank | Rank documents against a query. |
Reference
Common parameters
Use these as the first integration checklist. Model-specific options such as voices, media formats, and tool support are listed on each model detail page.
| Endpoint | Parameters | Notes |
|---|---|---|
| Chat | model, messages, stream, temperature, max_tokens | Use for text and multimodal text-output models. |
| Responses | model, input, max_output_tokens, tools | Start with plain input. Tool availability is model-specific. |
| Images | model, prompt, n, size | Some image models return synchronously; others return a task to poll. |
| Video | model, input.prompt, input.media, parameters.duration, parameters.resolution, parameters.watermark | Video models usually create async tasks and can be high-cost. |
| Speech | model, input, voice, format | Use short text first; supported voices and formats are model-specific. |
| Embeddings | model, input | Input can be a string or an array of strings. |
| Rerank | model, query, documents, top_n, return_documents | Documents are scored against the query; use top_n for smaller responses. |
Example
Chat completions
Use the OpenAI SDK by pointing it at the WLRouter base URL.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["WLROUTER_API_KEY"],
base_url="https://api.wlrouter.com/v1",
)
response = client.chat.completions.create(
model="anthropic.claude-sonnet-4.6",
stream=False,
messages=[{"role": "user", "content": "Write a one sentence product summary."}],
)
print(response.choices[0].message.content)Responses
Responses
Use /v1/responses when a supported text model exposes the Responses API. Start with plain text input; tools such as web search are optional and depend on the selected model and workspace configuration.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "qwen3.7-max",
"input": "Summarize the deployment risks in three bullets."
}
response = requests.post(
"https://api.wlrouter.com/v1/responses",
headers=headers,
json=payload,
)
print(response.json())Inputs
Model input examples
Input shapes vary by model family. These examples are intentionally small for integration checks.
Chat / text
Use OpenAI-compatible chat requests for text models such as Gemini 3.5 Flash, Claude Sonnet 4.6, or NVIDIA Nemotron 3 Super 120B. Cache-read usage is billed from verified usage when returned.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "gemini-3.5-flash",
"stream": False,
"max_tokens": 32,
"messages": [
{ "role": "user", "content": "Reply with one short sentence." }
]
}
response = requests.post(
"https://api.wlrouter.com/v1/chat/completions",
headers=headers,
json=payload,
)
print(response.json())Responses / text
Use Responses for supported text models that expose the Responses API. Keep the first integration check tool-free.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "qwen3.7-max",
"input": "Summarize the deployment risks in three bullets."
}
response = requests.post(
"https://api.wlrouter.com/v1/responses",
headers=headers,
json=payload,
)
print(response.json())Responses / tools
Tool calls such as web search are optional and model-specific. Enable them only after the selected model and workspace support the tool.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "qwen3.7-max",
"input": "Search for the latest public product announcement and summarize it.",
"tools": [
{ "type": "web_search_preview" }
]
}
response = requests.post(
"https://api.wlrouter.com/v1/responses",
headers=headers,
json=payload,
)
print(response.json())Image generation
Image models use the image generation endpoint. Gemini image models return synchronously; async task models return a task ID first.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "gemini-3.1-flash-image",
"prompt": "orange dot on white background",
"n": 1
}
response = requests.post(
"https://api.wlrouter.com/v1/images/generations",
headers=headers,
json=payload,
)
print(response.json())Video text-to-video
Some video models accept text-only prompts. Async tasks return a task ID; poll it before reading final usage and final billing status.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "vidu/viduq3-pro_text2video",
"input": { "prompt": "orange dot on white background" },
"parameters": {
"duration": 1,
"resolution": "540P",
"watermark": False
}
}
response = requests.post(
"https://api.wlrouter.com/v1/video/generations",
headers=headers,
json=payload,
)
print(response.json())Video reference-to-video
Reference-video models require media input. Use image references when possible for low-cost checks; reference videos may be counted by source duration.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "wan2.7-r2v",
"input": {
"prompt": "orange dot on white background, subtle motion",
"media": [
{
"type": "reference_image",
"url": "https://example.com/reference.png"
}
]
},
"parameters": {
"duration": 2,
"resolution": "720P",
"prompt_extend": False,
"watermark": False
}
}
response = requests.post(
"https://api.wlrouter.com/v1/video/generations",
headers=headers,
json=payload,
)
print(response.json())Poll media task
Poll image or video task IDs until the task succeeds or fails. Successful async tasks are billed after completion from verified usage.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
response = requests.get(
"https://api.wlrouter.com/v1/images/generations/{task_id}",
headers=headers,
)
print(response.json())Audio speech
Speech models create audio from short text input. Use a supported voice and output format.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "MiniMax/speech-2.8-turbo",
"input": "Hi",
"voice": "male-qn-qingse",
"format": "mp3"
}
response = requests.post(
"https://api.wlrouter.com/v1/audio/speech",
headers=headers,
json=payload,
)
print(response.json())Embeddings
Embedding models return vectors for search, retrieval, ranking, and clustering workflows.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "text-embedding-v4",
"input": "ok"
}
response = requests.post(
"https://api.wlrouter.com/v1/embeddings",
headers=headers,
json=payload,
)
print(response.json())Rerank
Rerank models score candidate documents against a query and can return only the top results.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "qwen3-rerank",
"query": "ok",
"documents": ["ok"],
"top_n": 1,
"return_documents": False
}
response = requests.post(
"https://api.wlrouter.com/v1/rerank",
headers=headers,
json=payload,
)
print(response.json())Tasks
Async media tasks
Image, video, and audio models can have different completion behavior. Some return the final asset in the first response; others return a task that must be polled before final usage and billing are known.
| Step | Behavior |
|---|---|
| Create | Image, video, and audio requests may return a task ID instead of the final asset. |
| Poll | Use the matching task endpoint until the task succeeds or fails. Keep both request_id and task_id for troubleshooting. |
| Billing | Synchronous requests are billed after verified usage. Async tasks stay pending until successful completion and final usage are available. |
| Failures | Failed tasks are not charged after WLRouter verifies the failed status. |
| Balance check | High-cost requests are estimated before execution. If available balance is below the safety-buffered estimate, WLRouter returns insufficient_balance before calling the upstream provider. |
Notes
Model-specific notes
Most text models share the chat format. Non-text models can have stricter media fields and billing units.
| Model | Note |
|---|---|
| gemini-3.5-flash | Fast Gemini text model on /v1/chat/completions. WLRouter bills from verified usage and records request log, usage billing event, and balance debit after success. |
| gemini-2.5-flash | Stable fast Gemini text model on /v1/chat/completions. Use short max_tokens values for low-cost integration checks. |
| gemini-2.5-pro | Stable Gemini Pro model on /v1/chat/completions for higher-quality reasoning and multimodal text-output work. |
| gemini-3.1-pro-preview | Callable preview Gemini Pro model on /v1/chat/completions. It remains marked Preview and should not be used as the default conservative production recommendation. |
| gemini-3.1-flash-image | Nano Banana 2 image model on /v1/images/generations. It returns synchronously; WLRouter bills per generated image from verified image-token usage. |
| gemini-3-pro-image | Nano Banana Pro premium image model on /v1/images/generations. It returns synchronously and carries higher per-image pricing than Flash Image. |
| anthropic.claude-haiku-4.5 | Fast, lower-cost Claude text model on /v1/chat/completions. Verified with minimum-cost token usage. |
| anthropic.claude-sonnet-4.6 | Recommended balanced Claude text model on /v1/chat/completions for agent development, coding assistance, content workflows, and knowledge work. |
| anthropic.claude-opus-4.6 | Premium Claude text model on /v1/chat/completions for higher-complexity reasoning and codebase work. Use short prompts for cost checks. |
| nvidia.nemotron-super-3-120b | OpenAI-compatible NVIDIA text model on /v1/chat/completions. Verified with minimum-cost token usage; successful requests record request log, usage billing event, and balance debit. |
| qwen3.7-max | Supports richer text-model capabilities on the model detail page. Use Responses only after confirming the requested tool is enabled and priced for the model. |
| Chat models with cache | When verified usage returns cached input tokens, WLRouter records cache-read tokens and applies the model's cache-read price. |
| wan2.7-r2v | Requires input.media. Use type reference_image, reference_video, or first_frame. Reference videos may increase billed duration because input video duration can be counted. |
| pixverse/pixverse-v6-r2v | Reference media uses image_url items and size such as 640*360. |
| happyhorse-1.1-i2v | Image-to-video requests use media type first_frame. |
| vidu/* video models | Reference/image-to-video requests use media items with type image; text-to-video variants may omit media. |
| MiniMax/speech-2.8-turbo | Speech requests require supported voice and audio format values. Start with short input text for integration checks. |
| Non-text async models | Billing is finalized from verified usage after successful task completion, including returned image count or video duration when available. Failed tasks are not charged. |
Realtime
Streaming
Set stream: true for Token-by-Token responses on supported chat models.
import os
import requests
headers = {
"Authorization": f"Bearer {os.environ['WLROUTER_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"model": "qwen-plus",
"stream": True,
"messages": [
{ "role": "user", "content": "Give me three launch checklist items." }
]
}
response = requests.post(
"https://api.wlrouter.com/v1/chat/completions",
headers=headers,
json=payload,
)
print(response.json())Handling
Errors
WLRouter returns OpenAI-compatible errors with a request ID. Keep that ID when contacting support.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request_error | The request shape or a model-specific parameter is not valid. |
| 401 | invalid_api_key | The API key is missing, disabled, expired, or malformed. |
| 402 | insufficient_balance | The workspace balance is below the safety-buffered request estimate. Add balance or lower request parameters before retrying. |
| 403 | account_disabled | The account or workspace is not active. |
| 404 | model_not_found | The model ID is not available for your workspace. |
| 422 | validation_error | Required fields are missing or failed validation. |
| 429 | rate_limited | Retry after a short delay or reduce concurrent requests. |
| 5xx | gateway_error | Keep the request_id and retry if the operation is safe to repeat. |
Usage
Billing
Token and cost records use authoritative gateway usage. Synchronous requests are deducted after success; async tasks stay pending until successful completion and verified usage are available.
Free trial
Included for new accounts
Min top-up
$10 USD
Service fee
6%, minimum $0.80
Help