MAX API: a Go model gateway with billing reconciliation and scope-bound step-up auth
MAX API Next 社区是由来自科研机构和高校的 AGI 爱好者组织发起、维护和运营的研究驱动型技术社区,聚焦 AI Models 与 Agents 治理方向,致力于建设面向 AGI 应用时代的开放基础设施。社区关注多模型与多平台接入、国产模型持续适配、AgentOps 工程实践、成本审计、权限与安全边界、私有化部署和长期运营优化,目标是把模型服务、Agent 应用、用户组织和上游平台之间的共性治理问题沉淀为稳定、可复用、可持续演进的工程能力。
At a glance
- What is it?
- MAX-API-Next/MAX-API is an AGPL-3.0 Go gateway that sits between agents and upstream model providers. Its distinguishing work is not routing but settlement: idempotent billing records, persistent effects, and a manual reconciliation state for failed long tasks.
- Who is it for?
- Adopt MAX API if you are routing several agents or tenants through multiple model providers and you need per-token budgets, idempotent settlement, and a single audit trail for credentials and high-risk operations; the SQLite default makes a local trial cheap, and the Docker image is pinned by digest.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 17, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem MAX API targets: governance between agents and providers
Direct connections to several model providers push the same work into every application. Credentials spread across environment variables, each SDK has its own error format, retries and failover are reimplemented per service, and cost attribution becomes a monthly exercise in matching invoices. MAX API positions itself as the layer that absorbs those concerns: the README describes it as sitting between applications, agents and upstream model services, acting as a unified model gateway, governance control plane and operations entry point. The intended audience is explicit in the repository description: developers, researchers, enterprise engineering teams, university contributors, and open source contributors working on AI models and agents governance. The project is organized by the MAX-API-Next community, which describes itself as research-driven and focused on multi-model access, domestic model adaptation, AgentOps practice, cost auditing, permission and security boundaries, private deployment and long-term operations. If you run one model from one application, this is more infrastructure than you need. The value appears when several teams, tokens or agents share the same upstream accounts and someone has to answer who spent what and who is allowed to call which model.
How the gateway is put together: Go relay, Gin router, multi-database storage
The repository layout shows a conventional Go service split: main.go at the root, with relay/, router/, controller/, service/, model/, middleware/, setting/, dto/ and types/ as the working directories, plus a web/ tree for the frontend and an electron/ directory. go.mod declares go 1.25.1 and a dependency set that maps directly to the stated capabilities: gin-gonic/gin for HTTP, gin-contrib/sessions for sessions, go-webauthn/webauthn for Passkey, pquerna/otp for TOTP second factors, golang-jwt/jwt for tokens, go-redis/redis for shared cache and coordination, glebarez/sqlite alongside the MySQL and PostgreSQL drivers, shopspring/decimal for money arithmetic, stripe-go and Calcium-Ion/go-epay for payment paths, tiktoken-go/tokenizer for token counting, and gorilla/websocket for realtime traffic. Protocol coverage is visible in the same file: aws-sdk-go-v2/service/bedrockruntime for Bedrock, plus audio decoders (go-audio/wav, go-audio/aiff, mewkiz/flac, tcolgate/mp3, jfreymuth/oggvorbis, abema/go-mp4) which line up with the README's claim of multimodal and asynchronous task protocols. The Dockerfile builds the frontend with Bun, then compiles the Go binary with CGO_ENABLED=0 and GOEXPERIMENT=greenteagc, stripping symbols and injecting the version from the VERSION file, and runs it on debian:bookworm-slim. The binary listens on port 3000 and the container entrypoint runs with /data as the working directory, which is why the quick start mounts a data volume there.
Billing that survives retries: idempotent settlement and the manual state
The most interesting design decision in the README is the treatment of money. The stated mechanism is pre-deduction, final settlement, idempotent records, failure refunds, asynchronous task polling and a manual reconciliation state. The goal is stated plainly: avoid duplicate charges, wrong refunds or untraceable results when long tasks, retries and exception windows overlap. The README summarizes this as One Billing Truth, meaning production billing, quota and settlement keep a single source of truth and no second accounting path is created for agents or plugins. That is a real architectural commitment, and it has a cost. Idempotent settlement and persistent effects require durable state, which is why the project warns that SQLite is for local experience, development and small-scale testing, while production should use MySQL (the README suggests 8.4 LTS) or PostgreSQL (14+) along with Redis, HTTPS, backup and recovery. Money is handled with decimal arithmetic rather than floats, which is the correct choice for token pricing. The manual state is worth reading as an admission: the system does not promise that every asynchronous task resolves automatically, only that unresolved tasks land somewhere a human can audit instead of silently disappearing.
Installing MAX API with Docker and making a first request
The README's quick start uses SQLite and needs only Docker. The image is pinned by digest in both the README and docker-compose.yml, which means the tag cannot silently move under you. Pull and run it with a local data volume:
MAX_API_IMAGE=cscitechtop/max-api:latest@sha256:006d5d86887a261baab4d71ec3797d429e3771a4836e5899734aee0e7f66f2ab
docker pull "$MAX_API_IMAGE"
docker run --name max-api -d --restart always -p 127.0.0.1:3000:3000 -e TZ=Asia/Shanghai -v ./data:/data "$MAX_API_IMAGE"The container binds to 127.0.0.1:3000, so it is reachable at http://localhost:3000 but not from other hosts until you change the port mapping. The README then lists three steps: create or confirm the administrator account, add an upstream channel and API key that you are legally authorized to use, and create an access token, pointing your application's Base URL at MAX API. For a production-shaped deployment, docker-compose.yml wires the gateway to PostgreSQL and Redis and sets the environment variables that matter:
services:
max-api:
image: cscitechtop/max-api:latest@sha256:006d5d86887a261baab4d71ec3797d429e3771a4836e5899734aee0e7f66f2ab
ports:
- "127.0.0.1:3000:3000"
volumes:
- ./data:/data
- ./logs:/app/logs
environment:
- SQL_DSN=postgresql://root:123456@postgres:5432/max-api
- REDIS_CONN_STRING=redis://:123456@redis:6379
- ERROR_LOG_ENABLED=true
- BATCH_UPDATE_ENABLED=true
- NODE_NAME=max-api-node-1The file carries a warning to change the default passwords before production, and NODE_NAME is documented as the node identity used in audit logs, recommended when running multiple instances. The .env.example file is the reference for everything else, including SQL_MAX_OPEN_CONNS, SQL_MAX_LIFETIME, SYNC_FREQUENCY, MEMORY_CACHE_ENABLED, RELAY_TIMEOUT and STREAMING_TIMEOUT, which defaults to 300 seconds and is described as the value to raise if you see empty completions. One variable deserves caution: QUOTA_DATA_AGGREGATE_MIGRATION_ENABLED is documented as off by default and only to be set to true manually on a single primary node during a low-traffic window, because it reorganizes the quota_data table and creates a unique aggregate_key index.
Where MAX API is the wrong choice
The release line is the first limitation. The most recent releases listed are v2.0.0-smartops.pre2 (2026-09-13) and v2.0.0-smartops.pre1 (2026-09-01), both pre-releases; the last stable-looking tag is v1.0.5 from 2026-08-16. Teams that need a frozen API contract should not build on a pre-release line without expecting changes. Second, the operational floor is higher than the quick start suggests. The README states that SQLite suits local experience, development and small-scale testing, and that production should run MySQL or PostgreSQL inside the vendor's security support window, with Redis, HTTPS, backup and recovery configured. A single-container trial and a production deployment are different projects. Third, the billing guarantees depend on durable storage; if your database is not backed up, idempotent settlement protects you from double-charging but not from losing the ledger. Fourth, the README does not document a rollback procedure beyond advising a database backup and a prepared rollback plan before upgrading. If your change-management process requires a tested downgrade path, that gap is on you to close. Finally, the project is explicitly built for multi-tenant, multi-provider governance. A single application calling a single provider gets routing, logging and quota features it will not use, plus a database and Redis to operate.
Alternatives and the difference in approach
The obvious comparison is a self-hosted gateway such as LiteLLM, which the README does not name. The architectural difference is where the money logic lives. A typical Python gateway proxy focuses on normalizing provider APIs and exposing an OpenAI-compatible endpoint, with spend tracking layered on top of request logs. MAX API instead treats settlement as a first-class state machine: pre-deduction, idempotent settlement, persistent effects, failure refunds, asynchronous task IDs, and an explicit pending or manual state, with the README stating that agents and plugins must not create a second accounting path. That is a heavier design, and it is the reason the project insists on MySQL or PostgreSQL for production. The second difference is scope. MAX API bundles the governance plane itself: users, tokens, model scopes, groups, routing, rate limits, quotas, prices and administrator permissions, plus Passkey, 2FA, Telegram, API tokens and session revocation with scope-bound step-up verification and session_generation. A lighter proxy leaves identity and permissions to whatever sits in front of it. If your organization already has an identity provider and a billing system, the lighter approach integrates with less friction; if it does not, MAX API is trying to be that system.
Licence, maintenance and upgrade cost
The repository is licensed AGPL-3.0, and the Dockerfile copies LICENSE, NOTICE and THIRD-PARTY-LICENSES.md into the image. The practical implication of AGPL-3.0 is the network clause: if you modify the software and let users interact with it over a network, the licence's source-availability obligation can extend to your modified version. Running an unmodified image behind your own API is a different situation from forking it and offering it as a service, but the boundary is fact-specific and not something this article can settle; read the licence text and get your own advice if you plan to redistribute or host a modified build. On maintenance, the repository is not archived and the last push was on 2026-09-17, the same day as the most recent activity, so the codebase is being touched. Upgrade cost is where the project is honest and thin at the same time. The README's tip for production is to pin a confirmed release tag, back up the database and prepare a rollback plan before upgrading. It does not describe a migration tool, a downgrade path, or a version compatibility matrix. Because the current line is a pre-release, plan for schema and contract changes between v2.0.0-smartops builds, and treat the VERSION file as the thing to diff, since the Dockerfile injects it into the binary at build time.
Editorial conclusion
Adopt MAX API if you are routing several agents or tenants through multiple model providers and you need per-token budgets, idempotent settlement, and a single audit trail for credentials and high-risk operations; the SQLite default makes a local trial cheap, and the Docker image is pinned by digest. Do not adopt it if you only call one provider from one application, or if you need a stable API surface today: the current release line is v2.0.0-smartops.pre2, a pre-release, and the documented rollback guidance is limited to taking a database backup before upgrading. Before committing, verify three things against your own stack: that your database of choice is one of the supported paths (SQLite, MySQL, PostgreSQL), that your settlement flow behaves correctly when an asynchronous task fails and lands in a pending or manual state, and that the AGPL-3.0 network copyleft terms fit how you intend to distribute or host the service.
Frequently asked questions
What is the API limit in MAX API?
The README does not publish a single global request limit. It describes rate limiting, quotas and model scopes as part of the governance control plane, configured per user, token, group or model, and .env.example exposes connection-pool limits such as SQL_MAX_OPEN_CONNS and SQL_MAX_IDLE_CONNS.
What does API mean in the context of MAX API?
In this project an API is the inbound surface that applications and agents call, which MAX API keeps stable while it translates to upstream providers. The README lists OpenAI Compatible, Responses, Claude Messages, Gemini, Realtime, and multimodal and asynchronous task protocols as the supported inbound shapes.
Which API is used the most with MAX API?
The README does not rank usage. It states that the gateway supports OpenAI Compatible, Responses, Claude Messages, Gemini, Realtime, and multimodal and asynchronous task protocols, and that v2.0 enhances Reasoning, cache keys, penalty parameters, tool definitions and multi-turn tool context for several of them.
What are the four types of APIs that MAX API deals with?
The README does not use the four-type taxonomy. It groups its protocol surface as OpenAI Compatible, Responses, Claude Messages, Gemini, Realtime, and multimodal and asynchronous task protocols, each translated through channels, model mapping, groups and routing.
How do I use the Claude Messages API with MAX API?
The README lists Claude Messages among the supported protocols and states that v2.0 enhances Reasoning, cache keys, penalty parameters, tool definitions and multi-turn tool context for Claude Messages. Configuration happens through channels and model mapping rather than application code changes.
Community notes