AISIX 0.13.0
This release is about telling traffic apart and reaching an upstream on its own terms.
Release date: September 1, 2026
This release is about telling traffic apart and reaching an upstream on its own terms. A Provider Key can now declare which API surfaces its endpoint serves natively and where each one lives, so one credential reaches both the OpenAI-compatible path and the Anthropic-compatible path an upstream serves, without a second key or a second model. Every usage record now names the work that was asked for, so an image generation and a video submission are no longer the same undifferentiated OpenAI stream in an exporter or in Logs. A caller the gateway rate-limits gets a response that says what the cap was and when to come back. And a response now reports the gateway model name the caller addressed on every endpoint that serves one, rather than the provider's own id on some of them.
Behavior Changes
-
Existing DeepSeek provider keys reach DeepSeek's own routes after the upgrade, instead of being translated. AISIX now carries a verified declaration of the API surfaces DeepSeek serves — its native
/v1/responsesand its Anthropic-compatible/anthropic/v1/messages— and applies it once, at upgrade, to provider keys that have no declaration of their own, use thedeepseekprovider, and still point athttps://api.deepseek.com. Those keys reportapis_source: catalog. What changes for traffic: a Responses API request is forwarded to DeepSeek's own/v1/responsesrather than translated to chat completions, so reasoning output items survive; and an Anthropic-wire request reaches the Anthropic-compatible path, so prompt-cache breakpoints and thinking blocks survive. A key you declared yourself is left untouched. -
A client reading the
modelfield off a response now sees the gateway model name it asked for, on/v1/messages,/v1/responses,/v1/completionsand/v1/embeddings— streamed and buffered alike — and on/v1/videospolls. These paths previously returned the provider's own id, so a model aliasedgpt4o-minicame back asgpt-4o-mini-2024-07-18, while/v1/chat/completionsalready returned the alias. Passthrough routes are unchanged and still relay the provider's response as-is. -
A gateway rate-limit rejection now carries response headers. A 429 the gateway itself produces describes the single limit that refused it:
x-ratelimit-limit,x-ratelimit-remaining,x-ratelimit-reset,x-ratelimit-scopeandRetry-After.x-ratelimit-resetandRetry-Afterare both a delta in seconds. A concurrency rejection now carries a retry hint where it previously carried none. These headers are added only when the gateway refuses the request; a 429 relayed from an upstream is passed through as the upstream sent it. The per-dimensionx-ratelimit-limit-requests/-tokens/-concurrentheaders on successful responses are unchanged. -
A Prometheus gauge whose key no longer exists stops reporting its last value.
aisix_budget_limit_usd/_spent_usd/_remaining_usd/_reset_seconds/_details_presentandaisix_ratelimit_remaining_{requests,tokens}are written only from the request path, so deleting an API key used to freeze its series at whatever it last read — and an alert on budget exhaustion kept firing for a credential that no longer exists. Such a series is now retired toNaN, which Prometheus treats as no value rather than as zero. An alert that compares these gauges no longer matches a deleted key. If you built a dashboard panel that reads a raw value, expect a gap rather than a flat line after a key is deleted.
New Features
-
Native API surfaces on a Provider Key. One upstream account often exposes more than one protocol, on different paths of the same host, under one credential — DeepSeek, Zhipu and Kimi each front an OpenAI-compatible path and an Anthropic-compatible one.
api_basecan name only one of them, so everything else was translated, losing what the target protocol carries and the canonical chat shape does not. A Provider Key now takes anapisblock naming each surface and, optionally, the base URL it lives at:{ "apis": { "responses": {}, "messages": { "base": "https://api.deepseek.com/anthropic" } } }The two surfaces resolve on different terms, because the evidence for them differs.
messagesis additive: a key whose adapter is alreadyanthropickeeps serving/v1/messagesnatively whatever the map says, and listing it here adds the route to a key whose adapter is something else.responsesis authoritative: once the block exists,/v1/responsesis served natively only if it is listed — which is how an operator says "this endpoint has no Responses route" and gets the request translated to chat completions instead of 404'd upstream. With no block at all, both fall back to what the gateway inferred before:/v1/messagesfrom the vendor id or theanthropicadapter,/v1/responsesfrom the vendor id alone. Surfaces the block has no key for — embeddings, audio, images, videos, files, batches, fine-tuning, rerank — always useapi_base, exactly as before. Set the block to{}to declare that the endpoint serves nothing beyond its adapter's own surface, or tonullto clear the declaration. Configurable in the console on the Provider Keys page, and over the Cloud Admin API onPOSTandPATCH /provider_keys. -
Usage records name the operation that was asked for. Every usage event now carries
operation— the kind of work a request asked for, chosen by the route it matched and never by caller text:chat,completions,messages,count_tokens,responses,embeddings,rerank,realtime,image_generation,image_edit,transcription,translation,speech,video_generation,files,batches,batch_completion,fine_tuning,mcp,a2aandpassthrough.inbound_protocolreportsopenaifor every OpenAI-shaped route, so nothing could previously separate a text chat from an image generation or a video submission short of a regular expression over a captured prompt — which ametadata_onlyexporter has no prompt for, and which a zero-token video submission does not answer at all. The field reaches your own exporters (OTLP, Datadog, SLS) and the console: Logs filters on the operation and marks each request with it — the conversational endpoints (chat,messages,responses,completions) are left unmarked as the common case — andGET /usage_eventsandGET /usage_events/exporttake anoperationquery parameter and return the field on each item.
Improvements
- Usage-event and budget metrics name the member, not just their id.
aisix_usage_events_emitted_total,aisix_usage_event_drops_totaland the fiveaisix_budget_*gauges now carryuser_namebesideuser_id, matchingaisix_proxy_requests_totaland theaisix_llm_*families. A usage-event alert or a budget dashboard can name the person it is about without a lookup outside Prometheus.
Fixes
aisix_budget_remaining_usdis now published. The gateway could only emit this gauge when the control plane stated the remaining amount in its budget decision, and the decision never carried it — so a series the metric reference documents existed in no 0.12.0 or earlier deployment, and a dashboard panel or alert built on it matched nothing. It now appears alongsideaisix_budget_limit_usdandaisix_budget_spent_usd, on the same labels and at the same moments. Upgrading the control plane is enough; no gateway change and no configuration.- The sign-in error for a rejected origin no longer misstates what the server
trusts, or points you at the wrong component to restart. It said the server
trusts only the one address it is configured to serve on; it also trusts that
address's
localhost/127.0.0.1twin and every origin inAISIX_TRUSTED_ORIGINS, and the message now offers that second remedy. It also told the operator to restart cp-api, where the check that rejected them runs in the dashboard. - The Helm chart's post-install notes no longer name an address the port-forward they tell you to run does not serve, and carried the same overstated claim about trusted origins.
API Changes
No breaking changes. All additions are optional.
| Endpoint | Change |
|---|---|
| New optional request property apis. The 201 response may now carry warnings when a data plane in scope runs a gateway too old to execute a declared surface. |
| New optional request property apis; null clears the declaration, {} declares that the endpoint serves nothing beyond its adapter's surface. Response adds apis, apis_source and warnings. |
| Response adds apis, apis_source (catalog or operator) and warnings. |
| New optional operation query parameter; each item gains operation. |
| New optional operation query parameter; each exported item gains operation. |
Note that apis is not echoed by the create response, the same as api_base —
read it back with GET /provider_keys/{provider_key_id}, whose apis_source
reports catalog when AISIX supplied the declaration rather than you.
Upgrade Notes
These notes apply when you upgrade from any release earlier than 0.13.0, including an upgrade that passes over it on the way to a later release.
- The control plane applies the curated API-surface declaration once, on the first
boot after the upgrade, to the provider keys described under Behavior Changes.
It is best-effort and idempotent: a boot that cannot complete it retries on the
next one, and a key that already carries a declaration is never touched. Set
apisyourself on any key whose endpoint you do not want reached natively. - If you alert on
aisix_budget_*oraisix_ratelimit_remaining_*, review the expressions against the gauge-retirement change above before upgrading. - A gateway still running a release before 0.13.0 records no
operation, because the gateway is what derives the value from the matched route. While such a gateway is in the fleet, filtering by operation — in Logs, onGET /usage_events, or on an export — excludes its traffic from the results. Its requests are proxied and recorded as before; only the operation filter cannot see them. Upgrading the gateway resolves it for traffic from that point on; rows already recorded without an operation stay outside the filter.