Documentation

The API works like OpenAI's Chat Completions API. Change the base URL and API key and your existing code keeps working.

Quickstart

  1. Create an account and add at least $1 credit in Billing.
  2. Create an API key in API Keys.
  3. 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

OptionMeaning
routing.qualitylow, mid or high. A hard requirement, used with smart. If no model exists at that level we use the nearest level above.
routing.speedlow, mid or high. A preference. Also works with a named model, where it picks the server.
routing.costlow, mid or high. A preference, same as speed.
routing.fallbackfalse turns off backup models. Default true.
routing.exclude_modelsList of model names that must never be used (Smart mode).
routing.requireForce 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, streamThe 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_logprobsStandard OpenAI options.
top_k, min_p, repetition_penaltyOptions common on open-source models.
tools, tool_choice, parallel_tool_calls, response_formatFunction calling and JSON output.
reasoninglow, medium or high, for models that think before answering. More thinking costs more.
userYour 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/modelsList of models you can name, with context length, capabilities and starting prices.
GET /v1/balanceYour current balance in USD.
GET /v1/preview?quality=high&speed=high&cost=lowShows 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.

HTTPcodeMeaning
401invalid_api_keyKey is wrong or revoked.
402insufficient_balanceAdd credit in the dashboard.
403key_limit_reachedThis key hit its monthly limit.
403account_suspendedThe account is suspended.
403content_filteredThe content was blocked.
404model_not_foundUnknown model name.
400context_too_longInput is too long for any suitable model.
400capability_not_supportedThe named model cannot do what you asked (for example images).
400invalid_requestMissing or invalid fields.
409duplicate_requestThis Idempotency-Key was already used.
429rate_limitedToo many requests. Check the Retry-After header.
503service_unavailable / no_model_availableAll 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

  1. Change base_url to BASE_URL.
  2. Use your API key from this site.
  3. 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)