Model or dataset
yym68686/uni-api avatar
yym68686/uni-api

uni-api: Config-File LLM Routing Without a Front End

This is a project that unifies the management of LLM APIs. It can call multiple backend services through a unified API interface, convert them to the OpenAI format uniformly, and support load balancing. Currently supported backend services include: OpenAI, Anthropic, DeepBricks, OpenRouter, Gemini, Vertex, etc.

1,256 stars157 forksPythonApache-2.0

At a glance

What is it?
uni-api is a Python gateway that turns a YAML file into an OpenAI-compatible endpoint in front of OpenAI, Anthropic, Gemini, Vertex, Azure, AWS and others. It is aimed at individuals who find one/new-api too heavy, and its main trade-off is that the configuration file is the entire control plane.
Who is it for?
Adopt uni-api if you are running a personal or small-team endpoint and want provider routing, retries and channel cooling defined in a single api.yaml rather than in a web console. Do not adopt it if you need multi-tenant billing, a browser UI, or a governance layer that non-engineers can operate.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem: one endpoint, many provider APIs

Every provider ships its own request shape. Anthropic does not accept OpenAI chat payloads, Gemini and Vertex have their own authentication and body formats, and Azure and AWS differ again in how the endpoint and key are expressed. If you use more than one of them, your client code accumulates per-provider branches, and every new model means touching application code.

uni-api moves that branching into a configuration file. The README states the intent plainly: it is for personal use, and one/new-api is described as too complex with commercial features an individual does not need. The target reader is someone who wants to run their own API station by writing a file, without a front-end interface. That is a narrower audience than a general gateway product, and the documentation is written for it.

What the request path actually looks like

The architecture is a translation and routing layer. A client sends an OpenAI-format request to one of the exposed endpoints: /v1/chat/completions, /v1/responses, /v1/images/generations, /v1/embeddings, /v1/audio/transcriptions, /v1/audio/speech, /v1/moderations or /v1/models. uni-api resolves the requested public model name to a provider entry in api.yaml, rewrites the request into that provider's native format, and sends it upstream. Native tool use and native image recognition are supported for OpenAI, Anthropic, Gemini, Vertex, Azure, AWS and xai, which means the translation covers structured function calls and image inputs, not just plain text turns.

On the way back, the provider response is converted into OpenAI format. This is the part that decides how much of a provider's extra surface you can reach: anything the translation layer does not model is not visible to your client. Model renaming is handled at the same layer, so claude-sonnet-4-5-20250929 can be exposed as claude-sonnet-4-5 and your callers never see the dated identifier.

Load balancing, retries and channel cooling

Three scheduling mechanisms are described in the README, and two of them are off by default. Channel-level weighted load balancing distributes requests according to weights you assign to channels, and requires configuring those weights. Channel-level sequential balancing is enabled by setting SCHEDULING_ALGORITHM to round_robin; the README frames it as improving the immersive translation experience, which suggests the intended use is a steady stream of short requests rather than bursty traffic. The third mechanism, key-level round-robin, rotates multiple API keys inside a single channel and is described as automatic.

Failure handling is the more interesting part. When a channel fails, uni-api retries the next channel, and the failed channel enters a cooling period during which it receives no requests. When cooling ends the model is restored, and if it fails again it is cooled again. This is a circuit-breaker pattern implemented per channel, and it means a provider outage degrades capacity rather than producing errors, provided you configured more than one channel for that model. Per-model timeouts are configurable, so a slow reasoning model does not inherit the timeout of a fast one.

The README does not state the default cooling duration or the retry count. Those values are not in the supplied material, so treat them as something to confirm in the repository before relying on the behaviour.

Getting it running: api.yaml and the two startup paths

There is no way to start uni-api without a configuration file. The README gives two options. The first sets the CONFIG_URL environment variable to a URL, and the file is downloaded at startup. The second mounts a file named api.yaml into the container; the name is not negotiable, and the documentation repeats that requirement. A Docker image is published as yym68686/uni-api, and a one-click deploy button for Fugue is offered alongside.

The minimum working file has two top-level keys. Under providers, each entry needs provider (a label, and it can be any name), base_url pointing at the upstream chat completions address, and api holding the provider key. If you omit the model list, uni-api calls the /v1/models endpoint on that base_url with that key and imports every available model. Under api_keys, each entry is a key your own callers will present; a key with no channel restrictions can reach every model from every provider.

The advanced form adds a model list with optional renaming using the original-name: short-name syntax, plus filters. exclude_endpoints takes exact request paths such as /v1/responses/compact. exclude_request_types takes semantic types such as compaction, which the README defines as either that path or a /v1/responses call with input type compaction_trigger. exclude_request_rules is the most specific: it matches on fields including endpoint and request_model, and the provider is skipped only when every field in a rule matches. only_request_types is the inverse, restricting a provider to the listed types. These filters exist so that a provider which cannot handle a particular request shape is never selected for it.

Access control is coarse, and that is the point

Per-key permissions are set with wildcards over model names, and rate limiting is expressed as a human-readable string: 2/min, 5/hour, 10/day, 10/month, 10/year. The default is 60/min. That is the whole authorization model described in the README. There is no notion of an account, a balance or a quota in currency, which is consistent with the stated goal of avoiding commercial features.

If you are handing keys to other people, understand what you are and are not getting. You can limit which models a key reaches and how often it can call. You cannot, from the material provided, attribute spend per key, bill for usage, or revoke a key through an interface. Those are application-level concerns you would build on top, and building them is the work that one/new-api already did.

Where it is the wrong tool

The absence of a front end is a deliberate constraint, not an oversight, and it has consequences. Any change to routing, keys, weights, timeouts or rate limits is an edit to api.yaml plus a restart or a re-fetch of CONFIG_URL. There is no audit trail of who changed what, because there is no who: the file is the control plane.

A second limitation is translation fidelity. The supported endpoint list is broad, but each provider's native API is wider than the OpenAI format. Features that have no OpenAI equivalent are not representable in a response, and the README does not enumerate what is dropped. If you depend on a provider-specific parameter that is not part of the OpenAI schema, assume it is unavailable until you confirm otherwise in the code.

Third, the moderation feature is a filter, not a policy engine. It uses OpenAI moderation to screen user messages and returns an error when content is flagged, which the README says reduces the risk of the backend API being banned by providers. It does not give you per-tenant policy, appeals, or logging of flagged content.

Alternatives and the difference in approach

The README names one/new-api directly and positions uni-api against it: one/new-api is described as too complex, carrying commercial features an individual does not need, and offering a complicated front-end. The difference is architectural rather than a matter of feature count. one/new-api is a platform with a user interface and the account, billing and quota machinery that a multi-user deployment requires. uni-api is a process that reads a file and proxies. If your requirement is a shared service with users who log in, uni-api is the wrong shape and one/new-api is the right one. If your requirement is a private endpoint that fronts several providers and survives one of them failing, uni-api is smaller than the alternative and asks less of you.

The same split applies to any gateway with an admin console. The console is a feature when non-engineers must operate the system, and a liability when you would rather keep routing decisions in version control next to the rest of your configuration.

Maintenance, releases and licence

The release cadence is aggressive. Three releases are listed within roughly twenty minutes on 2026-09-10 (v1.7.269, v1.7.270, v1.7.271), and the last push to main is timestamped a few minutes after the newest tag. Whatever else that says, it means the main branch moves constantly. Pin a specific tag in your deployment rather than pulling latest, and read the release notes before moving the pin.

The licence is Apache-2.0, which permits commercial use and modification and includes an explicit patent grant. It also requires that you preserve copyright and licence notices and state significant changes if you redistribute. That is a summary of the licence text, not legal advice; if you plan to redistribute a modified uni-api, read the full terms.

Operationally, the cost of running it is mostly the cost of the configuration file. Every provider you add is another base_url and key to rotate, another model list to keep accurate, and another entry that participates in retries and cooling. The README's automatic model import via /v1/models reduces that burden, but it also means your exposed model surface changes when a provider changes theirs, which is a reason to list models explicitly once your setup stabilises.

Editorial conclusion

Adopt uni-api if you are running a personal or small-team endpoint and want provider routing, retries and channel cooling defined in a single api.yaml rather than in a web console. Do not adopt it if you need multi-tenant billing, a browser UI, or a governance layer that non-engineers can operate. Before deploying, verify three things against your own providers: that the /v1/models endpoint exposes the model names you expect for every configured provider, that your API keys are scoped to the models you intend to expose through wildcards, and that the request-type filters (exclude_endpoints, exclude_request_types, exclude_request_rules) actually skip the traffic you meant to skip. The project publishes releases at a pace of several per day, so pin a tag rather than tracking latest.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. yym68686/uni-api on GitHub
Community notes

Community notes