one-api-pro: an enterprise AI API gateway rebuilt on one-api
one-api-pro is an enterprise-grade AI API Gateway built on one-api(oneapi). It has undergone a full architectural redesign, adding support for subscription plans, active-active clusters, precise billing. one-api-pro是基于one-api(oneapi)的企业级AI API Gateway网关,进行了架构级别的重构,全新支持套餐订阅、多活集群、精确计费、渠道成本管控等功能,适合企业级多员工、多模型统一管理与私有化部署
At a glance
- What is it?
- one-api-pro is a Go and Vue 3 rewrite of one-api that adds subscription plans, order records with WeChat and Alipay payment channels, and a decentralized active-active cluster. It targets teams that need per-model billing and self-hosted multi-tenant access, not single developers.
- Who is it for?
- one-api-pro fits organizations that already run one-api and need subscriptions, order records or multi-region nodes under their own database. It does not fit anyone who wants a single binary with no operational surface: the cluster mode asks each node to run its own MySQL and Redis, and the repository does not document a rollback path or a migration guide from upstream one-api.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- 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 21, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What one-api-pro adds on top of upstream one-api
Upstream one-api aggregates model providers behind one OpenAI-compatible endpoint. one-api-pro keeps that relay layer and rebuilds the surrounding business logic. The README's comparison table frames the fork around four additions: a subscription plan system with per-token or per-request billing and hourly, weekly or monthly rate limits; a full order record per purchase; channel cost control; and a decentralized active-active cluster.
The audience is stated plainly in the repository description: enterprises with many employees and many models that want unified management and private deployment. That is a narrower audience than one-api's. A solo developer routing a few API keys through a laptop gets nothing from an order table or a cluster node registry, and pays for it in setup work.
The billing model is the part that changes day-to-day behavior. Pricing is split into Prompt, Completion and Cached tokens, with group discounts stacked on top. That granularity is why the project exists: one-api bills a request, one-api-pro bills the parts of a request differently.
How the token, plan and order tables fit together
The relay path is the familiar one-api design: a request arrives with a token, the token maps to a user and a channel group, the channel router picks a provider channel by weight and health, and the response is metered with tiktoken-go. The repository keeps channelrouter/, relay/, middleware/ and model/ as separate top-level directories, so the routing and metering code is not fused into the controller layer.
The business layer is where the fork diverges. A plan defines billing mode and rate limits. A subscription binds a user to a plan. Every purchase writes a row into the orders table, and the README states that row carries an order number, the user, a plan snapshot as JSON, the amount, the payment method, status, payment time and a channel transaction number. Storing a snapshot means a later edit to the plan does not rewrite the history of what a customer bought.
Balance top-ups reuse the same table with order type 2 (OrderTypeTopup) and an order number prefixed TP. The README says the payment callback funnels through processNotify, which dispatches on order.Type to ActivatePackageByOrder or ActivateTopupByOrder. Idempotency is handled by returning early when the order is already paid. That single dispatch point is the right shape: one place to reason about double-charging.
Running it locally and creating the first subscription plan
The README offers a prebuilt binary from GitHub Releases or a source build. A source build has an ordering constraint the README calls out explicitly: the backend must be compiled after the frontend, because the Go build embeds the compiled Vue assets.
git clone https://github.com/modelbus/one-api-pro.git
cd one-api-pro
cd web
sh build.sh
cd ..
go build -ldflags "-s -w" -o one-api-proThe web build script reads web/THEMES and builds each theme, with default-pro as the default. The README also documents a release script at the repository root that runs dependency download, frontend build and cross-compilation, and accepts a version argument or --skip-frontend to reuse an existing web/build directory. After the binary starts, http://localhost:3000 serves the console, and the README gives the initial credentials as root / 123456. Change that password before the port is reachable from anywhere else.
If you prefer a container, the Dockerfile has a wrinkle worth knowing before you build. Frontend assets are not built inside the image. The comment in the Dockerfile records that building npm inside a multi-architecture buildx run produced SIGILL under QEMU arm64 emulation, so since v0.0.16 the CI workflow pre-builds web/build/default-pro and the Dockerfile only copies it. The image expects that directory to already exist in the build context.
docker build -t one-api-pro .
docker run -d --name one-api-pro -p 3000:3000 -v /host/config:/app/config -v /host/data:/app/data one-api-proThe image declares the volumes /app/config and /app/data, exposes port 3000, and runs a healthcheck against http://localhost:${PORT}/api/status every 30 seconds. Database selection is environment-driven: leave SQL_DSN unset and the service falls back to SQLite at SQLITE_PATH; set it to a MySQL or PostgreSQL DSN and GORM switches drivers. The .env.example shows both DSN forms as comments.
The cluster mode is not a load balancer
The README describes the cluster as decentralized active-active: each node runs its own MySQL and Redis, and nodes synchronize through application-layer events rather than a shared database. The stated benefit is geographic proximity, since a user in one region does not have to reach a database in another.
This is a real trade-off, and it is worth being blunt about it. Without a shared database, there is no single serialization point for quota deduction. The .env.example exposes MEMORY_CACHE_ENABLED with the warning that enabling it delays quota updates, and SYNC_FREQUENCY defaulting to 600 seconds. Those knobs tell you the consistency model is eventual, not linear. CLUSTER_NODE_ID must match MySQL auto_increment_offset, and the README constrains it to 1 through 49. Get that wrong and nodes collide on primary keys.
If your requirement is a quota that can never be overspent by even one request, a shared database with one writer is the safer architecture, and one-api-pro's cluster mode is the wrong tool. If your requirement is that a request from Singapore does not pay the latency of a database round trip to Frankfurt, the design is aimed at exactly that.
Payment channels, and what the repository does not cover
The README lists native WeChat Pay (Native, PC QR code) and Alipay 当面付 (TradePrecreate), plus three administrative channels: bank transfer, offline and free. Plan upgrades compute the price difference proportionally by remaining days, and the README says stacking mode lets old and new plans run in parallel. All of those rules are described as hot-switchable under 设置 → 套餐运营.
What the README does not document is rollback. There is no described path for reverting a plan activation, reversing a top-up, or reconciling an order whose payment callback never arrived. The order table records a status and a channel transaction number, so the data to investigate exists, but the operational procedure is not in the repository documentation I can see. Plan for that gap before you connect a live payment channel.
The licence situation is also worth a direct look. The README renders an MIT badge linking to a LICENSE file, but the repository metadata I have does not state a licence identifier. Since the project is a fork of one-api, the upstream licence terms matter as well. Read both files rather than trusting the badge.
one-api-pro against LiteLLM and a plain one-api install
LiteLLM is the closest comparison in intent: a Python proxy that presents one OpenAI-compatible interface over many providers, with a virtual key system and spend tracking. The difference in approach is the unit of accounting. LiteLLM's budget model is organized around keys and teams with spend limits; one-api-pro organizes around plans, subscriptions and orders, and it ships the payment collection path in the same binary. If you sell access to models, one-api-pro has the checkout flow and LiteLLM does not. If you only need internal keys with budgets, LiteLLM's model is simpler and you avoid the order table entirely.
Against upstream one-api, the honest framing is that one-api-pro is a superset with a larger operational surface. The README claims fixes to API permission holes in the original and a four-level Guest/User/Admin/Root permission model. If you are already on one-api and your only pain is provider coverage, upgrading buys you a schema with plans, subscriptions and orders in it. That is a migration, not a drop-in replacement, and the repository does not document one.
Maintenance, releases and the cost of following them
The last push to the default branch was on 2026-09-17, and the most recent release listed is v0.0.21 on the same day, following v0.0.20 on 2026-09-13 and v0.0.17 on 2026-09-11. The version numbers are still in the 0.0.x range, which is a signal about API stability rather than activity. The repository is not archived.
Upgrade cost concentrates in three places. The database schema, because orders, plans and subscriptions are tables upstream one-api does not have. The cluster configuration, because CLUSTER_NODE_ID has to stay aligned with the MySQL auto_increment_offset on every node. And the frontend, because the Go binary embeds pre-built Vue assets, so a backend-only rebuild will serve stale UI unless web/build is regenerated first. The release.sh script at the repository root automates dependency download, frontend build and cross-compilation, and accepts --skip-frontend when you want to reuse an existing web/build directory.
Running the release script yourself is the cheapest way to see the real upgrade surface, because it makes the frontend-before-backend ordering explicit instead of hiding it inside CI.
Editorial conclusion
one-api-pro fits organizations that already run one-api and need subscriptions, order records or multi-region nodes under their own database. It does not fit anyone who wants a single binary with no operational surface: the cluster mode asks each node to run its own MySQL and Redis, and the repository does not document a rollback path or a migration guide from upstream one-api. Before adopting it, check the LICENSE file the README links to, confirm the payment channel you need is one of the three the README lists, and read docker-entrypoint.sh to see which environment variables the container actually consumes.
Frequently asked questions
What is one-api-pro and how does it differ from one-api?
one-api-pro is an AI API gateway built on one-api and described as an enterprise-grade rewrite. The README lists subscription plans, order records with WeChat and Alipay payment channels, precise per-token cost accounting, channel cost control and a decentralized active-active cluster as the additions over upstream.
How do I install one-api-pro?
Download a prebuilt binary from GitHub Releases, or build from source. A source build requires the Vue frontend to be compiled first, because the Go build embeds the frontend assets, then go build produces the binary and ./one-api-pro --port 3000 starts it.
What database does one-api-pro use?
GORM supports SQLite, MySQL and PostgreSQL. If SQL_DSN is unset the service falls back to SQLite at SQLITE_PATH; setting SQL_DSN to a MySQL or PostgreSQL connection string switches the driver, and .env.example shows both forms.
Community notes