Skip to content

Repository files navigation

Sub2API Logo

Sub2API m37v7

Base Gemini Go Vue PostgreSQL Redis Docker

An AI API gateway for account management, quota distribution, scheduling, billing, and protocol-compatible access.

中文 | English

This repository is a maintained customization of the official Sub2API project. It is based on official v0.1.184 and is released as m38v1.

Important notice

Please review the terms of service of every upstream provider before using this software. Operate it only in compliance with the laws and regulations applicable to you. This project is provided for technical learning, research, and self-hosted gateway administration; the user is responsible for upstream accounts, credentials, traffic, billing, and all consequences of operation. No commercial operation or provider authorization is implied by this repository.

What is m38v1?

m38v1 keeps the upstream v0.1.184 platform while carrying a complete Gemini 3.8 Flash & 3.7 Flash compatibility layer with full thinking observability.

Custom capability Behavior
Model catalog gemini-3.8-flash* and gemini-3.7-flash* (high, low, medium, tiered)
Base-name routing gemini-3.8-flash resolves to gemini-3.8-flash-medium; gemini-3.7-flash resolves to gemini-3.7-flash-medium
Native thinking observability Extracts thinkingConfig.thinkingLevel from native requests (multi-path, camelCase & snake_case) and records normalized effort in usage logs
Suffix fallback Derives reasoning effort from model suffix when client omits explicit thinkingConfig
Empty parts sanitization Automatically cleans empty parts to comply with upstream Google API strict schema validation
Provider naming Use bare model IDs like gemini-3.8-flash; keep provider as a separate gemini setting
Release identity v0.1.184-m38v1

The custom layer does not replace the upstream gateway architecture. Account management, API keys, groups, billing, scheduling, payments, the admin dashboard, and the other upstream integrations remain part of the v0.1.184 baseline.

Main capabilities

  • Manage multiple upstream accounts using OAuth or API keys.
  • Create user API keys and route users to configured groups.
  • Track token usage and calculate costs at usage-log level.
  • Schedule accounts with sticky sessions, concurrency limits, rate limits, and failover.
  • Expose OpenAI-compatible, Anthropic-compatible, and provider-specific gateway endpoints.
  • Provide an admin dashboard for accounts, groups, users, channels, usage, quotas, and system operations.
  • Support built-in payment flows, including EasyPay, Alipay, WeChat Pay, and Stripe. See docs/PAYMENT.md.
  • Support composite groups that map requested model names to concrete upstream routes. See docs/COMPOSITE_GROUPS.md.
  • Support asynchronous image generation and editing tasks. See docs/ASYNC_IMAGE_TASKS.md.
  • Support Grok/xAI OAuth and API-key accounts, where configured. See the Grok section below.
  • Support Antigravity accounts for Claude and Gemini traffic.

Our deployment path

m37v7 uses one explicit deployment path: build the sub2api:m37v7-0184-local image from this repository, then run it with the local-directory Docker Compose layout. This keeps the application image, PostgreSQL data, Redis data, and configuration under an operator-controlled deployment directory.

The commands below are for this m37v7 repository and use only the versioned image built from this source tree.

Docker Compose deployment

Prerequisites

  • Docker Engine 20.10 or newer.
  • Docker Compose v2 or newer.
  • A host with enough disk space for PostgreSQL, Redis, application data, and logs.
  • An egress path to the upstream providers. If your network requires a proxy, configure it in the deployment environment without committing the value.

1. Build the m37v7 image

From the repository root:

docker build -t sub2api:m37v7-0184-local \
  --build-arg GOPROXY=https://goproxy.cn,direct \
  --build-arg GOSUMDB=sum.golang.google.cn \
  -f Dockerfile .

The image is a multi-stage build: the Vue frontend is compiled first, then embedded into a static Go backend. The final image runs as the non-root sub2api user and exposes port 8080.

On Linux/macOS or Git Bash, the repository helper is equivalent to the build above:

./deploy/build_image.sh
docker tag sub2api:latest sub2api:m37v7-0184-local

On Windows PowerShell, use the explicit docker build command above. The deployment instructions always refer to the versioned m37v7 tag, not latest.

2. Prepare a persistent deployment directory

mkdir -p sub2api-deploy
cp deploy/docker-compose.local.yml sub2api-deploy/docker-compose.yml
cp deploy/.env.example sub2api-deploy/.env.example
cd sub2api-deploy
cp .env.example .env

Edit .env and set at least:

POSTGRES_PASSWORD=replace_with_a_long_random_password
JWT_SECRET=replace_with_a_random_32_byte_secret
TOTP_ENCRYPTION_KEY=replace_with_a_random_32_byte_secret
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=replace_with_a_strong_admin_password
SERVER_PORT=8080
TZ=Asia/Shanghai

Generate secrets with OpenSSL when available:

openssl rand -hex 32

Keep .env private. It can contain database passwords, signing keys, OAuth client secrets, proxy credentials, and other sensitive values. Do not paste it into an issue or commit it to Git.

3. Point Compose at the local m37v7 image

Create docker-compose.override.yml beside the copied compose file. This override both selects the m37v7 image and forwards the deployment-specific Antigravity/proxy settings:

services:
  sub2api:
    image: sub2api:m37v7-0184-local
    environment:
      GATEWAY_ANTIGRAVITY_FORWARD_BASE_URL: ${GATEWAY_ANTIGRAVITY_FORWARD_BASE_URL:-daily}
      HTTP_PROXY: ${HTTP_PROXY:-}
      HTTPS_PROXY: ${HTTPS_PROXY:-}
      NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1,postgres,redis}

The base Compose file already forwards UPDATE_PROXY_URL for GitHub update and pricing traffic. Keep the override file beside docker-compose.yml, otherwise Compose will not load it automatically.

The local compose file stores application, PostgreSQL, and Redis data in data/, postgres_data/, and redis_data/. These directories are the deployment's persistence boundary and should be included in your backup policy.

4. Start and verify

docker compose up -d
docker compose ps
docker compose logs -f sub2api

Then open http://YOUR_SERVER_IP:8080. The compose configuration uses AUTO_SETUP=true, initializes the database on first start, and creates the admin account from ADMIN_EMAIL and ADMIN_PASSWORD. If ADMIN_PASSWORD is left empty, inspect the first-start logs for the generated password.

Health check:

curl -fsS http://127.0.0.1:8080/health

For a deployment behind a reverse proxy, expose only the proxy publicly and keep PostgreSQL and Redis on the internal Compose network. Set a fixed JWT_SECRET and TOTP_ENCRYPTION_KEY before the first production start so container recreation does not invalidate sessions or existing 2FA secrets.

External PostgreSQL and Redis

Use the standalone file when the database and cache are managed outside Compose:

cp deploy/docker-compose.standalone.yml sub2api-deploy/docker-compose.yml
cd sub2api-deploy
cp ../deploy/.env.example .env

Set these connection variables in .env:

DATABASE_HOST=your-postgres-host
DATABASE_PORT=5432
DATABASE_USER=sub2api
DATABASE_PASSWORD=your-database-password
DATABASE_DBNAME=sub2api
DATABASE_SSLMODE=require
REDIS_HOST=your-redis-host
REDIS_PORT=6379
REDIS_USERNAME=
REDIS_PASSWORD=your-redis-password

Also add the same image override shown above. The external services must be reachable from the container and must be backed up independently.

Network, proxy, and Antigravity routing

m37v7 production deployments may use the daily Antigravity forward path and an egress proxy. Keep the values in the private deployment .env or in the persisted application configuration, not in this repository:

# Antigravity forward-base selector used by the m37v7 deployment
GATEWAY_ANTIGRAVITY_FORWARD_BASE_URL=daily

# Optional: proxy for auxiliary GitHub/pricing operations
UPDATE_PROXY_URL=http://proxy.example.com:7890

# If your Compose file forwards these variables to the container, use them for
# the provider egress path as required by your network:
HTTP_PROXY=http://proxy.example.com:7890
HTTPS_PROXY=http://proxy.example.com:7890
NO_PROXY=localhost,127.0.0.1,postgres,redis

The example values above are placeholders. Do not replace them with real credentials in a public commit. Verify that your deployment compose actually forwards HTTP_PROXY, HTTPS_PROXY, and NO_PROXY before relying on them; UPDATE_PROXY_URL is the application setting for update/pricing traffic and is not automatically the same as the AI gateway egress path.

When using Nginx with Codex CLI or other clients that send headers containing underscores, add this inside the Nginx http block:

underscores_in_headers on;

Without it, headers such as session_id may be discarded and sticky-session routing can fail.

For production, consider enabling the URL allowlist and using HTTPS-only upstream URLs. The full template is deploy/config.example.yaml; the edge trust-boundary guidance is deploy/EDGE_SECURITY.md.

Gemini 3.8 Flash & Gemini 3.7 Flash

Model IDs

Use these IDs exactly as written:

gemini-3.8-flash
gemini-3.8-flash-high
gemini-3.8-flash-low
gemini-3.8-flash-medium
gemini-3.8-flash-tiered

gemini-3.7-flash
gemini-3.7-flash-high
gemini-3.7-flash-low
gemini-3.7-flash-medium
gemini-3.7-flash-tiered

The base IDs (gemini-3.8-flash, gemini-3.7-flash) are compatibility aliases for their respective medium route. Explicit high, low, medium, and tiered IDs are retained for clients that need to select a route directly. Do not write google/gemini-3.8-flash when configuring this gateway; the provider name and model ID are separate fields.

Native Gemini requests

For an Antigravity Gemini group, the native-compatible base URL is normally:

https://YOUR_SUB2API_HOST/antigravity/v1beta

The native request may carry a thinking level in either of these locations:

{
  "generationConfig": {
    "thinkingConfig": {
      "thinkingLevel": "HIGH"
    }
  }
}

or:

{
  "thinkingConfig": {
    "thinkingLevel": "MEDIUM"
  }
}

m37v7 normalizes the observed level for usage/audit logging. It does not invent a level when the client omits one.

HanakoAgent integration

For the HanakoAgent client, keep the model ID and provider separate:

models:
  chat:
    id: gemini-3.7-flash
    provider: gemini

HanakoAgent controls the conversational thinking setting. Its current mapping is:

Hanako level Gemini native level
off omitted
minimal / low LOW
medium MEDIUM
high / xhigh HIGH

This means Hanako chooses the effort level, while Sub2API records the native thinkingConfig.thinkingLevel that arrived at the gateway. Keep the Antigravity provider base URL and API key in Hanako's private provider configuration.

Antigravity support

After creating and authorizing an Antigravity account in the admin dashboard, use the dedicated endpoints:

Endpoint Traffic
/antigravity/v1/messages Claude-compatible Messages traffic
/antigravity/v1beta/ Native Gemini traffic

Claude Code example:

export ANTHROPIC_BASE_URL="https://YOUR_SUB2API_HOST/antigravity"
export ANTHROPIC_AUTH_TOKEN="sk-your-sub2api-key"

Antigravity accounts can optionally participate in hybrid scheduling through the general endpoints. Keep Anthropic Claude and Antigravity Claude in separate groups when conversation-context isolation matters; mixing their formats in one context can produce incompatible state.

Other provider features

Grok / xAI

The gateway supports Grok subscription accounts through xAI OAuth and standard xAI API-key accounts. Configure an account in the admin dashboard, attach it to a Grok group, and issue a Sub2API API key to the client. Responses, Chat Completions, Claude-compatible Messages conversion, and supported image/video routes are covered by the upstream provider implementation. Use the model and endpoint details in the dashboard and the source documentation as the authority for a particular release.

Simple mode

For a personal or internal deployment:

RUN_MODE=simple
SIMPLE_MODE_CONFIRM=true

Simple mode hides SaaS features and skips billing/balance checks. Do not enable it on a shared service without understanding the resulting access and accounting model.

Asynchronous image tasks

Long-running image generation and editing requests can use:

POST /v1/images/generations/async
POST /v1/images/edits/async
GET  /v1/images/tasks/{task_id}

See docs/ASYNC_IMAGE_TASKS.md for payloads and polling behavior.

Build from source

Requirements

  • Go 1.27.0.
  • Node.js compatible with the frontend toolchain; Node 24 and pnpm 9 match the Docker build.
  • PostgreSQL 15 or newer.
  • Redis 7 or newer.

Build

git clone https://github.com/TheEarlyWinter/sub2api-m37.git
cd sub2api-m37

corepack enable
corepack prepare pnpm@9 --activate
pnpm --dir frontend install --frozen-lockfile
pnpm --dir frontend run build

cd backend
go build -tags embed -o sub2api ./cmd/server

-tags embed is required because it embeds the compiled frontend into the Go binary. Run ./sub2api from backend/ for the first start. If no configuration exists, use the setup wizard to configure PostgreSQL, Redis, and the initial administrator. Treat deploy/config.example.yaml as a reference template and copy it only after understanding the setup behavior; pre-creating a config file can skip the first-run wizard.

For later starts, set CONFIG_FILE or DATA_DIR according to the deployment layout. Never commit a populated config.yaml containing passwords, tokens, OAuth credentials, or proxy URLs.

Development

# Backend
cd backend
go run ./cmd/server

# Frontend, in another terminal
cd frontend
pnpm run dev

When changing backend/ent/schema, regenerate generated code:

cd backend
go generate ./ent
go generate ./cmd/server

The repository already contains the verified build and deployment checks for this release. Documentation-only changes do not require rerunning the full project test suite.

Upgrade, backup, and rollback

Treat an upgrade as a database migration plus an application-image change. Before replacing a running container:

  1. Record the current image digest/tag and copy the active Compose file and .env to a private backup location.
  2. Create and verify a PostgreSQL dump. Keep the checksum with the dump.
  3. Back up data/, postgres_data/, and redis_data/ when using the local-directory Compose layout.
  4. Keep the previous application image locally until the new image has passed health and smoke checks.

Normal image replacement:

docker compose pull   # only when intentionally using a remote image
docker compose up -d --force-recreate
docker compose ps
curl -fsS http://127.0.0.1:8080/health

Rollback the application image by changing the override back to the previous tag, then recreate the service:

docker compose up -d --force-recreate sub2api
curl -fsS http://127.0.0.1:8080/health

If a migration changed the database schema, restore the database dump only after stopping the application and confirming the restore plan. Do not delete the old data directories or the previous image as part of the first rollback attempt. Database restore is deliberately separate from image rollback because it can overwrite newer writes.

Repository layout

backend/       Go service, gateway, accounts, scheduling, and generated Ent code
frontend/      Vue application and admin dashboard
deploy/        Compose files, environment template, Dockerfile helpers, and config template
docs/          Payment, gateway, security, image-task, and integration guides
assets/        Logo and repository assets

Useful references:

License

This project is licensed under the GNU Lesser General Public License v3.0 or later.

The upstream project and its contributors retain their respective copyrights and licenses. This fork does not grant access to any third-party service, account, credential, or paid feature.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages