A lightweight API gateway that unifies access to multiple large language model providers (OpenAI, Anthropic, Gemini, etc.) through a single OpenAI-compatible interface. It offers configuration-file-based setup, load balancing, automatic retries, and fine-grained permission controls for managing multiple API backends.
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, Gemin...
README
uni-api
Introduction
For personal use, one/new-api is too complex with many commercial features that individuals don't need. If you don't want a complicated frontend interface and prefer support for more models, you can try uni-api. This is a project that unifies the management of large language model APIs, allowing you to call multiple backend services through a single unified API interface, converting them all to OpenAI format, and supporting load balancing. Currently supported backend services include: OpenAI, Anthropic, Gemini, Vertex, Azure, AWS, xai, Cohere, Groq, Cloudflare, OpenRouter, 0-0.pro and more.
✨ Features
- No front-end, pure configuration file to configure API channels. You can run your own API station just by writing a file, and the documentation has a detailed configuration guide, beginner-friendly.
- Unified management of multiple backend services, supporting providers such as OpenAI, Deepseek, OpenRouter, and other APIs in OpenAI format. Supports OpenAI Dalle-3 image generation.
- Simultaneously supports Anthropic, Gemini, Vertex AI, Azure, AWS, xai, Cohere, Groq, Cloudflare, 0-0.pro. Vertex simultaneously supports Claude and Gemini API.
- Support OpenAI, Anthropic, Gemini, Vertex, Azure, AWS, xai native tool use function calls.
- Support OpenAI, Anthropic, Gemini, Vertex, Azure, AWS, xai native image recognition API.
- Support three types of load balancing.
- Supports channel-level weighted load balancing, allowing requests to be distributed according to different channel weights. It is not enabled by default and requires configuring channel weights.
- All APIs support channel-level sequential load balancing, enhancing the immersive translation experience. It is not enabled by default and requires configuring
SCHEDULING_ALGORITHMasround_robin. - Support automatic API key-level round-robin load balancing for multiple API Keys in a single channel.
- Support automatic retry, when an API channel response fails, automatically retry the next API channel.
- Support channel cooling: When an API channel response fails, the channel will automatically be excluded and cooled for a period of time, and requests to the channel will be stopped. After the cooling period ends, the model will automatically be restored until it fails again, at which point it will be cooled again.
- Support fine-grained model timeout settings, allowing different timeout durations for each model.
- Support fine-grained permission control. Support using wildcards to set specific models available for API key channels.
- Support rate limiting, you can set the maximum number of requests per minute as an integer, such as 2/min, 2 times per minute, 5/hour, 5 times per hour, 10/day, 10 times per day, 10/month, 10 times per month, 10/year, 10 times per year. Default is 60/min.
- Supports multiple standard OpenAI format interfaces:
/v1/chat/completions,/v1/responses,/v1/images/generations,/v1/embeddings,/v1/audio/transcriptions,/v1/audio/speech,/v1/moderations,/v1/models. - Support OpenAI moderation moral review, which can conduct moral reviews of user messages. If inappropriate messages are found, an error message will be returned. This reduces the risk of the backend API being banned by providers.
Usage method
To start uni-api, a configuration file must be used. There are two ways to start with a configuration file:
- The first method is to use the
CONFIG_URLenvironment variable to fill in the configuration file URL, which will be automatically downloaded when uni-api starts. - The second method is to mount a configuration file named
api.yamlinto the container.
Method 1: Mount the api.yaml configuration file to start uni-api
One-click deployment:
You must fill in the configuration file in advance to start uni-api, and you must use a configuration file named api.yaml to start uni-api, you can configure multiple models, each model can configure multiple backend services, and support load balancing. Below is an example of the minimum api.yaml configuration file that can be run:
providers:
- provider: provider_name # Service provider name, such as openai, anthropic, gemini, openrouter, can be any name, required
base_url: https://api.your.com/v1/chat/completions # Backend service API address, required
api: sk-YgS6GTi0b4bEabc4C # Provider's API Key, required, automatically uses base_url and api to get all available models through the /v1/models endpoint.
# Multiple providers can be configured here, each provider can configure multiple API Keys, and each provider can configure multiple models.
api_keys:
- api: sk-Pkj60Yf8JFWxfgRmXQFWyGtWUddGZnmi3KlvowmRWpWpQxx # API Key, user request uni-api requires API key, required
# This API Key can use all models, that is, it can use all models in all channels set under providers, without needing to add available channels one by one.
Detailed advanced configuration of api.yaml:
providers:
- provider: provider_name # Service provider name, such as openai, anthropic, gemini, openrouter, can be any name, required
base_url: https://api.your.com/v1/chat/completions # Backend service API address, required
api: sk-YgS6GTi0b4bEabc4C # Provider's API Key, required
model: # Optional, if model is not configured, all available models will be automatically obtained through base_url and api via the /v1/models endpoint.
- gpt-5.2 # Usable model name, required
- claude-sonnet-4-5-20250929: claude-sonnet-4-5 # Rename model, claude-sonnet-4-5-20250929 is the provider's model name, claude-sonnet-4-5 is the renamed name, you can use a simple name to replace the original complex name, optional
- dall-e-3
exclude_endpoints: # Optional. Exact request paths this provider should skip.
- /v1/responses/compact
preferences:
max_request_body_bytes: 20000000 # Optional. Skip this provider when the incoming JSON request body is larger than this many bytes. Numeric values and strings like "20MB" or "20MiB" are supported.
- provider: anthropic
base_url: https://api.anthropic.com/v1/messages
api: # Supports multiple API Keys, multiple keys automatically enable polling load balancing, at least one key, required
- sk-ant-api03-bNnAOJyA-xQw_twAA
- sk-ant-api02-bNnxxxx
model:
- claude-sonnet-4-5-20250929: claude-sonnet-4-5 # Rename model, claude-sonnet-4-5-20250929 is the provider's model name, claude-sonnet-4-5 is the renamed name, you can use a simple name to replace the original complex name, optional
- claude-sonnet-4-5-20250929: claude-sonnet-4-5-think # Rename model, claude-sonnet-4-5-20250929 is the provider's model name, claude-sonnet-4-5-think is the renamed name, if "think" is in the renamed name, it will be automatically converted to claude think model, default think token limit is 4096. Optional
tools: true # Whether to support tools, such as generating code, generating documents, etc., default is true, optional
preferences:
post_body_parameter_overrides: # Support customizing request body parameters
# Apply order: global parameters and global __remove__ first, then model-specific parameters and model-specific __remove__; model-specific settings take precedence.
__remove__: # Optional. Remove top-level request body fields; accepts a string or a list. If omitted, nothing is removed.
- response_format
claude-sonnet-4-5-think: # Add custom request body parameters to the model claude-sonnet-4-5-think
__remove__:
- temperature
tools:
- type: code_execution_20250522 # Add code_execution tool to the model claude-sonnet-4-5-think
name: code_execution
- type: web_search_20250305 # Add web_search tool to the model claude-sonnet-4-5-think, max_uses means to use up to 5 times
name: web_search
max_uses: 5
- provider: gemini
base_url: https://generativelanguage.googleapis.com/v1beta # base_url supports v1beta/v1, only for Gemini model use, required
api: # Supports multiple API Keys, multiple keys automatically enable polling load balancing, at least one key, required
- AIzaSyAN2k6IRdgw123
- AIzaSyAN2k6IRdgw456
- AIzaSyAN2k6IRdgw789
model:
- gemini-3-pro-preview: gemini-3-pro
- gemini-2.5-flash: gemini-2.5-flash # After renaming, the original model name gemini-2.5-flash cannot be used, if you want to use the original name, you can add the original name in the model, just add the line below to use the original name
- gemini-2.5-flash
- gemini-pro-latest: gemini-2.5-pro-search # To enable search for a model, rename it with the -search suffix and set custom request body parameters for this model in `post_body_parameter_overrides`.
- gemini-2.5-flash: gemini-2.5-flash-think-24576-search # To enable search for a model, rename it with the -search suffix and set custom request body parameters for this model in post_body_parameter_overrides. Additionally, you can customize the inference budget using -think-number. These options can be used together or separately.
- gemini-2.5-flash: gemini-2.5-flash-think-0 # Support to rename models with -think-number suffix to enable search, if the number is 0, it means to close the reasoning.
- gemini-embedding-001
- text-embedding-004
tools: true
preferences:
api_key_rate_limit: 15/min # Each API Key can request up to 15 times per minute, optional. The default is 999999/min. Supports multiple frequency constraints: 15/min,10/day
# api_key_rate_limit: # You can set different frequency limits for each model
# gemini-2.5-flash: 10/min,500/day
# gemini-2.5-pro: 5/min,25/day,1048576/tpr # 1048576/tpr means the token limit per request is 1,048,576 tokens.
# default: 4/min # If the model does not set the frequency limit, use the frequency limit of default
api_key_cooldown_period: 60 # Each API Key will be cooled down for 60 seconds after encountering a 429 error. Optional, the default is 0 seconds. When set to 0, the cooling mechanism is not enabled. When there are multiple API keys, the cooling mechanism will take effect.
api_key_schedule_algorithm: round_robin # Set the request order of multiple API Keys, optional. The default is round_robin, and the optional values are: round_robin, random, fixed_priority, smart_round_robin. It will take effect when there are multiple API keys. round_robin is polling load balancing, and random is random load balancing. fixed_priority is fixed priority scheduling, always use the first available API key. `smart_round_robin` is an intelligent scheduling algorithm based on historical success rates, see FAQ for details.
model_timeout: # Model timeout, in seconds, default 100 seconds, optional
gemini-2.5-pro: 500 # Model gemini-2.5-pro timeout is 500 seconds
gemini-2.5-flash: 500 # Model gemini-2.5-flash timeout is 500 seconds
default: 10 # Model does not have a timeout set, use the default timeout of 10 seconds, when requesting a model not in model_timeout, the timeout is also 10 seconds, if default is not set, uni-api will use the default timeout set by the environment variable TIMEOUT, the default timeout is 100 seconds
keepalive_interval: # Heartbeat interval, in seconds, default 99999 seconds, optional. Suitable for when uni-api is hosted on cloudflare and uses inference models. Priority is higher than the global configuration keepalive_interval.
gemini-2.5-pro: 50 # Model gemini-2.5-pro heartbeat interval is 50 seconds, this value must be less than the model_timeout set timeout, otherwise it will be ignored.
proxy: socks5://[username]:[password]@[ip]:[port] # Proxy address, optional. Supports socks5 and http proxies, default is not used.
headers: # Add custom http request headers, optional
Custom-Header-1: Value-1
Custom-Header-2: Value-2
post_body_parameter_overrides: # Support customizing request body parameters
gemini-2.5-flash-search: # Add custom request body parameters to the model gemini-2.5-flash-search
tools:
- google_search: {} # Add google_search tool to the model gemini-2.5-flash-search
- url_context: {} # Add url_context tool to the model gemini-2.5-flash-search
- provider: vertex
project_id: gen-lang-client-xxxxxxxxxxxxxx # Description: Your Google Cloud project ID. Format: String, usually composed of lowercase letters, numbers, and hyphens. How to obtain: You can find your project ID in the project selector of the Google Cloud Console.
region: global # Vertex AI region, optional and defaults to global. Set one explicit region such as us-central1 when needed.
private_key: "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE" # Description: Private key for Google Cloud Vertex AI service account. Format: A JSON formatted string containing the private key information of the service account. How to obtain: Create a service account in Google Cloud Console, generate a JSON formatted key file, and then set its content as the value of this environment variable.
client_email: [email protected] # Description: Email address of the Google Cloud Vertex AI service account. Format: Usually a string like "[email protected]". How to obtain: Generated when creating a service account, or you can view the service account details in the "IAM and Admin" section of the Google Cloud Console.
model:
- gemini-2.5-flash
- gemini-3-pro-preview: gemini-3-pro
- gemini-pro-latest: gemini-2.5-pro-search # To enable search for a model, rename it with the -search suffix and set custom request body parameters for this model in `post_body_parameter_overrides`. Not setting post_body_parameter_overrides will not enable search.
- claude-sonnet-4-5@20250929: claude-sonnet-4-5
- claude-opus-4-5@20251101: claude-opus-4-5
- claude-haiku-4-5@20251001: claude-haiku-4-5
- gemini-embedding-001
- text-embedding-004
tools: true
notes: https://xxxxx.com/ # You can put the provider's website, notes, official documentation, optional
preferences:
post_body_parameter_overrides: # Support customizing request body parameters
gemini-2.5-pro-search: # Add custom request body parameters to the model gemini-2.5-pro-search
tools:
- google_search: {} # Add google_search tool to the model gemini-2.5-pro-search
gemini-2.5-flash:
generationConfig:
thinkingConfig:
includeThoughts: True
thinkingBudget: 24576
maxOutputTokens: 65535
gemini-2.5-flash-search:
tools:
- google_search: {}
- url_context: {}
- provider: cloudflare
api: f42b3xxxxxxxxxxq4aoGAh # Cloudflare API Key, required
cf_account_id: 8ec0xxxxxxxxxxxxe721 # Cloudflare Account ID, required
model:
- '@cf/meta/llama-3.1-8b-instruct': llama-3.1-8b # Rename model, @cf/meta/llama-3.1-8b-instruct is the provider's original model name, must be enclosed in quotes, otherwise yaml syntax error, llama-3.1-8b is the renamed name, you can use a simple name to replace the original complex name, optional
- '@cf/meta/llama-3.1-8b-instruct' # Must be enclosed in quotes, otherwise yaml syntax error
- provider: azure
base_url: https://your-endpoint.openai.azure.com
api: your-api-key
model:
- gpt-5.2
preferences:
post_body_parameter_overrides: # Support customizing request body parameters
key1: value1 # Force the request to add "key1": "value1" parameter
key2: value2 # Force the request to add "key2": "value2" parameter
stream_options:
include_usage: true # Force the request to add "stream_options": {"include_usage": true} parameter
cooldown_period: 0 # When cooldown_period is set to 0, the cooling mechanism is not enabled, the priority is higher than the global configuration cooldown_period.
- provider: databricks
base_url: https://xxx.azuredatabricks.net
api:
- xxx
model:
- databricks-claude-sonnet-4: claude-sonnet-4
- databricks-claude-opus-4: claude-opus-4
- databricks-claude-sonnet-4-5: claude-sonnet-4-5
- provider: aws
base_url: https://bedrock-runtime.us-east-1.amazonaws.com
aws_access_key: xxxxxxxx
aws_secret_key: xxxxxxxx
model:
- anthropic.claude-sonnet-4-5-20250929-v1:0: claude-sonnet-4-5
- provider: vertex-express
base_url: https://aiplatform.googleapis.com/
project_id:
- xxx # project_id of key1
- xxx # project_id of key2
api:
- xx.xxx # api of key1
- xx.xxx # api of key2
model:
- gemini-3-pro-preview
- provider: other-provider
base_url: https://api.xxx.com/v1/messages
api: sk-bNnAOJyA-xQw_twAA
model:
- causallm-35b-beta2ep-q6k: causallm-35b
- anthropic/claude-sonnet-4-5
tools: false
engine: openrouter # Force the use of a specific message format, currently supports gpt, claude, gemini, openrouter native format, optional
# Doubao (Volcengine Ark) Translation via /api/v3/responses
- provider: doubao-translate
base_url: https://ark.cn-beijing.volces.com/api/v3/responses
api: xxxxxxxxxxxxxxxxxxxxxxxx
model:
- doubao-seed-translation
preferences:
post_body_parameter_overrides:
doubao-seed-translation:
translation_options:
target_language: zh # Default target language (optional)
# source_language: en # Optional
api_keys:
- api: sk-KjjI60Yf0JFWxfgRmXqFWyGtWUd9GZnmi3KlvowmRWpWpQRo # API Key, required for users to use this service
model: # Models that can be used by this API Key, optional. Default channel-level polling load balancing is enabled, and each request model is requested in sequence according to the model configuration. It is not related to the original channel order in providers. Therefore, you can set different request sequences for each API key.
- gpt-5.2 # Usable model name, can use all gpt-5.2 models provided by providers
- claude-sonnet-4-5 # Usable model name, can use all claude-sonnet-4-5 models provided by providers
- gemini/* # Usable model name, can only use all models provided by providers named gemini, where gemini is the provider name, * represents all models
role: admin # Set the alias of the API key, optional. The request log will display the alias of the API key. If role is admin, only this API key can request the v1/stats,/v1/generate-api-key endpoints. If all API keys do not have role set to admin, the first API key is set as admin and has permission to request the v1/stats,/v1/generate-api-key endpoints.
- api: sk-pkhf60Yf0JGyJxgRmXqFQyTgWUd9GZnmi3KlvowmRWpWqrhy
model:
- anthropic/claude-sonnet-4-5 # Usable model name, can only use the claude-sonnet-4-5 model provided by the provider named anthropic. Models with the same name from other providers cannot be used. This syntax will not match the model named anthropic/claude-sonnet-4-5 provided by other-provider.
- <anthropic/claude-sonnet-4-5> # By adding angle brackets on both sides of the model name, it will not search for the claude-sonnet-4-5 model under the channel named anthropic, but will take the entire anthropic/claude-sonnet-4-5 as the model name. This syntax can match the model named anthropic/claude-sonnet-4-5 provided by other-provider. But it will not match the claude-sonnet-4-5 model under anthropic.
- openai-test/omni-moderation-latest # When message moderation is enabled, the omni-moderation-latest model under the channel named openai-test can be used for moderation.
- sk-KjjI60Yd0JFWtxxxxxxxxxxxxxxwmRWpWpQRo/* # Support using other API keys as channels
preferences:
SCHEDULING_ALGORITHM: fixed_priority # When SCHEDULING_ALGORITHM is fixed_priority, use fixed priority scheduling, always execute the channel of the first model with a request. Default is enabled, SCHEDULING_ALGORITHM default value is fixed_priority. SCHEDULING_ALGORITHM optional values are: fixed_priority, round_robin, weighted_round_robin, lottery, random.
# When SCHEDULING_ALGORITHM is random, use random polling load balancing, randomly request the channel of the model with a request.
# When SCHEDULING_ALGORITHM is round_robin, use polling load balancing, request the channel of the model used by the user in order.
AUTO_RETRY: true # Whether to automatically retry, automatically retry the next provider, true for automatic retry, false for no automatic retry, default is true. Also supports setting a number, indicating the number of retries.
rate_limit: 15/min # Supports rate limiting, each API Key can request up to 15 times per minute, optional. The default is 999999/min. Supports multiple frequency constraints: 15/min,10/day
# rate_limit: # You can set different frequency limits for each model
# gemini-2.5-flash: 10/min,500/day
# gemini-2.5-pro: 5/min,25/day
# default: 4/min # If the model does not set the frequency limit, use the frequency limit of default
ENABLE_MODERATION: true # Whether to enable message moderation, true for enable, false for disable, default is false, when enabled, it will moderate the user's message, if inappropriate messages are found, an error message will be returned.
# Channel-level weighted load balancing configuration example
- api: sk-KjjI60Yd0JFWtxxxxxxxxxxxxxxwmRWpWpQRo
model:
- gcp1/*: 5 # The number after the colon is the weight, weight only supports positive integers.
- gcp2/*: 3 # The size of the number represents the weight, the larger the number, the greater the probability of the request.
- gcp3/*: 2 # In this example, there are a total of 10 weights for all channels, and 10 requests will have 5 requests for the gcp1/* model, 2 requests for the gcp2/* model, and 3 requests for the gcp3/* model.
preferences:
SCHEDULING_ALGORITHM: weighted_round_robin # Only when SCHEDULING_ALGORITHM is weighted_round_robin and the above channel has weights, it will request according to the weighted order. Use weighted polling load balancing, request the channel of the model with a request according to the weight order. When SCHEDULING_ALGORITHM is lottery, use lottery polling load balancing, request the channel of the model with a request according to the weight randomly. Channels without weights automatically fall back to round_robin polling load balancing.
AUTO_RETRY: true
credits: 10 # Supports setting balance, the number set here represents that the API Key can use 10 dollars, optional. The default is unlimited balance, when set to 0, the key cannot be used. When the user has used up the balance, subsequent requests will be blocked.
created_at: 2024-01-01T00:00:00+08:00 # When the balance is set, created_at must be set, indicating that the usage cost starts from the time set in created_at. Optional. The default is 30 days before the current time.
preferences: # Global configuration
model_timeout: # Model timeout, in seconds, default 100 seconds, optional
gpt-5.2: 10 # Model gpt-5.2 timeout is 10 seconds, gpt-5.2 is the model name, when requesting models like gpt-5.2-2025-12-11, the timeout is also 10 seconds
claude-sonnet-4-5: 10 # Model claude-sonnet-4-5 timeout is 10 seconds, when requesting models like claude-sonnet-4-5-20250929, the timeout is also 10 seconds
default: 10 # Model does not have a timeout set, use the default timeout of 10 seconds, when requesting a model not in model_timeout, the default timeout is 10 seconds, if default is not set, uni-api will use the default timeout set by the environment variable TIMEOUT, the default timeout is 100 seconds
gemini-3-pro: 30 # Model gemini-3-pro timeout is 30 seconds, when requesting models starting with gemini-3-pro, the timeout is 30 seconds
gemini-3-pro-image: 100 # Model gemini-3-pro-image timeout is 100 seconds, when requesting models starting with gemini-3-pro-image, the timeout is 100 seconds
cooldown_period: 300 # Channel cooldown time, in seconds, default 300 seconds, optional. When a model request fails, the channel will be automatically excluded and cooled down for a period of time, and will not request the channel again. After the cooldown time ends, the model will be automatically restored until the request fails again, and it will be cooled down again. When cooldown_period is set to 0, the cooling mechanism is not enabled.
rate_limit: 999999/min # uni-api global rate limit, in times/minute, supports multiple frequency constraints, such as: 15/min,10/day. Default 999999/min, optional.
keepalive_interval: # Heartbeat interval, in seconds, default 99999 seconds, optional. Suitable for when uni-api is hosted on cloudflare and uses inference models.
gemini-2.5-pro: 50 # Model gemini-2.5-pro heartbeat interval is 50 seconds, this value must be less than the model_timeout set timeout, otherwise it will be ignored.
error_triggers: # Error triggers, when the message returned by the model contains any of the strings in the error_triggers, the channel will return an error. Optional
- The bot's usage is covered by the developer
- process this request due to overload or policy
proxy: socks5://[username]:[password]@[ip]:[port] # Proxy address, optional.
model_price: # Model price, in dollars/M tokens, optional. Default price is 1,2, which means input 1 dollar/1M tokens, output 2 dollars/1M tokens.
gpt-5.2: 1,2
claude-sonnet-4-5: 0.12,0.48
default: 1,2
Mount the configuration file and start the uni-api docker container:
docker run --user root -p 8001:8000 --name uni-api -dit \
-v ./api.yaml:/home/api.yaml \
yym68686/uni-api:latest
Method two: Start uni-api using the CONFIG_URL environment variable
After writing the configuration file according to method one, upload it to the cloud disk, get the file's direct link, and then use the CONFIG_URL environment variable to start the uni-api docker container:
docker run --user root -p 8001:8000 --name uni-api -dit \
-e CONFIG_URL=http://file_url/api.yaml \
yym68686/uni-api:latest
Codex (/v1/responses + engine: codex)
If you want to use Codex CLI / OpenAI Responses API clients directly against uni-api:
- Point the client
base_urlto uni-api and use a uni-apiapi_keys[].api. - Add a provider with
engine: codex, and configure multiple account credentials viaapi(list supported; useaccount_id,refresh_tokencomma format; uni-api will automatically mint/refresh anaccess_token). - When an account runs out of quota, uni-api will cool down that token and automatically switch to the next one (default cooldown is 6 hours; override with
api_key_quota_cooldown_period).
Example:
providers:
- provider: codex
engine: codex
# Supports https://chatgpt.com/backend-api/codex or https://chatgpt.com/backend-api/codex/responses
base_url: https://chatgpt.com/backend-api/codex
api:
# Each entry is "account_id,refresh_token" (sets Chatgpt-Account-Id and mints an access_token for Bearer)
- <chatgpt_account_id_1>,<refresh_token_1>
- <chatgpt_account_id_2>,<refresh_token_2>
model:
- gpt-5.2-codex
- gpt-5.2-codex-mini
preferences:
api_key_schedule_algorithm: round_robin
api_key_quota_cooldown_period: 21600 # seconds (optional)
api_keys:
- api: sk-xxx
model:
- codex/*
Tip: if your client only supports /v1/chat/completions, you can still call /v1/chat/completions with the same Codex model names; uni-api will translate upstream Responses streams when needed.
Search providers (/v1/search)
To enable the /v1/search endpoint, configure providers that include the search model, then explicitly allow provider/search in api_keys[].model.
Example (Jina + Tavily):
providers:
- provider: jina
base_url: https://api.jina.ai/v1/chat/completions
api:
- jina_xxx1
- jina_xxx2
model:
- jina-embeddings-v3
- search
preferences:
api_key_rate_limit:
search: 100/min
- provider: tavily
base_url: https://api.tavily.com/search
api:
- tvly-dev-xxx
model:
- search
preferences:
api_key_rate_limit:
search: 100/min
api_keys:
- api: sk-xxx
model:
- jina/search
- tavily/search
Example request:
curl -X GET 'https://xxx.xxx/v1/search?q=Jina%2BAI' \
--header 'Authorization: Bearer sk-xxx'
Environment variable
- CONFIG_URL: The download address of the configuration file, which can be a local file or a remote file, optional
- DEBUG: Whether to enable debug mode, default is false, optional. When enabled, more logs will be printed, which can be used when submitting issues.
- TIMEOUT: Request timeout, default is 100 seconds. The timeout can control the time needed to switch to the next channel when one channel does not respond. Optional
- DISABLE_DATABASE: Whether to disable the database, default is false, optional
- DB_TYPE: Database type, default is sqlite, optional. Supports sqlite and postgres.
- FUGUE_OBSERVABILITY_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT: Optional Fugue telemetry agent HTTP endpoint. When unset, Fugue observability export is disabled and request handling is unchanged.
- FUGUE_OBSERVABILITY_SERVICE_NAME: Optional observability service name, default is
uni-api-ember. - FUGUE_OBSERVABILITY_SAMPLE_RATE: Optional successful request observability sample rate, default is
1.0. Errors are always eligible for export. - FUGUE_OBSERVABILITY_REQUEST_SUMMARY_ENABLED, FUGUE_OBSERVABILITY_STAGE_SPANS_ENABLED, FUGUE_OBSERVABILITY_METRICS_ENABLED: Optional switches for Fugue request summaries, spans, and metrics. Export failure only drops observability data and does not fail business requests.
- STDOUT_REQUEST_SUMMARY_LOG_ENABLED: Optional switch for human-readable stdout request summary logs, default is
true. - STDOUT_REQUEST_SUMMARY_LOG_SAMPLE_RATE: Optional sample rate for human-readable stdout request summary logs, default is
1.0. Use a lower value or disable the logs during high-concurrency tests.
Startup resource sizing
The production launcher computes one immutable concurrency envelope whenever a
new process starts. It reads cgroup v2/v1 CPU and memory, CPU affinity,
RLIMIT_NOFILE, the ephemeral port range/TCP occupancy, and somaxconn.
There is no default 100-request ceiling. The CPU candidate scales from the
measured Fugue baseline of 64 active requests at 465m CPU (cgroup v2 weight 55)
and is then reduced by retained-memory, file-descriptor, and upstream-port
bounds. The default burst target is at least 1000 total admitted requests or
twice the active limit, subject to the same resource bounds.
The accepted TCP connection limit and absolute request-header timeout are
enforced before ASGI admission. Active work, bounded waiters, request bodies,
buffered responses, SSE parsers, and stream queues are separately accounted.
GET /v1/observability/runtime exposes the detected inputs, selected bounds,
reservations, rejections, and connection-protocol counters.
JSON request sizing uses the same cgroup memory envelope instead of a fixed
256 MiB materialization estimate. The default product wire contract is 128
MiB on a sufficiently sized runtime. Startup budgets for the five-times raw
JSON materialization estimate plus one wire-size unit of headroom, caps one
large request at 25% of effective process memory, and starts with one separate
large-body slot. Operators may raise it to two only when the detected memory
envelope can contain both. Smaller requests keep the normal high-concurrency
lane. The runtime observability endpoint exposes the effective
wire, JSON estimate, weighted reservation, large-body threshold, limit, and
active count. REQUEST_LARGE_BODY_THRESHOLD_WEIGHTED_BYTES is measured in
weighted retained-memory bytes, not raw wire bytes.
Large-body slot changes emit body-free large_body_admission_decision events
for claim, reject, and release. Each event carries request_self_* wire,
decoded, JSON-estimator, weighted-reservation, request/trace/lease facts and
runtime_global_* threshold, active/limit, budget, and cgroup facts. The event
records its decision timestamp together with the governor's latest cgroup
sample, sample sequence, age-at-decision, and sampling error. It deliberately
does not perform filesystem I/O while holding the admission lock, so a slow
cgroup read can never delay slot release; the age field is the explicit
boundary rather than a claim of an atomic kernel measurement. Holder identities
stay out of public runtime gauges and metric labels. Admission rejection
decisions and completed or failed ASGI 503 response writes are separate
counters; a joinable
admission_503_response_write_outcome event records the per-request write
result. ASGI write completion does not claim that the remote peer consumed the
response.
Primary overrides are REQUEST_ADMISSION_CPU_MILLICORES (useful when a
standalone host's default CPU weight is not meaningful),
REQUEST_ADMISSION_ACTIVE_LIMIT, REQUEST_ADMISSION_WAITER_LIMIT,
REQUEST_ADMISSION_TOTAL_LIMIT, REQUEST_ADMISSION_MAX_ACTIVE_LIMIT,
REQUEST_ADMISSION_WAIT_TIMEOUT_SECONDS,
MEMORY_SOFT_LIMIT_BYTES, MEMORY_GUARD_BYTES, MEMORY_GUARD_RATIO,
PRODUCT_REQUEST_MAX_BODY_BYTES, REQUEST_MAX_BODY_BYTES,
REQUEST_JSON_COMPLEXITY_MAX_BYTES, REQUEST_BODY_RESERVATION_MAX_BYTES,
REQUEST_LARGE_BODY_THRESHOLD_WEIGHTED_BYTES, REQUEST_LARGE_BODY_LIMIT,
UPSTREAM_POOL_SIZE, UVICORN_CONNECTION_LIMIT, and
UVICORN_HEADER_TIMEOUT_SECONDS. Explicit limits that exceed the detected
startup safety envelope fail startup instead of silently overcommitting. The
formula is a resource-safety envelope, not a throughput guarantee; validate
large CPU shapes with workload-specific load tests.
Without an override, the admission wait deadline is
max(5 seconds, 2 seconds * ceil(total / active)). This gives each bounded
burst wave time to advance instead of applying the old fixed five-second
deadline to every Pod size.
When DB_TYPE is postgres, the following environment variables need to be set:
- DB_USER: Database user name, default is postgres, optional
- DB_PASSWORD: Database password, default is mysecretpassword, optional
- DB_HOST: Database host, default is localhost, optional
- DB_PORT: Database port, default is 5432, optional
- DB_NAME: Database name, default is postgres, optional
Koyeb remote deployment
Click the button below to automatically use the built uni-api docker image to deploy:
There are two ways to let Koyeb read the configuration file, choose one of them:
-
Fill in the environment variable
CONFIG_URLwith the direct link of the configuration file -
Paste the api.yaml file content, if you paste the api.yaml file content directly into the Koyeb environment variable setting file, after pasting the text in the text box, enter the api.yaml path as
/home/api.yamlin the path field.
Then click the Deploy button.
Ubuntu deployment
In the warehouse Releases, find the latest version of the corresponding binary file, for example, a file named uni-api-linux-x86_64-0.0.99.pex. Download the binary file on the server and run it:
wget https://github.com/yym68686/uni-api/releases/download/v0.0.99/uni-api-linux-x86_64-0.0.99.pex
chmod +x uni-api-linux-x86_64-0.0.99.pex
./uni-api-linux-x86_64-0.0.99.pex
Serv00 Remote Deployment (FreeBSD 14.0)
First, log in to the panel, in Additional services click on the tab Run your own applications to enable the option to run your own programs, then go to the panel Port reservation to randomly open a port.
If you don't have your own domain name, go to the panel WWW websites and delete the default domain name provided. Then create a new domain with the Domain being the one you just deleted. After clicking Advanced settings, set the Website type to Proxy domain, and the Proxy port should point to the port you just opened. Do not select Use HTTPS.
ssh login to the serv00 server, execute the following command:
git clone --depth 1 -b main --quiet https://github.com/yym68686/uni-api.git
cd uni-api
python -m venv uni-api
source uni-api/bin/activate
pip install --upgrade pip
cpuset -l 0 pip install -vv -r requirements.txt
From the start of installation to the completion of installation, it will take about 10 minutes. After the installation is complete, execute the following command:
tmux new -A -s uni-api
source uni-api/bin/activate
export CONFIG_URL=http://file_url/api.yaml
export DISABLE_DATABASE=true
# Modify the port, xxx is the port, modify it yourself, corresponding to the port opened in the panel Port reservation
sed -i '' 's/port=8000/port=xxx/' main.py
sed -i '' 's/reload=True/reload=False/' main.py
python main.py
Use ctrl+b d to exit tmux, allowing the program to run in the background. At this point, you can use uni-api in other chat clients. curl test script:
curl -X POST https://xxx.serv00.net/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-xxx' \
-d '{"model": "gpt-5.2","messages": [{"role": "user","content": "Hello"}]}'
Reference document:
https://docs.serv00.com/Python/
https://linux.do/t/topic/201181
https://linux.do/t/topic/218738
Docker local deployment
Start the container
docker run --user root -p 8001:8000 --name uni-api -dit \
-e CONFIG_URL=http://file_url/api.yaml \ # If the local configuration file has already been mounted, there is no need to set CONFIG_URL
-v ./api.yaml:/home/api.yaml \ # If CONFIG_URL is already set, there is no need to mount the configuration file
-v ./uniapi_db:/home/data \ # If you do not want to save statistical data, there is no need to mount this folder
yym68686/uni-api:latest
Or if you want to use Docker Compose, here is a docker-compose.yml example:
services:
uni-api:
container_name: uni-api
image: yym68686/uni-api:latest
environment:
- CONFIG_URL=http://file_url/api.yaml # If a local configuration file is already mounted, there is no need to set CONFIG_URL
ports:
- 8001:8000
volumes:
- ./api.yaml:/home/api.yaml # If CONFIG_URL is already set, there is no need to mount the configuration file
- ./uniapi_db:/home/data # If you do not want to save statistical data, there is no need to mount this folder
CONFIG_URL is the URL of the remote configuration file that can be automatically downloaded. For example, if you are not comfortable modifying the configuration file on a certain platform, you can upload the configuration file to a hostin
Comments (0)
Sign in to join the discussion.
No comments yet
Be the first to share your take.