Documentation
The API works like OpenAI's Chat Completions API. Change the base URL and API key and your existing code keeps working.
Quickstart
- Create an account and add at least $1 credit in Billing.
- Create an API key in API Keys.
- Make your first request:
from openai import OpenAI
client = OpenAI(base_url="BASE_URL", api_key="YOUR_API_KEY")
reply = client.chat.completions.create(
model="smart",
messages=[{"role": "user", "content": "Hello!"}],
)
print(reply.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({ baseURL: "BASE_URL", apiKey: "YOUR_API_KEY" });
const reply = await client.chat.completions.create({
model: "smart",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(reply.choices[0].message.content);curl BASE_URL/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"smart","messages":[{"role":"user","content":"Hello!"}]}'API keys
Send your key in the Authorization: Bearer header. The full key is shown only once when you create it, so copy it right away. Treat it like a password and never put it in public code. You can revoke a key at any time and set a monthly spending limit per key.
Chat completions
POST /v1/chat/completions
Use "model": "smart" to let us choose, or a model name from the Models page to choose yourself.
{
"model": "smart",
"messages": [{"role": "user", "content": "Explain DNS in one paragraph."}],
"routing": {"quality": "mid", "speed": "high", "cost": "low"}
}
Images (image_url parts), tools and JSON output (response_format) are supported. We automatically pick only models that support what your request needs.
Streaming
Add "stream": true and the answer arrives piece by piece as server-sent events, ending with data: [DONE]. Add "stream_options": {"include_usage": true} to receive token usage and cost in the final chunk.
stream = client.chat.completions.create(
model="smart",
messages=[{"role": "user", "content": "Write a short poem."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
If a model fails before it starts writing, we move to the next model. Once writing has started we do not switch; if the stream breaks, you receive an error and are charged only for what was generated. The answering model is sent in the response headers X-Model, X-Server and X-Used-Fallback.
Smart Routing & fallback
| Option | Meaning |
|---|---|
routing.quality | low, mid or high. A hard requirement, used with smart. If no model exists at that level we use the nearest level above. |
routing.speed | low, mid or high. A preference. Also works with a named model, where it picks the server. |
routing.cost | low, mid or high. A preference, same as speed. |
routing.fallback | false turns off backup models. Default true. |
routing.exclude_models | List of model names that must never be used (Smart mode). |
routing.require | Force capabilities: vision, tools, json, long_context, coding, reasoning. |
If you send nothing, your default setting from the dashboard (Smart Routing page) is used. At most 3 models are tried, within the total time limit of 60 seconds. You are charged only for the model that answered.
Not every request problem triggers a fallback: if your own request is invalid, too long or blocked, you get the error right away, because another model would fail the same way.
Parameters
messages, model, stream | The conversation, the model (or smart), and streaming on or off. |
temperature, top_p, max_tokens, max_completion_tokens, stop, seed, n, presence_penalty, frequency_penalty, logit_bias, logprobs, top_logprobs | Standard OpenAI options. |
top_k, min_p, repetition_penalty | Options common on open-source models. |
tools, tool_choice, parallel_tool_calls, response_format | Function calling and JSON output. |
reasoning | low, medium or high, for models that think before answering. More thinking costs more. |
user | Your own tag (for example a user ID). You can filter usage by it. |
An option a model does not understand is quietly ignored. Requests with tools, images or JSON output only go to models that support them. Send an Idempotency-Key header to make sure a retried request is never charged twice.
max_tokens matters for cost: before each request we hold the maximum possible cost, then charge the real cost and release the rest. Default is 4096 if you do not set it.
Response details
The response matches OpenAI's format, plus:
"usage": {"prompt_tokens": 12, "completion_tokens": 40, "total_tokens": 52, "cost": 0.000021},
"unified": {
"request_id": "...", "model": "llama-3.3-70b", "server": "Groq",
"used_fallback": false, "tokens_per_sec": 540.2, "latency_ms": 310
}
cost is in USD and is what was deducted from your balance.
Other endpoints
GET /v1/models | List of models you can name, with context length, capabilities and starting prices. |
GET /v1/balance | Your current balance in USD. |
GET /v1/preview?quality=high&speed=high&cost=low | Shows which model and server would run, with prices. Nothing is charged. |
Errors
Every error has the same shape: {"error": {"message": "...", "type": "...", "code": "..."}}. You are never charged for a failed request.
| HTTP | code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Key is wrong or revoked. |
| 402 | insufficient_balance | Add credit in the dashboard. |
| 403 | key_limit_reached | This key hit its monthly limit. |
| 403 | account_suspended | The account is suspended. |
| 403 | content_filtered | The content was blocked. |
| 404 | model_not_found | Unknown model name. |
| 400 | context_too_long | Input is too long for any suitable model. |
| 400 | capability_not_supported | The named model cannot do what you asked (for example images). |
| 400 | invalid_request | Missing or invalid fields. |
| 409 | duplicate_request | This Idempotency-Key was already used. |
| 429 | rate_limited | Too many requests. Check the Retry-After header. |
| 503 | service_unavailable / no_model_available | All attempted models failed, or none fit your request. Try again shortly. |
Limits
Each key has a requests-per-minute limit (60 by default; contact us if you need more). You can also set a monthly spending limit per key; when it is reached, that key stops working.
Pricing & billing
You add credit first and usage is deducted from it. Minimum top-up is $1, balances are in USD, and there is no free credit. See Pricing. Cost per request is: input tokens × input price + output tokens × output price, at the server that answered. Your Usage page lists every request with its cost.
Moving from OpenAI
- Change
base_urltoBASE_URL. - Use your API key from this site.
- Keep your code. Use a model name from the Models page, or
smart.
LangChain & LlamaIndex
# LangChain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="smart", base_url="BASE_URL", api_key="YOUR_API_KEY")
# LlamaIndex
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(model="smart", api_base="BASE_URL", api_key="YOUR_API_KEY", is_chat_model=True)