Quick Start (3 minutes)
Snodus is an AI gateway that exposes a single endpoint for Anthropic, OpenAI, and Ollama, with virtual API keys, budget, rate limiting, dashboard, and smart routing.
1. Sign up
curl -X POST https://snodus.ai/signup \
-H "Content-Type: application/json" \
-d '{"email":"you@company.com","name":"Name","company":"Company","plan":"basic"}'
2. Save your API key
The response contains api_key starting with sk-. Save it — it will not be shown again.
3a. Use with Claude Code
export ANTHROPIC_BASE_URL="https://snodus.ai"
export ANTHROPIC_AUTH_TOKEN="sk-abc123..."
claude
3b. Or use curl directly
curl https://snodus.ai/v1/messages \
-H "Authorization: Bearer sk-abc123..." \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"auto","max_tokens":100,"messages":[{"role":"user","content":"Hello!"}]}'
4. View your usage
Open /admin/ to see spend, tokens, models used, keys, and teams.
Authentication
Every request to /v1/* requires a virtual API key Snodus (sk-*) in one of these headers:
Authorization: Bearer sk-xxx(preferred)x-api-key: sk-xxx(compatibility)
Keys have: owner, rate limit (requests/min), monthly budget (cents), active/revoked status. The gateway replaces the virtual key with the real upstream provider API key.
For the Admin API (/admin/*): Basic auth with ADMIN_USERNAME:ADMIN_PASSWORD or a virtual key with role=admin.
POST /v1/messages
Main endpoint, Anthropic-compatible format. Auth: virtual key.
Request
{
"model": "claude-sonnet-4-5", // or "auto" if router enabled
"max_tokens": 1024,
"system": "You are...",
"messages": [{"role": "user", "content": "..."}],
"stream": false
}
Response headers
| Header | Description |
|---|---|
x-ratelimit-limit | Allowed requests/minute |
x-ratelimit-remaining | Requests remaining in window |
x-ratelimit-reset | Seconds until window reset |
Error codes
| Code | When |
|---|---|
| 401 | Missing or invalid key |
| 402 | Monthly budget exceeded |
| 403 | Key revoked, expired, or plan limit reached |
| 429 | Rate limit exceeded (retry_after in body) |
| 502 | Upstream provider error |
| 504 | Upstream provider timeout |
POST /v1/chat/completions
Native OpenAI endpoint — useful if your app already speaks OpenAI. Requires an OpenAI model (gpt-*, o1-*, o3-*, o4-*).
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "hi"}]
}
POST /signup
Available on the hosted service only. Creates a team, admin user, and API key in one call.
{
"email": "jane@company.com",
"name": "Jane Smith",
"company": "Acme Inc",
"plan": "basic"
}
Rate limit: max 5 signups per hour per IP.
Admin API
| Method | Path | Description |
|---|---|---|
| GET | /admin/keys | List virtual keys |
| POST | /admin/keys | Create key (respects plan max_keys) |
| PATCH | /admin/keys/{id} | Update rate_limit / budget |
| POST | /admin/keys/{id}/rotate | Rotate key, old expires in 24h |
| DELETE | /admin/keys/{id} | Revoke key |
| GET | /admin/users | List users |
| POST | /admin/users | Create user (respects plan max_users) |
| GET | /admin/teams | List teams |
| PATCH | /admin/teams/{id}/plan | Change team plan |
| GET | /admin/teams/{id}/account | Account summary with progress |
| GET | /admin/plans | List available plans |
| GET | /admin/providers | List registered providers |
| GET | /admin/analytics/{daily,models,users,recent,providers,routing} | Dashboard data |
| GET | /admin/analytics/export | CSV spend log |
Smart Routing
Passing "model": "auto" in the body, the router picks the best model based on rules:
- Complex keywords (refactor, architect, debug) → Opus
- Simple keywords (translate, format, list) → Haiku
- Short input (<200 token) → Haiku
- Medium input (<2000 token) → Sonnet
- Long input (≥2000 token) → Opus
The routing decision is logged in spend_log.routed_from='auto' + routing_method='rules'.
Enable with env var SNODUS_ROUTER_ENABLED=true.
Dashboard
Available at /admin/. Tabs: Spend (KPIs + charts), Activity (recent requests), Keys (CRUD), Users & Teams, Account (plan + progress). Auth: Basic auth with admin credentials.
Plans
| Plan | Price | Tokens/month | Users | Keys |
|---|---|---|---|---|
| Free | $0 | 100K | 1 | 1 |
| Basic | $19/month | 1M | 1 | 3 |
| Pro | $49/month | 5M | 5 | 10 |
| Enterprise | Contact us | Unlimited | Unlimited | Unlimited |
Self-Hosting
Docker (recommended)
git clone https://github.com/42NE-Ltd/snodus
cd snodus
cp .env.example .env
# Edit .env: ANTHROPIC_API_KEY, ADMIN_PASSWORD
docker compose up -d
From source
cargo build --release
./target/release/snodus serve
Configuration (env vars)
| Variable | Description | Default |
|---|---|---|
DATABASE_URL | Postgres connection string | — |
ANTHROPIC_API_KEY | Real Anthropic API key | — |
OPENAI_API_KEY | Enable OpenAI provider | — |
OLLAMA_BASE_URL | Enable local Ollama | — |
ADMIN_PASSWORD | Admin bootstrap password | — |
SNODUS_ROUTER_ENABLED | Smart router for model: "auto" | false |
SNODUS_FEATURES_SIGNUP | Enable /signup | false |
SNODUS_FEATURES_PLANS | Enable plan enforcement | false |
SNODUS_FEATURES_LANDING | Enable landing page at / | false |
SNODUS_WEBHOOK_URL | URL for budget/rate limit notifications | — |
CLI Reference
snodus serve # start gateway
snodus status # general summary
snodus providers # provider status
snodus plans # list plans
snodus budget # spend vs budget per team/key
snodus account --team-id UUID # account summary with progress
snodus teams create --name "Company" --budget 5000
snodus teams update --id UUID --budget 10000
snodus users create --email x@y.com --name "Mario" --team-id UUID --role admin
snodus keys create --user-id UUID --name "dev" --rate-limit 60 --budget 5000
snodus keys rotate --id UUID # generate new, old expires in 24h
snodus keys revoke --id UUID
Snodus v0.1.0 — github.com/42NE-Ltd/snodus — MIT