Sub2API can put one Base URL in front of several AI providers and accounts. Your clients use keys that you issue, while the gateway handles authentication, routing, usage accounting, and concurrency limits.
Getting the containers online is the easy part. Once the gateway is running, you also own its database, Redis instance, TLS endpoint, credentials, logs, backups, and upgrades.
This guide builds the smallest useful private setup and shows what to verify before giving anyone else access.
The request path looks like this:
Sub2API currently supports multiple upstream account types, platform API keys, token-level usage accounting, sticky-session scheduling, per-user and per-account concurrency controls, rate limits, composite groups, and an admin dashboard.
This does not make you independent of the upstream provider. If an upstream account is suspended, overloaded, or incompatible with a request, the gateway cannot manufacture capacity or model access.
The project README also warns that distributing quota from AI subscriptions may violate upstream terms of service. Keep the first deployment private, use accounts you are authorized to use, and review the provider terms before sharing or selling access.
Sub2API is useful when you need to:
If one person calls one official API, adding a gateway usually makes the system more fragile. Self-hosting starts to pay off when access management and routing are already becoming a coordination problem.
For the Docker path, you need a Linux server, Docker 20.10 or newer, Docker Compose v2, a domain, and at least one authorized upstream account or API key. PostgreSQL and Redis are included in the official Compose stack.
The project provides a deployment preparation script. Download it first so you can inspect what it will run:
mkdir -p sub2api-deploy
cd sub2api-deploy
curl -fsSLo docker-deploy.sh \
https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh
less docker-deploy.sh
chmod +x docker-deploy.sh
./docker-deploy.sh
The script saves the Compose definition as docker-compose.yml
, creates .env
, generates the PostgreSQL password and application secrets, and prepares local data directories. It prints the generated credentials to the terminal, so do not paste that output into an issue or chat.
Before starting the stack, edit .env
. If Nginx or Caddy will run on the same server, bind Sub2API to loopback so port 8080 is not exposed directly:
BIND_HOST=127.0.0.1
SERVER_PORT=8080
ADMIN_EMAIL=you@example.com
ADMIN_PASSWORD=replace-with-a-generated-password
TZ=UTC
Keep the generated JWT_SECRET
, TOTP_ENCRYPTION_KEY
, and POSTGRES_PASSWORD
stable. Changing them later can invalidate sessions, break existing 2FA configuration, or disconnect the database.
Start the services and check their status:
docker compose up -d
docker compose ps
docker compose logs -f sub2api
In another shell, check the local health endpoint:
curl -i http://127.0.0.1:8080/health
Confirm that the Sub2API, PostgreSQL, and Redis containers are healthy. Seeing the login page is not enough to prove that the dependencies are working.
Use a domain and HTTPS for the public Base URL. Sub2API handles long-lived SSE and WebSocket traffic, so the reverse proxy must avoid buffering those responses or closing them too early.
The relevant part of an Nginx configuration is:
underscores_in_headers on;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
}
}
underscores_in_headers on;
matters because Nginx otherwise drops headers such as session_id
, which Sub2API uses for sticky-session routing.
If you put a CDN in front of the server, restrict origin access and configure trusted proxy ranges instead of accepting forwarded IP headers from any client. The project's edge security guide covers that setup in more detail.
Verify the public route separately:
curl -i https://api.example.com/health
Start with one route you can understand end to end. The dashboard labels may change between releases, but the setup is roughly:
There are two different credentials in this setup:
Upstream credential -> Sub2API uses it to call the provider
Sub2API key -> your client uses it to call the gateway
Give clients the second key. They should not need the upstream credential.
For an OpenAI Responses-compatible route, make a small request with the test user's key:
export OPENAI_BASE_URL="https://api.example.com/v1"
export OPENAI_API_KEY="your-sub2api-key"
curl "$OPENAI_BASE_URL/responses" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "your-model-alias",
"input": "Return exactly: gateway-ok"
}'
Claude Code commonly uses:
export ANTHROPIC_BASE_URL="https://api.example.com"
export ANTHROPIC_AUTH_TOKEN="your-sub2api-key"
claude
For Codex, start with a clean shell:
export OPENAI_BASE_URL="https://api.example.com/v1"
export OPENAI_API_KEY="your-sub2api-key"
codex
After the first request, open the dashboard and check the record. Confirm that the expected user, key, group, account, model, token count, and charge were used.
Then test the behavior your real client depends on:
Also try an invalid key, a user with no remaining budget, and an unavailable upstream. These tests tell you whether access stops cleanly and whether a failure can silently reach the wrong model.
Before using the gateway for regular work:
latest
unattended./health
, container restarts, disk space, upstream errors, latency, and certificate expiry..env
, the Compose file, application data, and PostgreSQL.Do not copy a live PostgreSQL data directory and assume it is consistent. Use pg_dump
, a database-aware storage snapshot, or stop the stack before taking a filesystem archive. Encrypt backups and test a restore on another machine.
Sub2API is a reasonable choice when you want to own the gateway policy and are willing to operate the supporting infrastructure.
If you would rather not maintain PostgreSQL, Redis, TLS, backups, security, and upstream accounts, do not self-host merely because the code is available. You can compare existing AI API relay services, including services built with Sub2API, on CCNavX.