Skip to main content

Janus

The two-faced gateway for AI coding tools. Janus sits at the threshold of every AI call — facing the developer on one side and every provider on the other.

Janus is a self-hosted, multi-tenant AI routing gateway. It exposes OpenAI/Anthropic/Gemini-compatible HTTP endpoints that your coding tools (Claude Code, Codex, Cursor, Cline, ...) talk to, then translates and routes each request to any of 29 built-in AI providers — or any OpenAI-compatible endpoint — without either side needing to know the other exists.

Janus 3 includes Cloudline, a responsive Svelte dashboard for monitoring and operating the gateway.

First-time setup

Janus needs Python 3.11+. Everything lives under ~/.janus/ — a seed config.yaml and a SQLite database (janus.db) that becomes the source of truth after the first startup.

1. Install

From PyPI (recommended):

pip install janus-ai

From source (development):

git clone https://github.com/amanverasia/Janus.git
cd Janus
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

2. Create config

janus config-init

This writes ~/.janus/config.yaml. Open it and add at least one provider with your API keys. Environment variables in ${VAR} form are resolved at startup:

export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

Example provider block:

providers:
  - id: openai
    prefix: openai
    api_type: openai_compat
    base_url: https://api.openai.com/v1
    api_key: ${OPENAI_API_KEY}
    models: [gpt-4o, gpt-4o-mini]

You can also add providers later from the dashboard — no restart required.

3. Start the server

janus serve --port 20128

For access from other machines on your LAN or Tailscale:

janus serve --host 0.0.0.0 --port 20128

Janus serves plain HTTP only. Use http://, not https://, unless you put a reverse proxy with TLS in front.

4. Verify

curl http://localhost:20128/v1/health
# {"status":"ok"}

Open Cloudline at http://localhost:20128/dashboard/ui. / and the former /dashboard page route both redirect there. Dashboard access always requires a Janus API key, including from localhost.

5. Configure via dashboard

On first startup, Janus imports providers, combos, token_savers, and pricing from YAML into SQLite. After that, the database is authoritative — editing YAML and restarting will not re-apply changes. Use the dashboard instead.

Step Where What
Add providers Providers Pick from the catalog or add custom; fetch models, test connection
Create a client key API Keys sk-janus-... shown once — save it
Enable auth Settings Toggle Require API key (recommended for remote access)
Set reporting timezone Settings Choose an IANA timezone for Today's Spend and daily-budget boundaries
Grant dashboard access API Keys Enable Allow dashboard login on the keys permitted to sign in
Connect your tools Tool Setup Copy-paste env vars for Claude Code, Codex, Cursor, Cline

Dashboard access rules:

  • All clients, including localhost and loopback — sign in at /dashboard/login with a Janus API key
  • DB-managed keys must be active and have Allow dashboard login (can_login=true)
  • Static keys configured in YAML are also accepted
  • Username/password login and the loopback bypass are not supported

Create a key from the CLI instead:

janus keys create --name "my-laptop"

6. Send a test request

curl http://localhost:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 50
  }'

List registered models:

curl http://localhost:20128/v1/models

7. Point your coding tool at Janus

Claude Code / Anthropic tools:

export ANTHROPIC_BASE_URL=http://localhost:20128/v1
export ANTHROPIC_API_KEY=sk-janus-yourkey   # if require_api_key is on

Cursor / OpenAI Chat Completions tools:

export OPENAI_BASE_URL=http://localhost:20128/v1
export OPENAI_API_KEY=sk-janus-yourkey      # if require_api_key is on

Codex CLI uses POST /v1/responses — configure a provider in ~/.codex/config.toml with wire_api = "responses" (see Client Setup).

Use prefix/model in requests (e.g. openai/gpt-4o, anthropic/claude-sonnet-4-20250514) or a combo name like best-effort.

📚 Documentation · Contributing · Changelog

Docker

mkdir -p janus-data
janus config-init --path janus-data/config.yaml
# Edit janus-data/config.yaml — add providers and ${ENV_VAR} keys

# Optional: pass API keys via .env in the repo root
echo 'OPENAI_API_KEY=sk-...' >> .env

docker compose up -d

The image binds to 0.0.0.0:20128. SQLite and config persist in ./janus-data/. After first startup, manage providers and settings from the dashboard — not by editing YAML alone.

Dashboard: create a Janus API key with Allow dashboard login enabled, then use that key at /dashboard/login. This is required on localhost too. The Require API key setting controls API endpoint authentication; it does not disable dashboard authentication.

curl http://localhost:20128/v1/health
open http://localhost:20128/dashboard/ui    # macOS; or visit in your browser

Configuration

Janus reads YAML from ~/.janus/config.yaml (or --config) with ${ENV_VAR} token resolution. Generate a template with janus config-init.

On first startup only, YAML seeds the SQLite database. Subsequent changes should be made via the dashboard or Export Config / Reset to Defaults on the Settings page.

server:
  port: 20128
  host: 127.0.0.1
  require_api_key: false

providers:
  - id: openai
    prefix: openai
    api_type: openai_compat
    base_url: https://api.openai.com/v1
    api_key: ${OPENAI_API_KEY}
    models: [gpt-4o, gpt-4o-mini, o3, o4-mini]

  - id: anthropic
    prefix: anthropic
    api_type: anthropic
    base_url: https://api.anthropic.com
    api_key: ${ANTHROPIC_API_KEY}
    models: [claude-sonnet-4-20250514, claude-opus-4-20250514]

combos:
  - name: best-effort
    models: [anthropic/claude-sonnet-4-20250514, openai/gpt-4o]

Supported Provider Types

api_type Use For
openai_compat Any OpenAI-compatible API (OpenAI, Groq, Together, DeepSeek, OpenRouter, Mistral, Fireworks, Perplexity, xAI, ...)
anthropic Direct Anthropic API
gemini Direct Google Gemini API
github_copilot GitHub Copilot (device-code OAuth from the dashboard)
opencode_free OpenCode Zen free tier

Known Provider Base URLs

Provider base_url
OpenAI https://api.openai.com/v1
Groq https://api.groq.com/openai/v1
Together AI https://api.together.xyz/v1
DeepSeek https://api.deepseek.com/v1
OpenRouter https://openrouter.ai/api/v1
Mistral https://api.mistral.ai/v1
Fireworks https://api.fireworks.ai/inference/v1
Perplexity https://api.perplexity.ai
xAI (Grok) https://api.x.ai/v1
Qwen/DashScope https://dashscope.aliyuncs.com/compatible-mode/v1

Client Setup

See step 7 in First-time setup for the basics. Full guides: Client Setup. The dashboard Tools page (/dashboard/ui/tools) generates copy-paste env vars for your exact server URL and auth settings.

Claude Code / Anthropic tools:

export ANTHROPIC_BASE_URL=http://localhost:20128/v1

Cursor / OpenAI Chat Completions tools:

export OPENAI_BASE_URL=http://localhost:20128/v1
export OPENAI_API_KEY=sk-janus-yourkey  # if require_api_key is on

Codex CLI speaks the Responses API (POST /v1/responses). Prefer a ~/.codex/config.toml provider with wire_api = "responses" and base_url = "http://localhost:20128/v1" — see the docs link above.

Ollama-only tools use OLLAMA_HOST=http://localhost:20128 (/api/chat, /api/generate, /api/show, /api/tags). Gemini-native tools use GOOGLE_GEMINI_BASE_URL=http://localhost:20128.

Features

  • Multi-format inbound — OpenAI Chat Completions, OpenAI Responses (/v1/responses for Codex CLI), Anthropic Messages, Gemini GenerateContent, and Ollama (/api/chat, /api/generate, /api/show, /api/tags)
  • Fallback routing — multi-account rotation with cooldowns (429→60s, 5xx→30s, auth→300s, network→15s)
  • Rate-limit-aware rotation — accounts at their per-minute or per-day request quota are tried last
  • Subscription quotas — per-provider 5h / daily / weekly / monthly windows; near-limit banners and soft deprioritization in routing
  • Combos — named ordered model sequences (e.g., "model": "best-effort")
  • Token savers — RTK compression (default ON), Caveman, Ponytail, and optional Headroom compression proxy
  • GitHub Copilot OAuth — device-code connect from the dashboard; session tokens refreshed automatically
  • API key scopes — dashboard access (can_login), model allowlists (prefix/*), optional daily budgets
  • Budgets — daily spending limits per API key or global, with warn/block thresholds
  • Request logging — opt-in debug capture of request/response bodies (Settings → Request Logs)
  • Analytics — cost tracking, spend trends, success rates, per-model/provider/key breakdowns
  • Pricing — builtin model prices, YAML/DB overrides, cache token rates
  • Cloudline dashboard — responsive SvelteKit 2 + Svelte 5 + TypeScript SPA at /dashboard/ui, with light/dark/system themes, a command palette, live usage, analytics, routing visibility, and modular management screens
  • Single self-hosted dashboard — the versioned Cloudline bundle ships with Janus; production rendering has no runtime CDN or Node.js dependency. /dashboard and former page URLs are compatibility redirects to /dashboard/ui
  • Upstream key inventory — validate, monitor, and route through a multi-key pool for 29 providers (/dashboard/ui/inventory)

Upstream Key Inventory

Built-in dashboard for upstream provider API keys: health checks, credit tracking, and automatic routing through the best available key.

Dashboard: http://127.0.0.1:20128/dashboard/ui/inventory

  • Overview stats, paginated/sortable keys table, key detail modal, best-keys widget
  • Add keys, bulk submit, import from Dashboard export JSON, re-identify misclassified keys
  • Encryption at rest; routable keys wired into gateway fallback rotation
  • Credentials masked by default; authenticated Reveal/Copy actions clear the value after 30 seconds
  • History shows real status transitions and credit snapshots without no-op transition noise
  • Detected rate limits (RPM/RPD) deprioritize near-quota keys during routing
  • Background recheck scheduler (twice daily by default)
Variable Purpose
INVENTORY_ENCRYPTION_KEY Fernet key for encrypting upstream keys at rest
INVENTORY_PUSH_TOKEN Auth token for POST /dashboard/api/inventory/push
INVENTORY_SCHEDULER_ENABLED Set to false to disable background rechecks (default: true)
VALIDATION_MAX_FAILURES Pause automatic validation after this many consecutive failures (default: 3)
janus inventory generate-encryption-key          # create Fernet key
janus inventory migrate export.json --verify     # import Dashboard export + summary
janus inventory verify                           # cutover verification summary
janus inventory encrypt-keys                       # encrypt plaintext keys in DB

CLI Reference

Command Description
janus serve Start the gateway server
janus config-init Generate default config YAML
janus config-path Print config file path
janus keys create/list/update/revoke Manage API keys (scopes: --no-login, --models, --daily-budget)
janus usage stats/cost/by-key Usage and cost reports
janus budgets list/set/delete Manage spending budgets
janus pricing list/show View model pricing
janus inventory migrate/verify/encrypt-keys/generate-encryption-key Upstream key inventory and cutover

Development

git clone https://github.com/amanverasia/Janus.git
cd Janus
python -m venv .venv
pip install -e ".[dev]"

# Run tests
.venv/bin/python -m pytest

# Lint + typecheck
.venv/bin/ruff check src/janus/ tests/
.venv/bin/mypy src/janus/

# Start dev server
.venv/bin/janus serve --port 20128 --reload

# Verify and rebuild the Cloudline frontend
.venv/bin/python scripts/build_dashboard_ui.py --check
.venv/bin/python scripts/build_dashboard_ui.py

Tech Stack

Python 3.11+ / FastAPI / httpx / Pydantic v2 / aiosqlite / SvelteKit 2 / Svelte 5 / TypeScript

License

GPL-3.0 © 2026 Aman Verasia

Release files for janus-ai 3.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for janus-ai 3.7.0
File Size Uploaded
janus_ai-3.7.0.tar.gz 597.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for janus-ai 3.7.0
File Interpreter ABI Platform
janus_ai-3.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.0 MB

Release files / janus_ai-3.7.0.tar.gz

Download URL janus_ai-3.7.0.tar.gz
Size 597.1 kB
Tags Source
SHA-256 checksum
How to use checksums
b6731120d9f99b757f954354630a6c1164594c0c616bc5fab8ab6cb92cf5b52c
BLAKE2b-256 checksum
How to use checksums
1139223f815edaaf2b28d8977fe0695006c3410dae46e5de819c631efd90adbe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / janus_ai-3.7.0-py3-none-any.whl

Download URL janus_ai-3.7.0-py3-none-any.whl
Size 443.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6200f0831363b4609123e31ae0b70c3313bb355dedccfca9bc9263fe3b99ce17
BLAKE2b-256 checksum
How to use checksums
3bb1cd1c99659618cfc88138e35b0454e9ec839b51db826cee2368988b03528c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release history Release notifications | RSS feed

3.19.1

2 release files

3.19.0

2 release files

3.18.2

2 release files

3.18.1

2 release files

3.18.0

2 release files

3.17.0

2 release files

3.16.0

2 release files

3.15.0

2 release files

3.14.0

2 release files

3.13.0

2 release files

3.9.0

2 release files

3.8.0

2 release files

This release

3.7.0 This release

2 release files

3.6.0

2 release files

3.5.0

2 release files

3.4.0

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.0

2 release files

2.2.2

2 release files

2.2.0

2 release files

2.1.5

2 release files

2.1.4

2 release files

2.1.3

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page