An AI gateway you own and run.
Route one endpoint to 40+ providers, issue virtual keys, enforce budgets, and track usage.
Docs · otari.ai · Launch blog · Discord
Note
Developers Wilding, our AI hackathon at MozFest, runs until November 11. Build something with Otari and open-weight models for a chance at the $1,000 prize (plus runner-up prizes) and dedicated time with our AI engineers. Details and submissions.
Otari sits between your applications and model providers. It authenticates requests, resolves provider credentials, enforces budgets before dispatch, and records usage afterwards. Provider calls go through any-llm.
Run Otari with your own database and provider keys.
- One OpenAI and Anthropic-compatible endpoint for many providers
- Provider credentials stay behind the gateway
- Revocable API keys with user, workspace, and model scope
- Budget checks before spend and usage records after settlement
- Local routing policies for failover, weighting, and learned selection
- Optional code execution, web search, MCP, inference guardrails, and file understanding
Run an ephemeral gateway with Docker:
docker run --rm -p 8000:8000 \
-e OPENAI_API_KEY=YOUR_OPENAI_KEY \
-e OTARI_CONFIG_YAML='
default_pricing: true
providers:
openai:
api_key: ${OPENAI_API_KEY}
' \
mzdotai/otari:latest \
otari serveOn the first empty database, Otari creates an API key and prints it once:
No API keys found. Created bootstrap key for first run. Save this key now:
tk-...
Send a request with that key:
curl http://localhost:8000/api/v1/chat/completions \
-H "Authorization: Bearer tk-..." \
-H "Content-Type: application/json" \
-d '{
"model": "openai:gpt-4o-mini",
"messages": [{"role": "user", "content": "Say hello."}]
}'OpenAI clients work by setting base_url to
http://localhost:8000/api/v1.
This container uses SQLite inside the container and is deleted when it stops. Use the Compose setup below for persistent data.
The command a developer runs next to a coding agent (otari hook,
otari import claude-code) installs on its own, without the server:
brew install mozilla-ai/tap/otariSee Agent Guardrails and Use with Claude Code.
git clone https://github.com/mozilla-ai/otari
cd otari
cp config.example.yml config.yml
# Set a master key, provider credentials, and pricing in config.yml.
# Provider copies of attached files are off until they have a pepper of their own. Compose reads .env.
grep -qs OTARI_PROVIDER_ACCOUNT_PEPPER .env || echo "OTARI_PROVIDER_ACCOUNT_PEPPER=$(openssl rand -base64 32)" >> .env
docker compose pull
docker compose up -dCompose runs Otari with PostgreSQL. Optional profiles add the code sandbox, web search, and guardrail services:
docker compose --profile code-exec --profile web-search --profile guardrails up -dThe dashboard is served at http://localhost:8000/. To store provider keys
through the dashboard, set OTARI_SECRET_KEY to a Fernet key generated by
otari gen-secret-key.
A one-click deployment template is available for Railway.
The core completion routes are:
POST /api/v1/chat/completionsPOST /api/v1/messagesPOST /api/v1/responses
Otari also serves the broader OpenAI-compatible and management APIs. The
running server publishes Swagger UI at /api/v1/docs and OpenAPI at
/api/v1/openapi.json. See API reference.
The dashboard manages providers, models, routing, tools, keys, members, budgets, settings, activity, and usage. Its navigation adapts to the signed-in person's authority. See Admin dashboard.
git clone https://github.com/mozilla-ai/otari
cd otari
uv sync --dev
cp config.example.yml config.yml
uv run otari serve --config config.ymlFor local development without PostgreSQL, change database_url to
sqlite+aiosqlite:///./otari.db.
Common checks:
make test
make lint
make typecheckSee CONTRIBUTING.md before opening a pull request.
- Quickstart
- Deployment
- Configuration
- Models
- Routing
- Access control
- Built-in tools
- Agent Guardrails
- SDK and agent integrations
- Architecture
Apache 2.0. See LICENSE.
