Skip to main content

Rotor

Rotor is an API-only LLM gateway. It exposes OpenAI-compatible, Anthropic-compatible, and OpenAI Responses-compatible endpoints over the models and provider keys configured as channels.

Rotor includes a minimal browser admin page at /. Management can also be done directly through HTTP admin APIs.

Run

cd /Users/whoami/research/apirouter/rotor
pip install -e .
rotor serve --host 0.0.0.0 --port 8000

Open the admin page:

http://localhost:8000

By default, Rotor stores runtime files in ~/.cache/rotor:

~/.cache/rotor/
  rotor.db
  conversations/

Important Environment

# Optional. Defaults to sqlite+aiosqlite:///~/.cache/rotor/rotor.db
DATABASE_URL=
# Optional. Defaults to ~/.cache/rotor/conversations
CONVERSATION_STORE_DIR=

Configure Channels

Each channel stores one provider base URL, provider API key, supported models, priority, and weight.

curl -X POST http://localhost:8000/api/admin/channels \
  -H "Content-Type: application/json" \
  -d '{
    "name": "zhipu-main",
    "type": "zhipu",
    "key": "provider-api-key",
    "base_url": "https://open.bigmodel.cn/api/paas/v4",
    "models": ["glm-4.7"],
    "model_mapping": {},
    "priority": 10,
    "weight": 1,
    "enabled": true,
    "protocol": "openai"
  }'

base_url is the upstream provider API root. key is that provider's API key. Different providers or different keys should be configured as separate channels. Channels serving the same model are distributed by priority and weight.

Set protocol to openai_responses for an upstream that exposes native POST /responses. Native Responses channels preserve hosted tools, multimodal items, background jobs, response state, resource lifecycle calls, input-token counting, compaction, and Responses SSE events. Rotor persistently binds each native response ID to its originating channel and API token, so retrieval, cancellation, deletion, input-item listing, and previous_response_id requests return to the correct upstream account. Function tools can also be converted across openai, openai_responses, and anthropic channels.

Channel connectivity tests use GET /models and do not consume model tokens. An administrator can explicitly run a generation capability probe (which may be billable):

curl -X POST \
  "http://localhost:8000/api/admin/channels/1/test?capability=function_call&test_model=your-model"

Adaptive Routing

Rotor can rank otherwise-compatible channels using online success, latency, and in-flight load signals. The scoring interface also reserves a cost signal, which remains neutral until model pricing is configured. Administrative priority remains a hard tier: adaptive scoring only reorders channels within the same priority. The default strategy remains priority_weighted; enable the first explainable policy with:

curl -X PUT http://localhost:8000/api/admin/settings \
  -H "Content-Type: application/json" \
  -d '{
    "routing": {
      "strategy": "adaptive",
      "affinity_enabled": true
    }
  }'

Every generated decision stores its candidate set, feature snapshot, policy version, and score snapshot in routing_decisions. Request outcomes continue to be stored in usage_ledger; the tables join on request_id and form the training source for future offline models. Online statistics are process-local in this first version and reset on restart, while the training data persists.

Generate User API Key

curl -X POST "http://localhost:8000/api/admin/tokens/generate?name=demo&quota=1000000" \

Use the returned key against Rotor:

curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer $ROTOR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Conversation-Id: conv_demo" \
  -d '{
    "model": "glm-4.7",
    "messages": [{"role": "user", "content": "hello"}]
  }'

Image generation is exposed through the OpenAI-compatible Images API. The channel can remain protocol=openai_responses; Rotor uses the dedicated upstream /images/generations path for this endpoint. Override it with extra.images_path only when a provider uses a non-standard path.

curl -X POST http://localhost:8000/v1/images/generations \
  -H "Authorization: Bearer $ROTOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "A small red house beside a quiet lake",
    "size": "1024x1024"
  }'

Codex CLI、Claude Code 和 OpenCode 的配置模板与冒烟命令见 客户端接入指南。

Endpoints

  • GET /
  • GET /api
  • POST /v1/chat/completions
  • POST /v1/responses
  • POST /v1/images/generations
  • GET/DELETE /v1/responses/{response_id}
  • POST /v1/responses/{response_id}/cancel
  • GET /v1/responses/{response_id}/input_items
  • POST /v1/responses/input_tokens
  • POST /v1/responses/compact
  • POST /anthropic/v1/messages
  • POST /anthropic/v1/messages/count_tokens
  • GET /v1/models
  • GET/POST/PUT/DELETE /api/admin/channels
  • GET/POST/PUT/DELETE /api/admin/tokens
  • GET /api/admin/logs

Metadata

Release files for rotor-gateway 0.2.3

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

Source distribution (sdist)

Source distribution for rotor-gateway 0.2.3
File Size Uploaded Provenance
rotor_gateway-0.2.3.tar.gz 178.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for rotor-gateway 0.2.3
File Interpreter ABI Platform
rotor_gateway-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 415.2 kB

Release files / rotor_gateway-0.2.3.tar.gz

Download URL rotor_gateway-0.2.3.tar.gz
Size 178.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4a6708acf0c3b65494fe5710de22df529828fae667e1430218f7be033cc7e5e4
BLAKE2b-256 checksum
How to use checksums
2f79caaacb4b9acb5cb07c8cd999e86e5794e185815d7e8be370a3bb8ccc0b1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.3.0 CPython/3.13.11 Darwin/25.2.0

Release files / rotor_gateway-0.2.3-py3-none-any.whl

Download URL rotor_gateway-0.2.3-py3-none-any.whl
Size 236.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
705edc1ff83a0916697782c525cf052a5e9f0817badf6b1c5076d565849565b2
BLAKE2b-256 checksum
How to use checksums
8a923dcfe07327651dd7e1484efe2ab0eb83863fad3ae2369191bfbf6d3be16e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.3.0 CPython/3.13.11 Darwin/25.2.0

Security for rotor-gateway 0.2.3

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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