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 coding tools
export ANTHROPIC_BASE_URL="https://snodus.ai"
export ANTHROPIC_AUTH_TOKEN="sk-abc123..."
# then start your coding tool
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
Snodus ships two separate browser apps: the Operator Console at /admin/ for internal operators and super-admins, and the Customer Portal at /portal/ for organization owners, team admins, members and viewers. Admin APIs live under /admin/dashboard/*; customer-scoped APIs live under /portal/* and enforce team/org/user scope server-side.
Dashboard login is first-party email + password: customers sign in at /login (redirected to /portal/), operators at /admin/login (redirected to /admin/), with self-service reset at /reset. OIDC/SSO is optional and disabled by default (planned IdP integration). Basic auth with ADMIN_USERNAME:ADMIN_PASSWORD remains for operator bootstrap. All /v1/* API traffic is unchanged and authenticated by virtual API keys (sk-*).
| Surface | Path | Description |
|---|---|---|
| Operator Console (UI) | /admin/ | Admin/operator console; log in at /admin/login. |
| Admin API | /admin/dashboard/* | Operator-only dashboard API; requires an operator session. |
| Customer Portal (UI) | /portal/ | Customer portal; log in at /login. Operators are not accepted here. |
| Customer API | /portal/* | Customer-scoped API; team/org/user scope enforced server-side. |
| Compatibility API | /dashboard/* | Legacy namespace; prefer /admin/dashboard/* or /portal/*. |
| Method | Customer Portal API | Description |
|---|---|---|
| GET | /portal/context | Session identity, role, permissions, teams, organizations, feature flags, navigation |
| GET | /portal/overview | Spend, tokens, quota, active keys, subscription and onboarding state |
| GET | /portal/analytics/{daily,models,users,recent,providers} | Scoped analytics for charts and tables |
| GET/POST | /portal/keys | List and create API keys within permission scope |
| POST | /portal/keys/{id}/rotate | Rotate a key; the old key keeps a 24h grace window |
| GET | /portal/billing/{status,invoices,info}/{team_id} | Billing status, invoices and fiscal data for authorized roles |
| GET | /portal/audit | Scoped activity / audit log |
Plans
| Plan | Price | Monthly usage | Users | Keys |
|---|---|---|---|---|
| Free | €0 | €3 · 14-day trial | 1 | 1 |
| Basic | €19/month | €15 | 1 | 3 |
| Pro | €49/month | €39 | 5 | 10 |
| Enterprise | Contact us | Unlimited | Unlimited | Unlimited |
Each plan's monthly allowance is measured in actual usage — the provider cost of your requests — not a fixed token count. When you reach the allowance, requests pause until the next calendar month. Auto-routing and prompt caching make your allowance go further.
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