Developers
Pareto API docs
Pareto is Unbiased’s blended AI model: it selects frontier and open models for each request and blends their outputs into one answer. It is one model string built so AI providers compete for every request. It speaks the OpenAI and Anthropic API formats, so you can keep the client you already use: change the base URL, the key and the model string, then validate your client’s streaming, tools and error handling. Scores are on the model card, rates on the pricing page, release notes on the Pareto 26.10 hub. Setting up a coding agent? See vibe coding with Pareto.
Quickstart
- Base URL, OpenAI format:
https://api.unbiased.ai/v1 - Base URL, Anthropic format (Claude Code, Anthropic SDKs):
https://api.unbiased.ai. Leave/v1off: the client adds it. - Model string:
pareto - Key: create a platform.unbiased.ai account; new accounts are reviewed by hand, then your API key is issued on the platform.
curl https://api.unbiased.ai/v1/chat/completions \
-H "Authorization: Bearer $UNBIASED_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "pareto", "messages": [{"role": "user", "content": "Hello"}]}'
Rather have your agent do the setup? Hand it start/agent.md.
Already on OpenRouter? Use Pareto on OpenRouter.
Authentication
Send your API key as Authorization: Bearer <api-key> or in the x-api-key header. Keep it in an environment variable or your OS keychain, never in a repo.
Endpoints
| Endpoint | Format | Use it from |
|---|---|---|
POST /v1/chat/completions | OpenAI Chat Completions | OpenAI SDKs and any OpenAI-compatible tool |
POST /v1/messages | Anthropic Messages | Anthropic SDKs and Anthropic-compatible tools |
Both accept stream: true for server-sent events in their own format. Anthropic-format example:
curl https://api.unbiased.ai/v1/messages \
-H "x-api-key: $UNBIASED_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "pareto", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello"}]}'
OpenAI and Anthropic SDKs
Keep the SDK you already use. Point it at Pareto with a base URL, your key and the model string pareto; the rest of your code stays the same.
OpenAI SDK (Python):
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.unbiased.ai/v1", api_key=os.environ["UNBIASED_API_KEY"])
reply = client.chat.completions.create(
model="pareto",
messages=[{"role": "user", "content": "Hello"}],
)
print(reply.choices[0].message.content)
Anthropic SDK (Python). The SDK adds /v1/messages itself, so the base URL stops at the domain:
import os
import anthropic
client = anthropic.Anthropic(base_url="https://api.unbiased.ai", api_key=os.environ["UNBIASED_API_KEY"])
message = client.messages.create(
model="pareto",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)
Coding agents and other tools that take an OpenAI- or Anthropic-compatible base URL connect the same way. Works with has the exact settings for each one, from Claude Code, Codex and OpenCode to Cursor, Cline and Open WebUI.
Rate limits
| Plan | Requests per minute | Tokens |
|---|---|---|
| Personal | 20 | 50M a week |
| Personal Max | 60 | 600M a week |
| Team | 300 | No weekly cap; prepaid credits |
Requests over the limit return HTTP 429. Back off and retry. Plans and token rates are on the pricing page.
Errors
Errors come back as JSON in the format of the endpoint you called. A missing key on /v1/chat/completions:
{"error": {"message": "Missing API key. ...", "type": "invalid_request_error", "code": "invalid_api_key"}}
The same on /v1/messages:
{"type": "error", "error": {"type": "authentication_error", "message": "Missing API key. ..."}, "request_id": "req_..."}
Status codes: 400 invalid request, 401 missing or invalid key, 429 rate limit reached, 500 server error. Include the request ID (in the error body on /v1/messages, in the x-request-id response header on /v1/chat/completions) when you write to info@unbiased.ai, never the key.
Versioning and known gaps
- The major version is in the path:
/v1. Changes are announced in product updates. GET /v1/modelsis not implemented yet. If a client insists on listing models, hardcodepareto.- Unknown model ids are not rejected yet, so a typo is still served and billed as Pareto. Always send
pareto.
For agents and tools
- openapi.json: OpenAPI 3.1 spec for both endpoints
- llms.txt: site overview, including when to use Pareto
- start/agent.md: step-by-step setup instructions for an agent
- data/prices.json: dated token prices
- developers/openrouter: calling Pareto through OpenRouter
- works-with: setup guides for coding agents, editors, agent SDKs and team apps
- use-cases: tested recipes grouped by function, with code and run records