Skip to content

Repository files navigation

One API

Synopsis

Open‑source version of OpenRouter, managed through a unified gateway that handles all AI SaaS model calls. Core functions include:

  1. Aggregating chat, image, speech, TTS, embeddings, rerank and other capabilities.
  2. Aggregating multiple model providers such as OpenAI, Anthropic, Azure, Google Vertex, OpenRouter, DeepSeek, Replicate, AWS Bedrock, Groq, Grok/xAI, Fireworks, NVIDIA, Cerebras, Cloudflare, ZHIPU GLM, Z.ai, Cohere, etc.
  3. Aggregating various upstream API request formats like Chat Completion, Response, Claude Messages.
  4. Supporting different request formats; users can issue requests via Chat Completion, Response, or Claude Messages, which are automatically and transparently converted to the native request format of the upstream model. Even if the client sends a mismatched request format to wrong api endpoint, it will still be correctly processed.
  5. Supporting multi‑tenant management, allowing each tenant to set distinct quotas and permissions.
  6. Supporting generation of sub‑API Keys; each tenant can create multiple sub‑API Keys, each of which can be bound to different models and quotas.

Also welcome to register and use my deployed one-api gateway, which supports various mainstream models. For usage instructions, please refer to https://wiki.laisky.com/projects/gpt/pay/.

Try it at https://oneapi.laisky.com, login with test / 12345678. 🚀

📖 API reference — see docs/manuals/api_references.md for the complete HTTP API: authentication, conventions, errors, and every endpoint with curl examples, organized for both end-users (inference + API-key management) and administrators.

=== One-API Compatibility Matrix 2025-12-12T04:37:09Z ===
Request Format gpt-4o-mini gpt-5-mini claude-haiku-4-5 gemini-2.5-flash openai/gpt-oss-20b deepseek-chat grok-4-1-fast-non-reasoning azure-gpt-5-nano
Chat (stream=false) PASS 11.21s PASS 13.10s PASS 8.52s PASS 4.64s PASS 9.52s PASS 7.08s PASS 3.08s PASS 14.68s
Chat (stream=true) PASS 13.23s PASS 13.37s PASS 2.31s PASS 6.02s PASS 4.56s PASS 10.92s PASS 9.72s PASS 15.30s
Chat Tools (stream=false) PASS 5.60s PASS 12.94s PASS 7.69s PASS 7.11s PASS 3.14s PASS 8.71s PASS 5.48s PASS* 35.02s
Chat Tools (stream=true) PASS 14.51s PASS 18.90s PASS 7.60s PASS 4.36s PASS 8.87s PASS 7.56s PASS 7.45s PASS 13.13s
Chat Tools History (stream=false) PASS 9.09s PASS 14.28s PASS 12.04s PASS 7.45s PASS 10.40s PASS 9.52s PASS 6.26s PASS 13.61s
Chat Tools History (stream=true) PASS 14.80s PASS 25.49s PASS 3.08s PASS 11.24s PASS 5.22s PASS 4.97s PASS 5.14s PASS 15.56s
Chat Structured (stream=false) PASS 10.51s PASS 15.71s PASS 12.66s PASS 13.68s PASS 8.24s PASS 6.95s PASS 13.42s PASS 13.80s
Chat Structured (stream=true) PASS 11.26s PASS 14.50s PASS 6.07s PASS 4.84s PASS 6.97s PASS 6.86s PASS 4.51s PASS 14.04s
Response (stream=false) PASS 14.65s PASS 15.31s PASS 10.51s PASS 3.03s PASS 3.98s PASS 12.83s PASS 11.29s PASS 15.70s
Response (stream=true) PASS 8.91s PASS 17.54s PASS 6.51s PASS 5.81s PASS 5.26s PASS 7.56s PASS 9.51s PASS 15.66s
Response Vision (stream=false) PASS 12.32s PASS 14.49s PASS 14.12s PASS 8.82s SKIP SKIP PASS 8.74s PASS 16.59s
Response Vision (stream=true) PASS 11.04s PASS 9.50s PASS 10.75s PASS 13.60s SKIP SKIP PASS 9.05s PASS 11.51s
Response Tools (stream=false) PASS 11.02s PASS 11.71s PASS 7.68s PASS 10.55s PASS 4.04s PASS 10.30s PASS 10.15s PASS 12.93s
Response Tools (stream=true) PASS 8.64s PASS 14.40s PASS 10.73s PASS 13.20s PASS 6.81s PASS 7.62s PASS 13.42s PASS 12.03s
Response Tools History (stream=false) PASS 8.04s PASS 14.45s PASS 9.63s PASS 5.54s PASS 5.88s PASS 9.30s PASS 5.22s PASS 11.11s
Response Tools History (stream=true) PASS 9.89s PASS 12.22s PASS 6.58s PASS 5.18s PASS 7.40s PASS 5.84s PASS 4.50s PASS 16.86s
Response Structured (stream=false) PASS 14.35s PASS 15.40s PASS 13.74s PASS 12.78s PASS 7.59s PASS 5.99s PASS 12.10s PASS 13.18s
Response Structured (stream=true) PASS 15.04s PASS 12.68s PASS 12.52s PASS 7.83s PASS 7.85s PASS 3.81s PASS 8.35s PASS 11.01s
Claude (stream=false) PASS 4.78s PASS 11.79s PASS 12.18s PASS 10.58s PASS 8.75s PASS 12.46s PASS 9.66s PASS 14.93s
Claude (stream=true) PASS 4.46s PASS 9.82s PASS 6.43s PASS 14.37s PASS 9.22s PASS 12.17s PASS 3.13s PASS 20.63s
Claude Tools (stream=false) PASS 9.20s PASS 11.08s PASS 11.79s PASS 3.55s PASS 7.39s PASS 6.32s PASS 12.71s PASS 14.85s
Claude Tools (stream=true) PASS 3.01s PASS 6.56s PASS 14.15s PASS 8.11s PASS 9.11s PASS 8.37s PASS 4.16s PASS 12.80s
Claude Tools History (stream=false) PASS 9.67s PASS 15.07s PASS 7.45s PASS 6.70s PASS 8.47s PASS 9.25s PASS 13.92s PASS 15.36s
Claude Tools History (stream=true) PASS 11.15s PASS 19.37s PASS 13.52s PASS 8.90s PASS 7.20s PASS 8.89s PASS 5.81s PASS 9.87s
Claude Structured (stream=false) PASS 5.39s SKIP PASS 7.89s PASS 11.51s PASS 13.30s PASS 8.31s PASS 6.16s SKIP
Claude Structured (stream=true) PASS 6.43s SKIP PASS 11.05s PASS 9.62s PASS 3.05s PASS 4.64s PASS 4.69s SKIP
Totals | Requests: 208 | Passed: 200 | Failed: 0 | Skipped: 8
Warnings (passed with caveats):
- azure-gpt-5-nano - Chat Tools (stream=false) -> tool was not invoked
Skipped (unsupported combinations):
- azure-gpt-5-nano - Claude Structured (stream=false) -> Azure GPT-5 nano does not return structured JSON for Claude messages (empty content)
- azure-gpt-5-nano - Claude Structured (stream=true) -> Azure GPT-5 nano does not return structured JSON for Claude messages (empty content)
- deepseek-chat - Response Vision (stream=false) -> vision input unsupported by model deepseek-chat
- deepseek-chat - Response Vision (stream=true) -> vision input unsupported by model deepseek-chat
- gpt-5-mini - Claude Structured (stream=false) -> GPT-5 mini returns empty content for Claude structured requests
- gpt-5-mini - Claude Structured (stream=true) -> GPT-5 mini streams only usage deltas, never emitting structured JSON blocks
- openai/gpt-oss-20b - Response Vision (stream=false) -> vision input unsupported by model openai/gpt-oss-20b
- openai/gpt-oss-20b - Response Vision (stream=true) -> vision input unsupported by model openai/gpt-oss-20b
2025-12-12T04:37:09Z INFO oneapi-test test/main.go:58 command completed {"command": "run"}

Why this fork exists

The original author stopped maintaining the project, leaving critical PRs and new features unaddressed. As a long‑time contributor, I’ve forked the repository and rebuilt the core to keep the ecosystem alive and evolving.

Tutorial

Docker Compose Deployment

Docker images available on Docker Hub:

  • ppcelery/one-api:latest
  • ppcelery/one-api:arm64-latest

The initial default account and password are root / 123456. Listening port can be configured via the PORT environment variable, default is 3000.

Run one-api using docker-compose:

All environment variables can be set via the environment section in the docker-compose.yml file, please refer to ./common/config/config.go for all available configuration options.

oneapi:
image: ppcelery/one-api:latestrestart: unless-stoppedlogging:
driver: 'json-file'options:
max-size: '10m'environment:
# ⚠️ Only set ENABLE_COOKIE_SECURE=false for HTTP deployments; keep it true for HTTPS to ensure session security
- ENABLE_COOKIE_SECURE=falsevolumes:
- /var/lib/oneapi:/dataports:
- 3000:3000

Important

Session cookies are marked Secure by default, so the browser will only send them over HTTPS. If you are serving the service over plain HTTP (for example accessing http://<host>:3000 directly, or a reverse proxy that terminates HTTPS but is misconfigured), logins will appear to succeed but the next request is unauthenticated, looping the user back to the login page. In that case set ENABLE_COOKIE_SECURE=false in the environment section. Keep it at the default (true) for any production deployment served over HTTPS.

Outbound Email Configuration

one-api can send verification, password reset, quota reminder, and operator notification emails through either SMTP or the Resend HTTP API.

  • EMAIL_PROVIDER=smtp forces the SMTP backend.
  • EMAIL_PROVIDER=resend forces the Resend backend and requires RESEND_API_KEY.
  • Leaving EMAIL_PROVIDER empty enables auto mode: one-api uses Resend when RESEND_API_KEY is configured, otherwise it falls back to SMTP.

When RESEND_API_KEY or EMAIL_PROVIDER is set as a non-empty environment variable, that environment value is authoritative during startup, periodic option sync, and runtime option updates. A saved or cleared database option will not override it. To manage these values from the admin UI instead, remove the corresponding environment variable and restart the service.

Kubernetes Deployment

The Kubernetes deployment guide has been moved into a dedicated document:

Contributors

New Features

Universal Features

I18n Support

Support internationalization (i18n) in the web frontend, including English, Chinese, French, Spanish, and Japanese.

Unified Billing System

All channels share a four-layer billing pipeline (channel overrides → adapter defaults → global fallback → safe default) with support for tiered token pricing, time-of-day pricing windows, cached prompt buckets, and per-second/per-image media meters. Administrators can fetch defaults, override specific models, and audit every call via X-Oneapi-Request-Id; see docs/arch/billing.md for internals and docs/manuals/billing.md for the operational playbook.

Per-channel model_configs can define ratio, completion_ratio, cache-read/cache-write ratios, tiers, time_windows, max_tokens, and media pricing blocks (video, audio, image, embedding). time_windows are ordered wall-clock overlays with explicit timezones; the first matching window at request start time is merged before tiers, so streaming requests keep one consistent rate even when they cross a boundary.

Marketplace and aggregation-channel pricing snapshots such as OpenRouter, Together AI, Fireworks, Replicate, Cloudflare, and Novita are maintained from official provider docs or machine-readable official APIs rather than third-party trackers.

Support Open Telemetry

# set environment variables
OTEL_ENABLED="true"
OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4317"
OTEL_EXPORTER_OTLP_INSECURE="true"
OTEL_SERVICE_NAME="one-api"
OTEL_ENVIRONMENT="debug"

Use http:// with OTEL_EXPORTER_OTLP_INSECURE=true or https:// with OTEL_EXPORTER_OTLP_INSECURE=false. Startup rejects an explicit scheme paired with the opposite transport mode.

Scalable request tracing

Request traces are accumulated in memory and written once per request by an asynchronous batching writer, instead of the per-timestamp read-modify-write statements earlier versions issued. Defaults are unchanged for small deployments; high-volume deployments select a profile and, optionally, move traces out of the database entirely.

# One preset governs every trace knob. Individual variables still win.# Defaults are chosen so an upgrade changes nothing; "scaled" opts in.
OBSERVABILITY_PROFILE="scaled"# standalone (default) | scaled | external# Or tune individually. The standalone value is shown in the comment.
TRACE_WRITE_MODE="batched"# standalone: sync (pre-existing behaviour)
TRACE_SAMPLE_RATE="0.05"# standalone: 1.0
TRACE_ALWAYS_SAMPLE_ERRORS="true"
TRACE_ALWAYS_SAMPLE_SLOW_MS="5000"
TRACE_EXCLUDED_PATH_PREFIXES="/api/status,/metrics,/health,/static,/assets"
TRACE_SINK="db"# db | otlp | none, comma-separated to fan out
TRACE_BATCH_SIZE="500"
TRACE_FLUSH_INTERVAL_MS="1000"
TRACE_QUEUE_SIZE="50000"
TRACE_WRITER_COUNT="4"# Bounded trace resources. TRACE_QUEUE_SIZE bounds only COMPLETED records;# long-lived streaming requests accumulate on the active side, which is what# TRACE_MAX_ACTIVE_RECORDERS bounds. Over the limit a request runs normally# but records no trace, counted as oneapi_trace_records_total{outcome=# "dropped_active_limit"}.
TRACE_MAX_ACTIVE_RECORDERS="200000"# all profiles; 0 restores unbounded
TRACE_MAX_RECORD_BYTES="65536"# standalone: 262144; minimum 1024; truncates, never drops
TRACE_MAX_EXTERNAL_CALLS="256"# standalone: 1024
TRACE_BATCH_MAX_BYTES="8388608"# bounds one writer's flush-local buffer

Errors and slow requests are always retained regardless of the sample rate. TRACE_WRITE_MODE=sync is the legacy in-flight SQL path and therefore requires TRACE_SINK=db (or none) and TRACE_SAMPLE_RATE=1; configurations that need sampling, OTLP, or sink fan-out must use batched and fail fast otherwise. See docs/arch/tracing_system.md.

Upgrade note — observability settings are now validated at startup. These variables previously accepted anything and silently substituted a default: OTEL_ENABLED=1 meant false, TRACE_SINK=cassandra meant db, TRACE_SAMPLE_RATE=5 meant 1, and TRACE_WRITE_MODE=async meant batched. A misconfigured deployment therefore ran with telemetry quietly disabled and no way to find out. They are now rejected at startup with a message naming the variable, the offending value and the allowed values.

This intentional startup behavior affects configurations that were already not doing what they said. Only booleans spelled exactly true/false are accepted — 1, yes and on are not.

The OTLP trace outcome labels are now span_recorded and span_record_failed. The former labels local SDK recording; it does not claim that the asynchronous exporter or collector persisted the span. Dashboards that previously selected exported or export_failed must use the new labels.

Bounded log and telemetry retention

Retention sweeps delete in bounded chunks instead of one unbounded DELETE, and the log directory is bounded by age, total size, and free disk.

# Log files. Every deletion knob is OFF by default so an upgrade never removes# files an operator chose to keep; OBSERVABILITY_PROFILE=scaled turns them on.
LOG_RETENTION_DAYS="7"# standalone: 0 (never delete)
LOG_MAX_TOTAL_SIZE_MB="20480"# standalone: 0 (unlimited)
LOG_MIN_FREE_DISK_MB="1024"# standalone: 0 (guard disabled)
APP_LOG_SINK="both"# file | stdout | both; stdout suits Kubernetes# Optional OTLP application logs. Add the additive "otlp" token to APP_LOG_SINK# (both,otlp / stdout,otlp / file,otlp) to also export log records to the# collector configured by OTEL_EXPORTER_OTLP_ENDPOINT. It requires# OTEL_ENABLED=true, and a bare "otlp" is rejected: the bridge drops records on a# full queue, before its provider is installed and after shutdown, so it may not# be a deployment's only log destination. Exported records carry the request's# trace and span ids, so logs join to traces in Loki/Tempo/ClickHouse.# Off by default in EVERY profile, including external.# APP_LOG_SINK="both,otlp"
LOG_OTLP_MIN_LEVEL="info"# debug | info | warn | error; independent of LOG_LEVEL
LOG_OTLP_QUEUE_SIZE="10000"# records resident before drops are counted
LOG_OTLP_QUEUE_MAX_MB="64"# byte ceiling; record count alone does not bound memory
LOG_OTLP_MAX_ATTRIBUTE_VALUE_BYTES="4096"# the SDK default is unlimited# Active-file ceiling and disk-pressure guard. LOG_MAX_TOTAL_SIZE_MB can only# delete already-rotated files, so it cannot bound the file currently being# written; LOG_MAX_ACTIVE_FILE_SIZE_MB rotates on bytes and closes that hole.# The guard samples on its OWN fast cadence, not the slow retention sweep: at# 16 MB/s a 1 GB reserve lasts about 62 seconds.
LOG_MAX_ACTIVE_FILE_SIZE_MB="2048"# standalone: 4096; 0 disables
LOG_DISK_CHECK_INTERVAL_SEC="5"# independent of RETENTION_SWEEP_INTERVAL_MINUTES
LOG_EMERGENCY_MAX_BYTES_PER_SEC="1048576"# byte budget once headroom is gone
LOG_DISK_RECOVERY_MARGIN_PCT="20"# hysteresis, so the guard cannot flap# Per-request log line. The full form is the default so existing log pipelines# keep parsing the same fields.
LOG_RECORD_LINE_FORMAT="compact"# standalone: full
LOG_SAMPLE_INITIAL="100"# standalone: 0 (no sampling)
LOG_SAMPLE_THEREAFTER="100"
LOG_SAMPLE_TICK_MS="1000"# Database retention sweeps (traces, logs, async task bindings). These bound the# size of each DELETE; they do not change what gets deleted.
RETENTION_DELETE_BATCH_SIZE="5000"
RETENTION_DELETE_PAUSE_MS="10"
RETENTION_SWEEP_INTERVAL_MINUTES="60"# standalone: 1440 (historical 24h cadence)# Dashboard.
DASHBOARD_CACHE_TTL_SEC="60"# standalone: 0 (always live)
DASHBOARD_MAX_SITEWIDE_RANGE_DAYS="31"# standalone: 365 (the existing limit)
DASHBOARD_MAX_CONCURRENT_AGGREGATES="2"# standalone: 0 (unlimited). Concurrent# misses are coalesced regardless.# Keyset log pagination. Two ADDITIVE routes (/api/log/cursor and# /api/log/self/cursor); the existing offset routes are untouched.## OFF by default, and not because it is experimental: the keyset order# (created_at DESC, id DESC) has no supporting index in the shipped schema, so# on MySQL 8.4 the first page is a full table scan. Turn it on only after adding# the access paths for your engine. Measured plans:# docs/benchmarks/20260906_w24-cursor-plans.md
LOG_CURSOR_ENABLED="true"# default: false
LOG_CURSOR_TTL_SEC="1800"# how long a page token stays usable
LOG_CURSOR_MAX_RESPONSE_BYTES="4194304"# 0 disables the cap
LOG_COUNT_PROBE_MAX_ROWS="10000"# beyond this the count is a lower bound
LOG_COUNT_PROBE_TIMEOUT_MS="3000"# beyond this the count is unavailable
LOG_COUNT_CACHE_TTL_SEC="30"# 0 disables count reuse

Upgrading from an earlier release changes nothing unless you set one of these: retention, sampling, caching, the compact log line and keyset pagination are all off by default, and trace writes stay synchronous. See the compatibility contract.

Support channel's built-in tooling configuration

Configure the price and whitelist for a channel’s built‑in tools.

tooling-config

Support update user's remained quota

You can update the used quota using the API key of any token, allowing other consumption to be aggregated into the one-api for centralized management.

curl -X POST https://oneapi.laisky.com/api/token/consume \
-H "Authorization: Bearer <TOKEN_API_KEY>" \
-H "Content-Type: application/json" \
-d '{ "add_reason": "async-transcode", "add_used_quota": 150 }'

> Read More

Get request's cost

Each chat completion request will include a X-Oneapi-Request-Id in the returned headers. You can use this request id to request GET /api/cost/request/:request_id to get the cost of this request.

The returned structure is:

typeUserRequestCoststruct {
Idint`json:"id"`CreatedTimeint64`json:"created_time" gorm:"bigint"`UserIDint`json:"user_id"`RequestIDstring`json:"request_id"`Quotaint64`json:"quota"`CostUSDfloat64`json:"cost_usd" gorm:"-"`
}

Support Tracing info in logs

Support Cached Input

Now supports cached input, which can significantly reduce the cost.

Support Anthropic Prompt caching

Automatically Enable Thinking and Customize Reasoning Format via URL Parameters

Supports two URL parameters: thinking and reasoning_format.

  • thinking: Whether to enable thinking mode, disabled by default.
  • reasoning_format: Specifies the format of the returned reasoning.
    • reasoning_content: DeepSeek official API format, returned in the reasoning_content field.
    • reasoning: OpenRouter format, returned in the reasoning field.
    • thinking: Claude format, returned in the thinking field.

OpenAI Chat Completions, Response API, and Claude Messages requests also accept an extra_body object for allowlisted provider-specific passthrough fields. OneAPI flattens allowlisted keys into the upstream root payload, preserves explicit top-level request fields, and rejects malformed or non-allowlisted entries.

Reasoning Format - reasoning-content
curl --location 'https://oneapi.laisky.com/v1/chat/completions?thinking=true&reasoning_format=reasoning_content' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gpt-5-mini", "max_tokens": 1024, "messages": [ { "role": "user", "content": "1+1=?" } ] }'

Response:

{
"id": "resp_01282fbc2c1cd0a90069068d5ae43c819e93f5ca9ebacf4aaa",
"model": "gpt-5-mini",
"object": "chat.completion",
"created": 1762037082,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "2",
"reasoning_content": "**Calculating addition succinctly**\n\nI need to respond clearly. The user might be asking playfully, so I should keep it concise. The simplest answer is 1 + 1 = 2. It could be fun to mention that in binary, 1 + 1 equals 10, but that's not really necessary since the typical base is decimal. I'll stick with the straightforward response: \"2.\" Maybe I can add a brief note explaining it, like \"Adding one and one gives two,\" but I’ll keep it minimal.",
"reasoning": "**Calculating addition succinctly**\n\nI need to respond clearly. The user might be asking playfully, so I should keep it concise. The simplest answer is 1 + 1 = 2. It could be fun to mention that in binary, 1 + 1 equals 10, but that's not really necessary since the typical base is decimal. I'll stick with the straightforward response: \"2.\" Maybe I can add a brief note explaining it, like \"Adding one and one gives two,\" but I’ll keep it minimal."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 199,
"total_tokens": 209,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0,
"text_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 192,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 0,
"cached_tokens": 0
}
}
}
Reasoning Format - reasoning
curl --location 'https://oneapi.laisky.com/v1/chat/completions?thinking=true&reasoning_format=reasoning' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gpt-5-mini", "max_tokens": 1024, "messages": [ { "role": "user", "content": "1+1=?" } ] }'

Response:

{
"id": "resp_0e6222cdcfeabbbf0069068da588b88194964340c1e33fbabb",
"model": "gpt-5-mini",
"object": "chat.completion",
"created": 1762037157,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "2",
"reasoning": "**Calculating a simple equation**\n\nThe user asked what 1 + 1 equals, which is a straightforward question. I can just respond with \"2.\" Although I could add a simple explanation that 1 plus 1 equals 2, I should keep it concise. So, I’ll stick with the answer \"2\" and perhaps mention \"1 + 1 = 2\" for clarity. It's clear, and there are no concerns here, so I'll give the final response of \"2.\""
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 71,
"total_tokens": 81,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0,
"text_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 64,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 0,
"cached_tokens": 0
}
}
}
Reasoning Format - thinking
curl --location 'https://oneapi.laisky.com/v1/chat/completions?thinking=true&reasoning_format=thinking' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gpt-5-mini", "max_tokens": 1024, "messages": [ { "role": "user", "content": "1+1=?" } ] }'

Response:

{
"id": "resp_099bd53deedec1a80069068dc160d88191a1d3ff4eb82c37bb",
"model": "gpt-5-mini",
"object": "chat.completion",
"created": 1762037185,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "2",
"thinking": "**Calculating simple arithmetic**\n\nThe user asked a really straightforward question: \"1+1=?\". I should definitely keep it concise, so the answer is simply 2. I could also mention that 1+1 equals 2 in terms of adding integers. But really, just saying \"2\" should suffice. If they're curious for more detail, I can provide a brief explanation. Still, keeping it minimal, I'll just go with \"2\". That's all they need!"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 71,
"total_tokens": 81,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0,
"text_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 64,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 0,
"cached_tokens": 0
}
}
}

MCP Aggregators

Supports adding MCP servers as tool aggregators, which are then provided to downstream models as built-in tools. This enables clients to call any MCP tool with any model.

Features include MCP server addition, automatic MCP tool synchronization, billing, load balancing, automatic retries, and logging.

Additionally, one-api itself can act as an MCP server, aggregating all MCP tools via the /mcp endpoint.

Read Mode...

# MCP servers integrate the web_search and web_fetch tools, allowing any model that supports tools to invoke them
curl --location 'https://oneapi.laisky.com/v1/responses' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk-xxxxxxx' \
--data '{ "model": "openai/gpt-oss-120b", "max_output_tokens": 10000, "tools": [ { "type": "web_search" }, { "type": "web_fetch" } ], "input": "what'\''s the weather in ottawa canada?"}'

OpenAI Features

Support whisper

curl --location 'https://oneapi.laisky.com/v1/audio/transcriptions' \
--header 'Authorization: Bearer laisky-xxxxxxx' \
--form 'file=@"postman-cloud:///1efcd71f-7206-4a70-94d1-7727d79d124b"' \
--form 'model="whisper-1"' \
--form 'response_format="verbose_json"'

Response:

{
"task": "transcribe",
"language": "english",
"duration": 3.869999885559082,
"text": "Hello everyone, nice to see you today",
"segments": [
{
"id": 0,
"seek": 0,
"start": 0.0,
"end": 3.680000066757202,
"text": " Hello everyone, nice to see you today",
"tokens": [50364, 2425, 1518, 11, 1481, 281, 536, 291, 965, 50548],
"temperature": 0.0,
"avg_logprob": -0.44038617610931396,
"compression_ratio": 0.8604651093482971,
"no_speech_prob": 0.002639062935486436
}
],
"usage": {
"type": "duration",
"seconds": 4
}
}

Support openai images edits

curl --location 'https://oneapi.laisky.com/v1/images/edits' \
--header 'Authorization: sk-xxxxxxx' \
--form 'image[]=@"postman-cloud:///1f020b33-1ca1-4f10-b6d2-7b12aa70111e"' \
--form 'image[]=@"postman-cloud:///1f020b33-22c6-4350-8314-063db53618a4"' \
--form 'prompt="put all items in references image into a gift busket"' \
--form 'model="gpt-image-1"'

Response:

{
"created": 1762038453,
"data": [
{
"url": "https://xxxxxxx.png"
}
]
}

Support gpt-4o-audio

curl --location 'https://oneapi.laisky.com/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gpt-4o-audio-preview", "max_tokens": 200, "modalities": ["text", "audio"], "audio": { "voice": "alloy", "format": "pcm16" }, "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": [ { "type": "text", "text": "what is in this recording" }, { "type": "input_audio", "input_audio": { "data": "<BASE64_ENCODED_AUDIO_DATA>", "format": "mp3" } } ] } ] }'

Response:

{
"id": "chatcmpl-CXEuXGd0MagiwenLiOtDhLNMHZs63",
"object": "chat.completion",
"created": 1762038177,
"model": "gpt-4o-audio-preview-2025-06-03",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"refusal": null,
"audio": {
"id": "audio_690691a2f0248191be5a199d7a49968b",
"data": "<BASE64_ENCODED_AUDIO_DATA>",
"expires_at": 1762041778,
"transcript": "The recording contains a greeting where someone is saying, \"Hello everyone, nice to see you today.\" It sounds like a friendly and casual greeting"
},
"annotations": []
},
"finish_reason": "length"
}
],
"usage": {
"prompt_tokens": 64,
"completion_tokens": 200,
"total_tokens": 264,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 38,
"text_tokens": 26,
"image_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 159,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 41
}
},
"service_tier": "default",
"system_fingerprint": "fp_363417d4a6"
}

Support OpenAI web search models

support gpt-4o-search-preview & gpt-4o-mini-search-preview

curl --location 'https://oneapi.laisky.com/v1/chat/completions?thinking=true&reasoning_format=thinking' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gpt-4o-mini-search-preview", "max_tokens": 1024, "stream": false, "messages": [ { "role": "user", "content": "what'\''s the weather in ottawa canada?" } ] }'

Response:

{
"id": "resp_0a8e4f5c5f4e4b8f0069068d3f4bb88191f3e1e4b8f4c3faab",
"model": "gpt-4o-mini-search-preview",
"object": "chat.completion",
"created": 1762041234,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The current weather in Ottawa, Canada is partly cloudy with a temperature of 22°C (72°F). There is a light breeze coming from the northwest at 10 km/h (6 mph). Humidity is at 60%, and there is no precipitation expected today. For more detailed and up-to-date information, please check a reliable weather website or app.",
"thinking": "**Using web search to find current weather information**\n\nI searched for the latest weather updates for Ottawa, Canada. Based on the most recent data available, I found that the weather is partly cloudy with a temperature of 22°C (72°F). I also noted the wind speed and direction, humidity levels, and the absence of precipitation. This information should help the user understand the current weather conditions in Ottawa."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 15,
"completion_tokens": 150,
"total_tokens": 165,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0,
"text_tokens": 15,
"image_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 130,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 20,
"cached_tokens": 0
}
}
}

Response:

{
"id": "chatcmpl-3ba4b046-577a-4cbd-8ebc-80b48607e6ee",
"object": "chat.completion",
"created": 1762038412,
"model": "gpt-4o-mini-search-preview-2025-03-11",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "As of 6:06 PM on Saturday, November 1, 2025, in Ottawa, Canada, the weather is mostly cloudy with a temperature of 38°F (4°C).\n\n## Weather for Ottawa, ON:\nCurrent Conditions: Mostly cloudy, 38°F (4°C)\n\nDaily Forecast:\n* Saturday, November 1: Low: 35°F (1°C), High: 43°F (6°C), Description: Cloudy and breezy with a shower in spots\n* Sunday, November 2: Low: 36°F (2°C), High: 46°F (8°C), Description: Cloudy in the morning, then times of clouds and sun in the afternoon\n* Monday, November 3: Low: 36°F (2°C), High: 51°F (11°C), Description: Cloudy and breezy with showers\n* Tuesday, November 4: Low: 34°F (1°C), High: 52°F (11°C), Description: Mostly sunny and breezy\n* Wednesday, November 5: Low: 36°F (2°C), High: 44°F (7°C), Description: Cloudy with a couple of showers, mainly later\n* Thursday, November 6: Low: 29°F (-1°C), High: 44°F (7°C), Description: A little morning rain; otherwise, cloudy most of the time\n* Friday, November 7: Low: 32°F (0°C), High: 45°F (7°C), Description: Mostly cloudy\n\n\nIn November, Ottawa typically experiences cool and damp conditions, with average high temperatures around 5°C (41°F) and lows near -2°C (28°F). The city usually receives about 84 mm (3.3 inches) of precipitation over 14 days during the month. ([weather2visit.com](https://www.weather2visit.com/north-america/canada/ottawa-november.htm?utm_source=openai)) ",
"refusal": null,
"annotations": [
{
"type": "url_citation",
"url_citation": {
"end_index": 1358,
"start_index": 1247,
"title": "Ottawa Weather in November 2025 | Canada Averages | Weather-2-Visit",
"url": "https://www.weather2visit.com/north-america/canada/ottawa-november.htm?utm_source=openai"
}
}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 411,
"total_tokens": 420,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"system_fingerprint": ""
}

Support gpt-image family for image generation & edits

Support gpt-image for image generation and editing.

gpt-image-1 / gpt-image-1-mini / chatgpt-image-latest / gpt-image-1.5 / gpt-image-1.5-2025-12-16

Draw image:

curl --location 'https://oneapi.laisky.com/v1/images/generations' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gpt-image-1-mini", "prompt": "draw a goose", "n": 1, "size": "1024x1024", "response_format": "b64_json"}'

Response:

{
"created": 1763152907,
"background": "opaque",
"data": [
{
"b64_json": "iVBORw0KGgoAAAANS..."
}
],
"output_format": "png",
"quality": "high",
"size": "1536x1024",
"usage": {
"input_tokens": 437,
"input_tokens_details": {
"image_tokens": 388,
"text_tokens": 49
},
"output_tokens": 6208,
"total_tokens": 6645
}
}

Edit image:

curl --location 'https://oneapi.laisky.com/v1/images/edits' \
--header 'Authorization: sk-xxxxxxx' \
--form 'image[]=@"postman-cloud:///1f020b33-1ca1-4f10-b6d2-7b12aa70111e"' \
--form 'image[]=@"postman-cloud:///1f020b33-22c6-4350-8314-063db53618a4"' \
--form 'prompt="put all items in references image into a gift busket"' \
--form 'model="gpt-image-1-mini"'

Response:

{
"created": 1763152907,
"background": "opaque",
"data": [
{
"b64_json": "iVBORw0KGgoAAAANS..."
}
],
"output_format": "png",
"quality": "high",
"size": "1536x1024",
"usage": {
"input_tokens": 437,
"input_tokens_details": {
"image_tokens": 388,
"text_tokens": 49
},
"output_tokens": 6208,
"total_tokens": 6645
}
}

Support o3-mini & o3 & o4-mini & gpt-4.1 & o3-pro & reasoning content

Support OpenAI Response API

Also support websocket for OpenAI Response API.

curl --location 'https://oneapi.laisky.com/v1/responses' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "gemini-2.5-flash", "input": "Tell me a three sentence bedtime story about a unicorn." }'

Response:

{
"id": "resp-2025110123121283977003996295227",
"object": "response",
"created_at": 1762038734,
"status": "completed",
"model": "gemini-2.5-flash",
"output": [
{
"type": "message",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "Lily the unicorn lived in a meadow where rainbows touched the ground. Every evening, she would gallop beneath the starry sky, her horn glowing like a tiny lantern. When she finally nestled into her bed of soft moss, all the little forest creatures drifted off to sleep, feeling safe and warm."
}
]
}
],
"usage": {
"input_tokens": 12,
"output_tokens": 151,
"total_tokens": 163
},
"parallel_tool_calls": false
}

Support gpt-5 family

  • GPT-5.6 — Sol / Terra / Luna tiers (gpt-5.6 aliases to gpt-5.6-sol; adds the new max reasoning effort): gpt-5.6 / gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna
  • GPT-5.5: gpt-5.5 / gpt-5.5-pro / gpt-5.5-2026-04-23
  • GPT-5.4: gpt-5.4 / gpt-5.4-2026-03-05 / gpt-5.4-mini / gpt-5.4-nano / gpt-5.4-pro
  • GPT-5.3: gpt-5.3-codex / gpt-5.3-chat-latest (retires 2026-08-10)
  • GPT-5.2: gpt-5.2 / gpt-5.2-2025-12-11 / gpt-5.2-pro / gpt-5.2-pro-2025-12-11 / gpt-5.2-codex (retires 2026-07-23)
  • GPT-5.1: gpt-5.1 / gpt-5.1-2025-11-13 / gpt-5.1-codex / gpt-5.1-codex-mini / gpt-5.1-codex-max / gpt-5.1-chat-latest (retires 2026-07-23)
  • GPT-5: gpt-5 / gpt-5-2025-08-07 / gpt-5-mini / gpt-5-mini-2025-08-07 / gpt-5-nano / gpt-5-nano-2025-08-07 / gpt-5-pro / gpt-5-pro-2025-10-06 / gpt-5-chat-latest / gpt-5-codex (retire 2026-07-23)
  • ChatGPT alias: chat-latest — rolling alias to the latest Instant model used in ChatGPT
Realtime models
  • gpt-realtime-2.1 / gpt-realtime-2.1-mini / gpt-realtime-2 / gpt-realtime-1.5 / gpt-realtime (alias) / gpt-realtime-mini / gpt-realtime-translate / gpt-realtime-whisper
  • gpt-4o-realtime-preview / gpt-4o-realtime-preview-2025-06-03 / gpt-4o-mini-realtime-preview / gpt-4o-mini-realtime-preview-2024-12-17 (GPT-4o realtime previews retired upstream 2026-05-07)

Support o3-deep-research & o4-mini-deep-research

curl --location 'https://oneapi.laisky.com/v1/chat/completions?thinking=true&reasoning_format=thinking' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "o4-mini-deep-research", "max_tokens": 9086, "stream": false, "messages": [ { "role": "user", "content": "what'\''s the weather in ottawa canada?" } ] }'

Response:

Note

To run deep‑research successfully, you need to configure a comparatively large max_tokens value. This response was cut off due to the max_tokens limit you set.

{
"id": "resp_0457d54ec43cbbe2006906945811f081a28fce9f1839c1fa67",
"model": "o4-mini-deep-research",
"object": "chat.completion",
"created": 1762038872,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "",
"thinking": "**Finding current weather in Ottawa**\n\nThe user asked about the current weather in Ottawa, Canada, which means I need to retrieve up-to-date weather information. I can't rely on past knowledge here; I should search for current weather reports specifically for that location. It's November 1, 2025, so it's essential to consider both the time and place as I look for reliable sources, like local weather sites or official forecasts, to provide the user with accurate information.**Searching for current weather**\n\nThis looks like a weather query that requires me to retrieve the latest information. I need to remember that the instructions emphasize using searches for up-to-date data and not relying solely on past knowledge. Since the guidelines don't prohibit weather queries, I should feel safe in proceeding. I’ll look up the current weather for Ottawa, Canada, using a browser search to ensure I provide accurate and timely information for the user."
},
"finish_reason": "length"
}
],
"usage": {
"prompt_tokens": 31134,
"completion_tokens": 2608,
"total_tokens": 33742,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0,
"text_tokens": 0,
"image_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 2624,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 0,
"cached_tokens": 0
}
}
}

Support Codex Cli

# vi $HOME/.codex/config.toml
model = "gemini-2.5-flash"
model_provider = "laisky"
[model_providers.laisky]
# Name of the provider that will be displayed in the Codex UI.
name = "Laisky"# The path `/chat/completions` will be amended to this URL to make the POST# request for the chat completions.
base_url = "https://oneapi.laisky.com/v1"# If `env_key` is set, identifies an environment variable that must be set when# using Codex with this provider. The value of the environment variable must be# non-empty and will be used in the `Bearer TOKEN` HTTP header for the POST request.
env_key = "sk-xxxxxxx"# Valid values for wire_api are "chat" and "responses". Defaults to "chat" if omitted.
wire_api = "responses"# If necessary, extra query params that need to be added to the URL.# See the Azure example below.
query_params = {}

Support Sora

https://platform.openai.com/docs/guides/video-generation

Create Video Task:

curl --location 'https://oneapi.laisky.com/v1/videos' \
--header 'Authorization: sk-xxxxxxx' \
--form 'prompt="aurora"' \
--form 'model="sora-2"' \
--form 'seconds="4"' \
--form 'size="1280x720"'

Response:

{
"id": "video_691608967fe8819399e710799dae2ae708872b008b63ff61",
"object": "video",
"created_at": 1763051670,
"status": "queued",
"completed_at": null,
"error": null,
"expires_at": null,
"model": "sora-2",
"progress": 0,
"prompt": "aurora",
"remixed_from_video_id": null,
"seconds": "4",
"size": "1280x720"
}

Get Video Task Status:

curl --location 'https://oneapi.laisky.com/v1/videos/video_691608967fe8819399e710799dae2ae708872b008b63ff61'
--header 'Authorization: sk-xxxxxxx'

Response:

{
"id": "video_691611812ca88190bfb123716dcc953a089a232f54b02b21",
"object": "video",
"created_at": 1763053953,
"status": "completed",
"completed_at": 1763054021,
"error": null,
"expires_at": 1763057621,
"model": "sora-2",
"progress": 100,
"prompt": "aurora",
"remixed_from_video_id": null,
"seconds": "4",
"size": "1280x720"
}

Download Video:

curl --location 'https://oneapi.laisky.com/v1/videos/video_691611812ca88190bfb123716dcc953a089a232f54b02b21/content'
--header 'Authorization: sk-xxxxxxx'

Deprecated Models

Anthropic (Claude) Features

(Merged) Support aws claude

Support claude-3-7-sonnet & thinking

By default, the thinking mode is not enabled. You need to manually pass the thinking field in the request body to enable it.

Stream

Non-Stream

Support /v1/messages Claude Messages API

Support Claude Code
export ANTHROPIC_MODEL="openai/gpt-oss-120b"export ANTHROPIC_BASE_URL="https://oneapi.laisky.com/"export ANTHROPIC_AUTH_TOKEN="sk-xxxxxxx"

You can use any model you like for Claude Code, even if the model doesn’t natively support the Claude Messages API.

Support Azure AI Foundry Claude models

Azure AI Foundry serves Anthropic Claude through the native Anthropic Messages API — there is no OpenAI-compatible route for Claude on Foundry. one-api's existing Azure channel handles this automatically: on an Azure channel, claude-* models are routed to the resource's /anthropic/v1/messages surface (with the x-api-key and anthropic-version headers and Anthropic pricing), while gpt-* deployments continue to use the Azure OpenAI surface. No separate channel type is required.

To use it:

  1. Create an Azure channel and set the base URL to your resource endpoint, e.g. https://<resource>.services.ai.azure.com (no /anthropic or /openai suffix — one-api appends the correct path per model).
  2. Use the Azure resource key as the channel key (forwarded as x-api-key).
  3. Add the Claude models you deployed (e.g. claude-sonnet-5, claude-opus-4-8). Naming your Azure deployment to match the one-api model id lets both routing and default Anthropic pricing resolve automatically. If the deployment name differs, add a model mapping (claude-* → your-deployment); routing still works because it keys off the requested model, but you should then set a per-channel price for the deployment name so billing stays correct.

Support Claude 4.x Models

claude-opus-4-0 (retired 2026-06-15) / claude-opus-4-1 (retires 2026-08-05) / claude-opus-4-5 / claude-opus-4-6 / claude-opus-4-7 / claude-opus-4-8 / claude-opus-5 / claude-sonnet-4-0 (retired 2026-06-15) / claude-sonnet-4-5 / claude-sonnet-4-6 / claude-sonnet-5 / claude-haiku-4-5

Google (Gemini & Vertex) Features

Support gemini multimodal output #2197

Support gemini-2.5-pro

Support GCP Vertex gloabl region and gemini-2.5-pro-preview-06-05

Support gemini-2.5-flash-image-preview & imagen-4 series

Support gemini-3 family

Support gemini-3.1-pro-preview / gemini-3.1-pro-preview-customtools / gemini-3-pro-preview (retired 2026-03-09) / gemini-3-pro-image-preview (retired 2026-06-25) / gemini-3-flash-preview / gemini-3.1-flash-image-preview (retired 2026-06-25) / gemini-3.1-flash-lite-preview (retired 2026-05-25)

Deprecated Models

OpenCode Support

OpenCode logo

opencode.ai is an AI coding agent built for the terminal. OpenCode is fully open source, giving you control and freedom to use any provider, any model, and any editor. It's available as both a CLI and TUI.

One‑API integrates seamlessly with OpenCode: you can connect any One‑API endpoint and use all your unified models through OpenCode's interface (both CLI and TUI).

To get started, create or edit ~/.config/opencode/opencode.json like this:

Using OpenAI SDK:

{
"$schema": "https://opencode.ai/config.json",
"provider": {
"one-api": {
"npm": "@ai-sdk/openai",
"name": "One API",
"options": {
"baseURL": "https://oneapi.laisky.com/v1",
"apiKey": "<ONEAPI_TOKEN_KEY>"
},
"models": {
"gpt-4.1-2025-04-14": {
"name": "GPT 4.1"
}
}
}
}
}

Using Anthropic SDK:

{
"$schema": "https://opencode.ai/config.json",
"provider": {
"one-api-anthropic": {
"npm": "@ai-sdk/anthropic",
"name": "One API (Anthropic)",
"options": {
"baseURL": "https://oneapi.laisky.com/v1",
"apiKey": "<ONEAPI_TOKEN_KEY>"
},
"models": {
"claude-sonnet-4-5": {
"name": "Claude Sonnet 4.5"
}
}
}
}
}

AWS Features

Support AWS cross-region inferences

Support AWS BedRock Inference Profile

Replicate Features

Support replicate flux & remix

Support replicate chat models

DeepSeek Features

Support deepseek-reasoner

DeepSeek V4

Support deepseek-v4-flash / deepseek-v4-pro

OpenRouter Features

Support OpenRouter's reasoning content

By default, the thinking mode is automatically enabled for the deepseek-r1 model, and the response is returned in the open-router format.

Cohere

Support Cohere Command R & Rerank

curl --location 'https://oneapi.laisky.com/v1/rerank' \
--header 'Content-Type: application/json' \
--header 'Authorization: sk-xxxxxxx' \
--data '{ "model": "rerank-v3.5", "query": "What is the capital of the United States?", "top_n": 3, "documents": [ "Carson City is the capital city of the American state of Nevada.", "The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean. Its capital is Saipan.", "Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.", "Capitalization or capitalisation in English grammar is the use of a capital letter at the start of a word. English usage varies from capitalization in other languages.", "Capital punishment has existed in the United States since beforethe United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states." ] }'

Response:

{
"object": "cohere.rerank",
"model": "rerank-v3.5",
"id": "ff9458ce-318b-4317-ad49-f8654c976dff",
"results": [
{
"index": 2,
"relevance_score": 0.8742601
},
{
"index": 0,
"relevance_score": 0.17292508
},
{
"index": 4,
"relevance_score": 0.10793502
}
],
"meta": {
"api_version": {
"version": "2",
"is_experimental": false
},
"billed_units": {
"search_units": 1
}
},
"usage": {
"prompt_tokens": 153,
"total_tokens": 153
}
}

Coze Features

Support coze oauth authentication

Moonshot Features

Support Kimi Family

Current flagship (1M context, text + image + video input):

  • kimi-k3 — always-on thinking, depth selected by reasoning_effort (low / high / max, default max)

K3 pins temperature, top_p, n, presence_penalty and frequency_penalty upstream and rejects other values, so the Moonshot adaptor drops those fields for this model and maps the OpenAI effort ladder onto K3's three tiers (minimal/nonelow, mediumhigh, xhighmax).

K2 generation (text + image + video, 256k context, open weights on HuggingFace):

  • kimi-k2.7-code — top coding model, thinking-only deep reasoning
  • kimi-k2.7-code-highspeed — high-throughput variant, priced at 2x standard
  • kimi-k2.6 — multimodal, thinking and non-thinking modes
  • kimi-k2.5 — multimodal, thinking and non-thinking modes

Classic Moonshot V1 chat models (text, plus vision-preview variants):

  • moonshot-v1-8k / moonshot-v1-32k / moonshot-v1-128k
  • moonshot-v1-8k-vision-preview / moonshot-v1-32k-vision-preview / moonshot-v1-128k-vision-preview

kimi-k2.5 and the whole moonshot-v1 series stopped accepting newly registered Moonshot accounts when K3 launched, and go fully offline on 2026-08-31.

The legacy kimi-k2-0905-preview, kimi-k2-0711-preview, kimi-k2-turbo-preview, kimi-k2-thinking and kimi-k2-thinking-turbo models were discontinued by Moonshot on 2026-05-25.

Kimi K3 is also available through several hosted providers, each with its own case-sensitive model id: moonshotai/kimi-k3 (OpenRouter, Novita), moonshotai/Kimi-K3 (SiliconFlow) and kimi/kimi-k3 (Alibaba Bailian, billed in CNY with cache hits at 10% of input).

GLM Features

Flagship Models - Text

glm-5.3 / glm-5.2 / glm-5.1 / glm-5-turbo / glm-5 / glm-4.7 / glm-4.7-flashx / glm-4.7-flash / glm-4.6 / glm-4.5 / glm-4.5-x / glm-4.5-air / glm-4.5-airx

Flagship Models - Visual

autoglm-phone / glm-5.3-flash / glm-5v-turbo / glm-4.6v / glm-4.6v-flashx / glm-4.5v / glm-4.6v-flash / glm-4v-flash

Language Models

glm-4-plus / glm-4-air / glm-4-airx / glm-4-flashx-250414 / glm-4-long / glm-4-assistant / glm-4-flash-250414 / glm-4.5-flash / glm-4-flash

Reasoning Models

glm-z1-air / glm-z1-airx / glm-z1-flashx / glm-4.1v-thinking-flashx / glm-4.1v-thinking-flash

Multimodal Models

glm-4v-plus-0111 / glm-4v-plus / glm-4v / glm-4-voice

Image Generation Models

glm-image / cogview-4 / cogview-3-plus / cogview-3 / cogview-3-flash / cogvideox-3 / cogvideox-2 / cogviewx / cogviewx-flash / viduq1-image / viduq1-start-end / viduq1-text / vidu2-image / vidu2-start-end / vidu2-reference

Audio Models

glm-tts / glm-asr-2512 / glm-tts-clone

Voice cloning is exposed through /v1/voice/clones (Zhipu-compatible /api/paas/v4/voice/clone is also accepted).

Realtime Models

glm-realtime-flash / glm-realtime-air

Other Models

charglm-4 / emohaa / codegeex-4 / rerank / embedding-3 / embedding-2 / glm-3-turbo / glm-zero-preview

GLM OCR

curl --location 'https://oneapi.laisky.com/api/paas/v4/layout_parsing' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{ "model": "glm-ocr", "file": "https://s3.laisky.com/uploads/2026/04/IMG_5867.jpeg"}'

Response:

{
"created": 1775094925,
"data_info": {
"num_pages": 1,
"pages": [
{
"height": 4032,
"width": 3024
}
]
},
"id": "202604020955171fc1a13d434945b8",
"layout_details": [
[
{
"bbox_2d": [1348, 297, 2104, 502],
"content": "## metro",
"height": 4032,
"index": 0,
"label": "text",
"native_label": "paragraph_title",
"width": 3024
},
{
"bbox_2d": [877, 587, 2171, 695],
"content": "Store #100256(613)823-8825",
"height": 4032,
"index": 1,
"label": "text",
"native_label": "text",
"width": 3024
},
{
"bbox_2d": [877, 680, 2102, 785],
"content": "E&OE HST# R105216170",
"height": 4032,
"index": 2,
"label": "text",
"native_label": "text",
"width": 3024
},
{
"bbox_2d": [524, 820, 2564, 3724],
"content": "<table><thead><tr><th>MEAT</th><th></th><th></th></tr></thead><tbody><tr><td>LSM.PORK SHLD BL</td><td></td><td>4.31</td></tr><tr><td>THE KEG BBQ BACK</td><td></td><td>17.99</td></tr><tr><td>Saving 3.00</td><td></td><td></td></tr><tr><td>PRODUCE</td><td></td><td></td></tr><tr><td>TOFU MEDIUM-FIRM</td><td></td><td>2.99</td></tr><tr><td>PREMIUM BANANA</td><td>0.685 kg @ $1.74/kg</td><td>1.19</td></tr><tr><td>GINGER</td><td>0.235 kg @ $6.59/kg</td><td>1.55</td></tr><tr><td>PEP.GRN LG HOT</td><td>0.340 kg @ $11.00/kg</td><td>3.74</td></tr><tr><td>(2)GARLIC</td><td>2 @ $1.99</td><td>3.98</td></tr><tr><td>SEAFOOD</td><td></td><td>7.99</td></tr><tr><td>BW BREADED FISH</td><td></td><td>7.99</td></tr><tr><td>Saving 3.00</td><td></td><td></td></tr><tr><td>SUBTOTAL</td><td></td><td>43.74</td></tr><tr><td>TOTAL</td><td></td><td>43.74</td></tr><tr><td>CREDIT CR</td><td></td><td>43.74</td></tr><tr><td>Total number of items sold</td><td></td><td>9</td></tr></tbody></table>",
"height": 4032,
"index": 3,
"label": "table",
"native_label": "table",
"width": 3024
},
{
"bbox_2d": [581, 3593, 2462, 3886],
"content": "RETAIN RECEIPT FOR PRODUCT RETURN WITHIN 14 DAYS. SEE STORE FOR DETAILS",
"height": 4032,
"index": 4,
"label": "text",
"native_label": "text",
"width": 3024
},
{
"bbox_2d": [612, 3892, 2464, 4030],
"content": "CUSTOMER CARE NUMBER 1-866-595-5554",
"height": 4032,
"index": 5,
"label": "text",
"native_label": "text",
"width": 3024
}
]
],
"layout_visualization": [],
"md_results": "## metro\n\nStore #100256(613)823-8825\n\nE&OE HST# R105216170\n\n<table><thead><tr><th>MEAT</th><th></th><th></th></tr></thead><tbody><tr><td>LSM.PORK SHLD BL</td><td></td><td>4.31</td></tr><tr><td>THE KEG BBQ BACK</td><td></td><td>17.99</td></tr><tr><td>Saving 3.00</td><td></td><td></td></tr><tr><td>PRODUCE</td><td></td><td></td></tr><tr><td>TOFU MEDIUM-FIRM</td><td></td><td>2.99</td></tr><tr><td>PREMIUM BANANA</td><td>0.685 kg @ $1.74/kg</td><td>1.19</td></tr><tr><td>GINGER</td><td>0.235 kg @ $6.59/kg</td><td>1.55</td></tr><tr><td>PEP.GRN LG HOT</td><td>0.340 kg @ $11.00/kg</td><td>3.74</td></tr><tr><td>(2)GARLIC</td><td>2 @ $1.99</td><td>3.98</td></tr><tr><td>SEAFOOD</td><td></td><td>7.99</td></tr><tr><td>BW BREADED FISH</td><td></td><td>7.99</td></tr><tr><td>Saving 3.00</td><td></td><td></td></tr><tr><td>SUBTOTAL</td><td></td><td>43.74</td></tr><tr><td>TOTAL</td><td></td><td>43.74</td></tr><tr><td>CREDIT CR</td><td></td><td>43.74</td></tr><tr><td>Total number of items sold</td><td></td><td>9</td></tr></tbody></table>\n\nRETAIN RECEIPT FOR PRODUCT RETURN WITHIN 14 DAYS. SEE STORE FOR DETAILS\n\nCUSTOMER CARE NUMBER 1-866-595-5554",
"model": "glm-ocr",
"request_id": "202604020955171fc1a13d434945b8",
"usage": {
"completion_tokens": 604,
"prompt_tokens": 7666,
"total_tokens": 8270
}
}

Z.ai Features

Z.ai (https://api.z.ai) and Zhipu / open.bigmodel.cn are two brands of the same company serving the same GLM wire protocol, so one-api exposes them as two separate channel types: Zhipu (16) and Z.ai (58). Each holds its own API key and its own model list, and each bills from its own price table. Requests to glm-4.7 on a Zhipu channel bill at BigModel's CNY tiers; the same model on a Z.ai channel bills at Z.ai's flat USD rate.

Z.ai vs Zhipu / open.bigmodel.cn

Zhipu (16)Z.ai (58)
Base URLhttps://open.bigmodel.cnhttps://api.z.ai
AuthHS256-signed JWT built from a dotted {id}.{secret} keyplain Authorization: Bearer <key>
PricingCNY, tiered by input and output lengthUSD, flat (no tiers)
Endpointschat, embeddings, images, response API, Claude Messages, OCRchat, images, videos, audio transcription, response API, Claude Messages, OCR
Not availableembeddings, rerank, text-to-speech, realtime

Because the two catalogs overlap almost entirely, a model id served by both is attributed to a single channel in the listings.

/v1/models is derived entirely from the channels enabled on this deployment, scoped to the caller's group and then narrowed to the API key's own model allow-list — it never consults the compiled-in adaptor catalog. Every model it lists passes the same allow-list check the relay applies before serving a request, so a key is no longer shown models it would be refused. (The converse does not hold: models hidden on a channel are deliberately omitted from the listing while remaining callable.) Every row is rendered from the ability that makes the model routable, so each id is callable by construction, and owned_by names the channel that would serve it: the highest-priority channel offering that model, with the lowest channel id breaking ties. A deployment running only a Zhipu channel therefore reports zhipu and never zai, and with no channels configured the list is empty.

The admin catalog at /api/channel/models ranks enabled channels the same way but does fall back to the compiled-in adaptor list for models no channel serves yet — that list is what lets you pick models while creating your first channel.

owned_by is a display label in every case: billing always follows the channel the request was actually routed to, so the same glm-4.7 call bills at CNY tiers on a Zhipu channel and at flat USD on a Z.ai channel.

Z.ai's GLM Coding Plan uses different base URLs (/api/anthropic, /api/coding/paas/v4) and is not served by this channel; point a ClaudeCompatible channel at https://api.z.ai/api/anthropic for that instead.

Z.ai Model Catalog

Text: glm-5.3 / glm-5.2 / glm-5.1 / glm-5 / glm-5-turbo / glm-4.7 / glm-4.7-flashx / glm-4.7-flash / glm-4.6 / glm-4.5 / glm-4.5-x / glm-4.5-air / glm-4.5-airx / glm-4.5-flash / glm-4-32b-0414-128k

Vision: glm-5.3-flash / glm-5v-turbo / glm-4.6v / glm-4.6v-flashx / glm-4.6v-flash / glm-4.5v

OCR, image, video, audio: glm-ocr / glm-image / cogview-4-250304 / cogvideox-3 / viduq1-text / viduq1-image / viduq1-start-end / vidu2-image / vidu2-start-end / vidu2-reference / glm-asr-2512

glm-4.7-flash, glm-4.5-flash and glm-4.6v-flash are free on Z.ai. glm-4-32b-0414-128k and cogview-4-250304 exist only on Z.ai; conversely embedding-3, rerank, glm-tts and glm-realtime-* exist only on Zhipu. Pricing source: https://docs.z.ai/guides/overview/pricing.

XAI / Grok Features

Support XAI/Grok Text & Image Models

The XAI adaptor tracks the current Grok 4.6 flagship, Grok 4.5/4.3 and Grok 4.20 snapshots, Grok Build 0.1, legacy redirect aliases, and the current Grok Imagine image/video model slugs. Pricing is sourced from the official xAI pricing table, including the published long-context surcharge at 200K input tokens.

Black Forest Labs Features

Support black-forest-labs/flux-kontext-pro

NVIDIA Features

Support NVIDIA API Catalog (build.nvidia.com)

Adds an NVIDIA channel type that targets NVIDIA's OpenAI-compatible hosted inference API at https://integrate.api.nvidia.com/v1 (the models published on build.nvidia.com). Authenticate with an nvapi-... API key. The channel serves Chat Completions natively, and transparently handles Claude Messages / Response API requests through one-api's OpenAI-compatible conversion layer. Embeddings are not enabled by default until NVIDIA's model-specific request requirements are represented in the catalog.

Curated models include NVIDIA's own Nemotron family (e.g. nvidia/nemotron-3-ultra-550b-a55b, nvidia/llama-3.3-nemotron-super-49b-v1.5, nvidia/nemotron-nano-12b-v2-vl) plus popular hosted open models such as meta/llama-3.3-70b-instruct, deepseek-ai/deepseek-v4-flash, qwen/qwen3-next-80b-a3b-instruct, openai/gpt-oss-120b, and moonshotai/kimi-k2.6.

NVIDIA does not publish per-token pricing for the hosted endpoint (it is metered in free API credits rather than currency), so every bundled model defaults to free. Operators routing to NVIDIA AI Enterprise or a paid partner endpoint with real costs can set per-channel pricing overrides.

Cerebras Features

Support Cerebras Inference (api.cerebras.ai)

Adds a Cerebras channel type that targets Cerebras Inference, the OpenAI-compatible API served on Cerebras' wafer-scale (CS-3) hardware at https://api.cerebras.ai/v1. Authenticate with a Cerebras API key (Authorization: Bearer ...). The channel serves Chat Completions natively, and transparently handles Claude Messages / Response API requests through one-api's OpenAI-compatible conversion layer. Cerebras is chat-only — it does not expose embeddings or a native Anthropic Messages endpoint.

Bundled models (live on the shared public API with officially published per-token pricing):

  • gpt-oss-120b — OpenAI gpt-oss 120B open-weight MoE reasoning model (Production / GA); 131K context, tools and structured outputs, reasoning_effort supported. Billed at $0.35 / 1M input and $0.75 / 1M output tokens.
  • zai-glm-4.7 — Z.ai GLM-4.7 (355B) reasoning/agent model; 131K context. Marked Preview by Cerebras (evaluation only, may change on short notice). Billed at $2.25 / 1M input and $2.75 / 1M output tokens.
  • gemma-4-31b — Google Gemma 4 31B multimodal (text + image input) reasoning model; 131K context (paid tier), reasoning disabled by default (opt-in via reasoning_effort). Marked Preview by Cerebras. Billed at $0.99 / 1M input and $1.49 / 1M output tokens.

Per-token rates above are taken from the official Cerebras model cards; operators can override pricing per channel.

Bug Fixes & Enterprise-Grade Improvements (Including Security Enhancements)

Note

For additional enterprise-grade improvements, including security enhancements (e.g., vulnerability fixes), you can also view these pull requests here.

About

OpenRouter’s open‑source alternative. Multi-model/Multi-API-format/Multi-tenant LLM API aggregation platform.

Topics

Resources

Stars

295 stars

Watchers

3 watching

Forks

Sponsor this project

Used by

Contributors

Languages