Self-hosted AI API gateway for Claude Code, Codex, Gemini CLI, and Grok.
This repository is kiss-kedaya/sub2api, a maintained fork of Wei-Shaw/sub2api.
Compared with upstream, this tree is built around a production site that already runs payment, mixed-platform routing, and WebSocket traffic:
- API key smart routing — one key can bind several groups in strict order; protocol mismatches (for example an OpenAI account on an Anthropic path) are skipped instead of being forced.
- Built-in recharge — EasyPay (including relative
payurl/qrcode), per-provider fee and multiplier, instance recharge terms. See docs/PAYMENT_CN.md. - Usage dashboard — 30-day window with hourly rollup when data exists, otherwise a direct
usage_logsfallback. - Gateway reliability — WebSocket client-close is not treated as account failure; oversized passthrough can fall back to HTTP bridge; Spark 429 stays model-scoped; failed forwards release session slots immediately.
- Ops-safe upgrades — production
DATABASE_MIGRATION_MODE=validateon the live process; schema changes are applied out of band. Version is a single file:backend/cmd/server/VERSION. GitHub Releases fire only onv*tags.
Balance preauthorization stays off in this deployment (BILLING_BALANCE_PREAUTHORIZATION_ENABLED=false). Do not turn it on without a dedicated review.
- Multi-account upstreams: Anthropic OAuth / setup token, OpenAI API key and OAuth, Gemini, Grok, Antigravity
- API keys, groups, sticky sessions, concurrency and rate limits
- Token-level usage and billing
- Admin and user dashboards
- Composite groups for multi-provider model routing (docs/COMPOSITE_GROUPS.md)
- Codex / Claude Code / Gemini CLI / Grok CLI configuration from the key page
| Layer | Tech |
|---|---|
| Backend | Go 1.26.6, Gin, Ent |
| Frontend | Vue 3, Vite, TailwindCSS, pnpm |
| Database | PostgreSQL 15+ |
| Cache | Redis 7+ |
sub2api/
├── backend/ # Go service
│ ├── cmd/server/ # entry + VERSION
│ ├── internal/ # handlers, services, repositories
│ ├── migrations/ # numbered SQL
│ └── Makefile
├── frontend/ # Vue app (build output → backend/internal/web/dist)
├── deploy/ # systemd, Docker, install scripts, config.example.yaml
└── docs/ # payment, composite groups, plugins
Prerequisites: Go 1.26+, Node.js 18+, pnpm, PostgreSQL, Redis.
git clone https://github.com/kiss-kedaya/sub2api.git
cd sub2api
# Frontend (writes into backend/internal/web/dist)
pnpm --dir frontend install
pnpm --dir frontend build
# Backend with embedded UI
cd backend
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags embed -o sub2api ./cmd/serverOr from the repo root: make build.
Version string comes from backend/cmd/server/VERSION (or the v* tag when building a tagged checkout). Do not scatter version files elsewhere.
Run without embedding UI only for local backend work:
cd backend
go run ./cmd/serverFrontend dev server:
pnpm --dir frontend devCopy deploy/config.example.yaml to backend/config.yaml for binary deploys. First boot without a config file opens the setup wizard at http://<host>:8080.
GitHub Actions release.yml publishes assets when a v* tag is pushed (for example v0.1.258). A branch push only runs CI.
Linux install from a release:
curl -sSL https://raw.githubusercontent.com/kiss-kedaya/sub2api/main/deploy/install.sh | sudo bash
sudo systemctl enable --now sub2apiDocker:
mkdir -p sub2api-deploy && cd sub2api-deploy
curl -sSL https://raw.githubusercontent.com/kiss-kedaya/sub2api/main/deploy/docker-deploy.sh | bash
docker compose up -dDetails: deploy/README.md, deploy/DOCKER.md.
- Keep the Go process on
127.0.0.1:8080and put Nginx (or another reverse proxy) in front. Enableunderscores_in_headers on;so sticky-session headers survive. - Live traffic process:
DATABASE_MIGRATION_MODE=validate. Do not let the primary 8080 process apply migrations. - Canary a new binary on another port (for example 8081), then switch Nginx. Never kill the primary while it still serves traffic.
- WebSocket / SSE: if an egress proxy breaks OpenAI WS,
GATEWAY_OPENAI_WS_FORCE_HTTP=trueforces upstream HTTP/SSE without changing the client protocol.
underscores_in_headers on;Without this, Nginx drops headers such as session_id and sticky routing breaks.
RUN_MODE=simple hides SaaS billing UI. In production also set SIMPLE_MODE_CONFIRM=true.
GNU Lesser General Public License v3.0 (or later).
Upstream copyright remains with the original Sub2API authors. This fork does not grant extra commercial rights.