diff --git a/app/modules/api_keys/schemas.py b/app/modules/api_keys/schemas.py
index 6947c3dfc0..10aa0dfe10 100644
--- a/app/modules/api_keys/schemas.py
+++ b/app/modules/api_keys/schemas.py
@@ -33,7 +33,7 @@ class ApiKeyCreateRequest(DashboardModel):
default=None, pattern=r"(?i)^(none|minimal|low|medium|high|xhigh|max|ultra)$"
)
allowed_reasoning_efforts: list[str] | None = None
- enforced_service_tier: str | None = Field(default=None, pattern=r"(?i)^(auto|default|priority|flex|fast)$")
+ enforced_service_tier: str | None = Field(default=None, pattern=r"(?i)^(auto|default|priority|flex|(ultra)?fast)$")
traffic_class: str | None = Field(default=None, pattern=r"(?i)^(foreground|opportunistic)$")
transport_policy_override: str | None = None
usage_sections: str | None = None
@@ -53,7 +53,7 @@ class ApiKeyUpdateRequest(DashboardModel):
default=None, pattern=r"(?i)^(none|minimal|low|medium|high|xhigh|max|ultra)$"
)
allowed_reasoning_efforts: list[str] | None = None
- enforced_service_tier: str | None = Field(default=None, pattern=r"(?i)^(auto|default|priority|flex|fast)$")
+ enforced_service_tier: str | None = Field(default=None, pattern=r"(?i)^(auto|default|priority|flex|(ultra)?fast)$")
traffic_class: str | None = Field(default=None, pattern=r"(?i)^(foreground|opportunistic)$")
transport_policy_override: str | None = None
usage_sections: str | None = None
diff --git a/app/modules/api_keys/service.py b/app/modules/api_keys/service.py
index b6e3ca8f1a..a68bce8db0 100644
--- a/app/modules/api_keys/service.py
+++ b/app/modules/api_keys/service.py
@@ -1461,7 +1461,7 @@ def _normalize_model_slug(value: str | None) -> str | None:
_REASONING_EFFORT_ORDER = ("minimal", "low", "medium", "high", "xhigh", "max", "ultra")
_SUPPORTED_REASONING_EFFORTS = frozenset({"none", *_REASONING_EFFORT_ORDER})
_SUPPORTED_SELECTABLE_REASONING_EFFORTS = frozenset(_REASONING_EFFORT_ORDER)
-_SUPPORTED_SERVICE_TIERS = frozenset({"auto", "default", "priority", "flex"})
+_SUPPORTED_SERVICE_TIERS = frozenset({"auto", "default", "priority", "flex", "ultrafast"})
def _normalize_expires_at(value: datetime | None) -> datetime | None:
diff --git a/docs/screenshots/api-key-ultrafast-after.jpg b/docs/screenshots/api-key-ultrafast-after.jpg
new file mode 100644
index 0000000000..e9c89139dc
Binary files /dev/null and b/docs/screenshots/api-key-ultrafast-after.jpg differ
diff --git a/docs/screenshots/api-key-ultrafast-before.jpg b/docs/screenshots/api-key-ultrafast-before.jpg
new file mode 100644
index 0000000000..54ecb306f2
Binary files /dev/null and b/docs/screenshots/api-key-ultrafast-before.jpg differ
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 80121d75ae..bec37fc76d 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -11,9 +11,9 @@ codex-lb refreshes usage on its own schedule and treats upstream samples conserv
**Codex CLI falls back to POST instead of WebSockets.**
Run the [WebSocket verification steps](client-setup.md#verify-websocket-transport). If codex-lb sits behind a reverse proxy, make sure it forwards WebSocket upgrades — see [Remote Access](deployment/remote.md).
-## Fast Mode and service tiers
+## Fast Mode, Ultrafast, and service tiers
-Fast Mode and service-tier behavior is documented in the
+Fast Mode, Ultrafast, and service-tier behavior is documented in the
[Responses API compatibility context](https://github.com/Soju06/codex-lb/blob/main/openspec/specs/responses-api-compat/context.md#fast-mode-and-service-tiers).
## Old Codex sessions missing after migrating
diff --git a/frontend/src/features/api-keys/components/api-key-create-dialog.test.tsx b/frontend/src/features/api-keys/components/api-key-create-dialog.test.tsx
index af78496569..8a056a2d21 100644
--- a/frontend/src/features/api-keys/components/api-key-create-dialog.test.tsx
+++ b/frontend/src/features/api-keys/components/api-key-create-dialog.test.tsx
@@ -81,6 +81,31 @@ describe("ApiKeyCreateDialog", () => {
expect(onSubmit.mock.calls[0][0].trafficClass).toBe("opportunistic");
});
+ it("submits Ultrafast service tier", async () => {
+ const user = userEvent.setup();
+ const onSubmit = vi.fn().mockResolvedValue(undefined);
+
+ renderWithProviders(
+ ,
+ );
+
+ await user.type(screen.getByLabelText("Name"), "Ultrafast key");
+ await user.click(screen.getByRole("combobox", { name: /enforced service tier/i }));
+ await user.click(await screen.findByRole("option", { name: "Ultrafast" }));
+ await user.click(screen.getByRole("button", { name: "Create" }));
+
+ await waitFor(() => {
+ expect(onSubmit).toHaveBeenCalledTimes(1);
+ });
+
+ expect(onSubmit.mock.calls[0][0].enforcedServiceTier).toBe("ultrafast");
+ });
+
it("renders and submits a transport policy override", async () => {
const user = userEvent.setup();
const onSubmit = vi.fn().mockResolvedValue(undefined);
diff --git a/frontend/src/features/api-keys/components/api-key-create-dialog.tsx b/frontend/src/features/api-keys/components/api-key-create-dialog.tsx
index e6589988dc..c4376d00b7 100644
--- a/frontend/src/features/api-keys/components/api-key-create-dialog.tsx
+++ b/frontend/src/features/api-keys/components/api-key-create-dialog.tsx
@@ -260,6 +260,7 @@ function ApiKeyCreateForm({ busy, onClose, onSubmit }: ApiKeyCreateFormProps) {
{t("common.serviceTier.default")}{t("common.serviceTier.priority")}{t("common.serviceTier.flex")}
+ {t("common.serviceTier.ultrafast")}
diff --git a/frontend/src/features/api-keys/components/api-key-edit-dialog.test.tsx b/frontend/src/features/api-keys/components/api-key-edit-dialog.test.tsx
index bc8ddd7929..df842ed191 100644
--- a/frontend/src/features/api-keys/components/api-key-edit-dialog.test.tsx
+++ b/frontend/src/features/api-keys/components/api-key-edit-dialog.test.tsx
@@ -527,6 +527,20 @@ describe("ApiKeyEditDialog", () => {
const trafficClassSelect = screen.getByRole("combobox", { name: /traffic class/i });
expect(trafficClassSelect).toHaveTextContent("Opportunistic");
});
+
+ it("shows the stored Ultrafast service tier", () => {
+ renderWithProviders(
+ ,
+ );
+
+ expect(screen.getByRole("combobox", { name: /enforced service tier/i })).toHaveTextContent("Ultrafast");
+ });
});
describe("hasLimitRuleChanges", () => {
diff --git a/frontend/src/features/api-keys/components/api-key-edit-dialog.tsx b/frontend/src/features/api-keys/components/api-key-edit-dialog.tsx
index 3885d2d15c..f405931770 100644
--- a/frontend/src/features/api-keys/components/api-key-edit-dialog.tsx
+++ b/frontend/src/features/api-keys/components/api-key-edit-dialog.tsx
@@ -320,9 +320,11 @@ function ApiKeyEditForm({ apiKey, busy, onSubmit, onClose }: ApiKeyEditFormProps
-
{t("apiKeys.form.enforcedServiceTier")}
+
diff --git a/frontend/src/features/api-keys/schemas.test.ts b/frontend/src/features/api-keys/schemas.test.ts
index b87465d201..10b77f3870 100644
--- a/frontend/src/features/api-keys/schemas.test.ts
+++ b/frontend/src/features/api-keys/schemas.test.ts
@@ -189,6 +189,15 @@ describe("ApiKeyCreateRequestSchema", () => {
expect(parsed.enforcedReasoningEffort).toBe("ultra");
});
+ it("accepts Ultrafast service tier in create payload", () => {
+ const parsed = ApiKeyCreateRequestSchema.parse({
+ name: "Ultrafast key",
+ enforcedServiceTier: "ultrafast",
+ });
+
+ expect(parsed.enforcedServiceTier).toBe("ultrafast");
+ });
+
it("accepts a non-empty allowed reasoning effort list", () => {
const parsed = ApiKeyCreateRequestSchema.parse({
name: "Selectable reasoning key",
@@ -277,6 +286,14 @@ describe("ApiKeyUpdateRequestSchema", () => {
expect(parsed.trafficClass).toBe("opportunistic");
});
+
+ it("accepts Ultrafast service tier in update payload", () => {
+ const parsed = ApiKeyUpdateRequestSchema.parse({
+ enforcedServiceTier: "ultrafast",
+ });
+
+ expect(parsed.enforcedServiceTier).toBe("ultrafast");
+ });
});
describe("LimitRuleCreateSchema", () => {
diff --git a/frontend/src/features/api-keys/schemas.ts b/frontend/src/features/api-keys/schemas.ts
index a192e37864..2bbd8b91b0 100644
--- a/frontend/src/features/api-keys/schemas.ts
+++ b/frontend/src/features/api-keys/schemas.ts
@@ -30,7 +30,7 @@ const ApiKeyUsageSummarySchema = z.object({
totalCostUsd: z.number().nonnegative().default(0),
});
-const SERVICE_TIERS = ["auto", "default", "priority", "flex"] as const;
+const SERVICE_TIERS = ["auto", "default", "priority", "flex", "ultrafast"] as const;
export type ServiceTierType = (typeof SERVICE_TIERS)[number];
export const TRAFFIC_CLASSES = ["foreground", "opportunistic"] as const;
diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json
index 518306ccf3..41a81f801d 100644
--- a/frontend/src/i18n/locales/en.json
+++ b/frontend/src/i18n/locales/en.json
@@ -559,6 +559,7 @@
"common.serviceTier.default": "Default",
"common.serviceTier.flex": "Flex",
"common.serviceTier.priority": "Priority",
+ "common.serviceTier.ultrafast": "Ultrafast",
"common.states.active": "Active",
"common.states.disabled": "Disabled",
"common.states.enabled": "Enabled",
diff --git a/frontend/src/i18n/locales/ko.json b/frontend/src/i18n/locales/ko.json
index adac30f799..b5d482b8c9 100644
--- a/frontend/src/i18n/locales/ko.json
+++ b/frontend/src/i18n/locales/ko.json
@@ -559,6 +559,7 @@
"common.serviceTier.default": "Default",
"common.serviceTier.flex": "Flex",
"common.serviceTier.priority": "Priority",
+ "common.serviceTier.ultrafast": "Ultrafast",
"common.states.active": "활성",
"common.states.disabled": "꺼짐",
"common.states.enabled": "켜짐",
diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json
index e76c857631..60d781635a 100644
--- a/frontend/src/i18n/locales/zh-CN.json
+++ b/frontend/src/i18n/locales/zh-CN.json
@@ -559,6 +559,7 @@
"common.serviceTier.default": "默认",
"common.serviceTier.flex": "Flex",
"common.serviceTier.priority": "优先",
+ "common.serviceTier.ultrafast": "Ultrafast",
"common.states.active": "活跃",
"common.states.disabled": "已禁用",
"common.states.enabled": "已启用",
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/.openspec.yaml b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/.openspec.yaml
new file mode 100644
index 0000000000..4af864176c
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-08-14
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/design.md b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/design.md
new file mode 100644
index 0000000000..8edd2e5838
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/design.md
@@ -0,0 +1,35 @@
+## Context
+
+The Responses request models, upstream transports, request logs, and model registry already carry service tiers as normalized strings. They therefore preserve `ultrafast` without a transport change and can route it using live per-account catalog metadata. The remaining hard-coded allowlists are the API-key CRUD contract and dashboard controls.
+
+OpenAI documents `ultrafast` as an access-controlled processing tier currently available for `gpt-5.6-sol`. Entitlement must therefore come from each account's live upstream catalog instead of a static plan or bootstrap assumption.
+
+## Goals / Non-Goals
+
+**Goals:**
+
+- Make `ultrafast` a supported canonical API-key service tier.
+- Expose the tier through the existing dashboard API-key controls.
+- Preserve existing entitlement-aware account routing and response-tier logging.
+- Add focused regression coverage and user-facing compatibility notes.
+
+**Non-Goals:**
+
+- Invent an `ultrafast` model-name alias.
+- Advertise Ultrafast from bootstrap metadata or grant it to a plan statically.
+- Add a setting, dependency, or database migration.
+- Guess a distinct Ultrafast token price that OpenAI has not published.
+
+## Decisions
+
+1. Add `ultrafast` only to the existing backend and frontend API-key tier allowlists. The request models and transports already pass it through, so adding another normalization layer would duplicate working behavior.
+2. Keep `ultrafast` canonical. Unlike the legacy `fast` alias, it is an upstream wire value and must not normalize to `priority`.
+3. Reuse live model-catalog routing. An explicit or enforced Ultrafast request can select only accounts whose catalog advertises that tier; the existing enforced-tier fallback still removes it for models that do not advertise it.
+4. Do not add Ultrafast to the bundled model catalog. Static metadata cannot prove access to an access-controlled preview and would expose a tier that an imported account may not hold.
+5. Keep pricing unchanged. No distinct public Ultrafast token price is available in the official OpenAI documentation, so this change does not introduce a speculative multiplier.
+
+## Risks / Trade-offs
+
+- [An entitled account's catalog does not advertise `ultrafast`] → The existing explicit-tier routing error remains visible instead of silently selecting an ineligible account.
+- [OpenAI later publishes distinct Ultrafast pricing] → Add the published rates in a focused pricing change before claiming separate cost accuracy.
+- [Dashboard-visible option requires review evidence] → Include before and after screenshots in the PR body as required by the simplicity gates.
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/proposal.md b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/proposal.md
new file mode 100644
index 0000000000..cc3ec42afe
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/proposal.md
@@ -0,0 +1,27 @@
+## Why
+
+OpenAI introduced an access-controlled Ultrafast processing tier for `gpt-5.6-sol`. codex-lb already preserves unknown request tier strings, but its API-key policy and dashboard reject `ultrafast`, leaving the feature incomplete and untested.
+
+## What Changes
+
+- Accept and persist `ultrafast` as an API-key-enforced service tier.
+- Expose Ultrafast in the API key create and edit controls.
+- Preserve and forward the canonical `ultrafast` value through Responses-compatible routes.
+- Use live upstream model-catalog entitlement data to route Ultrafast requests only to advertising accounts.
+- Document the upstream availability constraint and add focused regression coverage.
+
+## Capabilities
+
+### New Capabilities
+
+None.
+
+### Modified Capabilities
+
+- `api-keys`: allow dashboard API keys to enforce the canonical `ultrafast` tier.
+- `responses-api-compat`: define pass-through behavior for explicit and enforced Ultrafast requests.
+- `model-catalog-compat`: define entitlement-aware account routing for the access-controlled tier.
+
+## Impact
+
+The change affects API-key request validation and normalization, dashboard API-key forms and translations, Responses compatibility documentation, model-catalog routing tests, and focused backend/frontend tests. It adds no dependency, setting, database migration, or bootstrap entitlement metadata.
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/api-keys/spec.md b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/api-keys/spec.md
new file mode 100644
index 0000000000..591b8408d6
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/api-keys/spec.md
@@ -0,0 +1,17 @@
+## ADDED Requirements
+
+### Requirement: API keys can enforce the Ultrafast service tier
+
+The dashboard API key CRUD surface MUST accept and persist `ultrafast` as a canonical enforced service tier. The service MUST return the same canonical value and MUST NOT normalize it to `priority`.
+
+#### Scenario: Create an API key with Ultrafast enforcement
+
+- **WHEN** a dashboard client creates an API key with `enforcedServiceTier: "ultrafast"`
+- **THEN** the request is accepted
+- **AND** the persisted and returned enforced service tier is `ultrafast`
+
+#### Scenario: Enforce Ultrafast on an advertising model
+
+- **GIVEN** an account model advertises the `ultrafast` service tier
+- **WHEN** a request uses an API key whose enforced service tier is `ultrafast`
+- **THEN** the upstream request carries `service_tier: "ultrafast"`
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/model-catalog-compat/spec.md b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/model-catalog-compat/spec.md
new file mode 100644
index 0000000000..b69a2ced33
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/model-catalog-compat/spec.md
@@ -0,0 +1,17 @@
+## ADDED Requirements
+
+### Requirement: Ultrafast routing follows live account entitlement
+
+The system MUST treat `ultrafast` as an access-controlled service tier and MUST derive account eligibility from live or retained per-account upstream catalog metadata. The bundled bootstrap catalog MUST NOT invent Ultrafast entitlement.
+
+#### Scenario: Only an advertising account is eligible
+
+- **GIVEN** two accounts advertise `gpt-5.6-sol`
+- **AND** only one account advertises the `ultrafast` service tier
+- **WHEN** a request explicitly asks for `service_tier: "ultrafast"`
+- **THEN** account selection considers only the advertising account
+
+#### Scenario: Bootstrap metadata does not grant preview access
+
+- **WHEN** no live or retained account catalog advertises `ultrafast`
+- **THEN** bootstrap model metadata does not expose or grant that tier
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/responses-api-compat/spec.md b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/responses-api-compat/spec.md
new file mode 100644
index 0000000000..c2bace9663
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/specs/responses-api-compat/spec.md
@@ -0,0 +1,15 @@
+## ADDED Requirements
+
+### Requirement: Responses routes preserve the Ultrafast service tier
+
+Responses-compatible routes MUST accept the canonical `ultrafast` service tier and MUST forward it unchanged. When upstream reports the actual response tier, request logging MUST preserve `ultrafast` using the existing requested, actual, and billable tier contract.
+
+#### Scenario: Explicit Ultrafast request is forwarded
+
+- **WHEN** a client sends a Responses request with `service_tier: "ultrafast"`
+- **THEN** the forwarded upstream payload contains `service_tier: "ultrafast"`
+
+#### Scenario: Upstream confirms Ultrafast processing
+
+- **WHEN** upstream completes a request with `response.service_tier: "ultrafast"`
+- **THEN** the actual and billable request-log tiers are `ultrafast`
diff --git a/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/tasks.md b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/tasks.md
new file mode 100644
index 0000000000..bf283c6da4
--- /dev/null
+++ b/openspec/changes/archive/2026-08-14-support-ultrafast-service-tier/tasks.md
@@ -0,0 +1,15 @@
+## 1. Backend support
+
+- [x] 1.1 Accept and persist canonical `ultrafast` API-key enforcement values
+- [x] 1.2 Add focused request, API-key, catalog-routing, and logging regression coverage
+
+## 2. Dashboard and documentation
+
+- [x] 2.1 Add Ultrafast to dashboard schemas, create/edit controls, and translations
+- [x] 2.2 Add frontend schema and interaction coverage for the new option
+- [x] 2.3 Document official availability, entitlement behavior, and a concrete request example
+
+## 3. Verification
+
+- [x] 3.1 Validate OpenSpec artifacts and run focused backend/frontend checks
+- [x] 3.2 Run the repository local CI gate and capture dashboard before/after evidence
diff --git a/openspec/specs/api-keys/spec.md b/openspec/specs/api-keys/spec.md
index 2127be5b61..274490f613 100644
--- a/openspec/specs/api-keys/spec.md
+++ b/openspec/specs/api-keys/spec.md
@@ -1403,3 +1403,19 @@ reclamation does.
- **WHEN** stale usage-reservation reclamation runs
- **THEN** the reservation stays `reserved`
+### Requirement: API keys can enforce the Ultrafast service tier
+
+The dashboard API key CRUD surface MUST accept and persist `ultrafast` as a canonical enforced service tier. The service MUST return the same canonical value and MUST NOT normalize it to `priority`.
+
+#### Scenario: Create an API key with Ultrafast enforcement
+
+- **WHEN** a dashboard client creates an API key with `enforcedServiceTier: "ultrafast"`
+- **THEN** the request is accepted
+- **AND** the persisted and returned enforced service tier is `ultrafast`
+
+#### Scenario: Enforce Ultrafast on an advertising model
+
+- **GIVEN** an account model advertises the `ultrafast` service tier
+- **WHEN** a request uses an API key whose enforced service tier is `ultrafast`
+- **THEN** the upstream request carries `service_tier: "ultrafast"`
+
diff --git a/openspec/specs/model-catalog-compat/spec.md b/openspec/specs/model-catalog-compat/spec.md
index 8cbc2cc3ba..4c5141e9c7 100644
--- a/openspec/specs/model-catalog-compat/spec.md
+++ b/openspec/specs/model-catalog-compat/spec.md
@@ -1057,3 +1057,18 @@ The model catalog builders for `GET /v1/models` and `GET /backend-api/codex/mode
acquisition
- **THEN** the reservation is released before cancellation propagates
+### Requirement: Ultrafast routing follows live account entitlement
+
+The system MUST treat `ultrafast` as an access-controlled service tier and MUST derive account eligibility from live or retained per-account upstream catalog metadata. The bundled bootstrap catalog MUST NOT invent Ultrafast entitlement.
+
+#### Scenario: Only an advertising account is eligible
+
+- **GIVEN** two accounts advertise `gpt-5.6-sol`
+- **AND** only one account advertises the `ultrafast` service tier
+- **WHEN** a request explicitly asks for `service_tier: "ultrafast"`
+- **THEN** account selection considers only the advertising account
+
+#### Scenario: Bootstrap metadata does not grant preview access
+
+- **WHEN** no live or retained account catalog advertises `ultrafast`
+- **THEN** bootstrap model metadata does not expose or grant that tier
diff --git a/openspec/specs/responses-api-compat/context.md b/openspec/specs/responses-api-compat/context.md
index 6f96c7ccc7..4a82968a8e 100644
--- a/openspec/specs/responses-api-compat/context.md
+++ b/openspec/specs/responses-api-compat/context.md
@@ -75,6 +75,33 @@ Responses request with:
Clients that expose Fast Mode as `fast` may keep using that spelling; codex-lb
normalizes it to `priority` before forwarding.
+### Ultrafast Processing
+
+The [OpenAI Responses API reference](https://developers.openai.com/api/reference/resources/responses/methods/create)
+documents `ultrafast` as an access-controlled processing tier currently
+available for `gpt-5.6-sol`. codex-lb forwards this canonical value unchanged;
+it does not grant Ultrafast access by itself.
+
+Account eligibility comes from live or retained per-account upstream catalog
+metadata. The bundled bootstrap catalog deliberately does not advertise
+Ultrafast. If no account advertises the tier, an explicit Ultrafast request
+cannot select an eligible account; API-key enforcement follows the existing
+model-capability fallback when the model itself does not advertise the tier.
+
+Send a Responses request with:
+
+```json
+{
+ "model": "gpt-5.6-sol",
+ "input": "Summarize the change.",
+ "service_tier": "ultrafast"
+}
+```
+
+After completion, verify that the response reports
+`service_tier: "ultrafast"`. Request logs retain `ultrafast` in the requested,
+actual, and effective billable tier fields when upstream confirms it.
+
### Operator Fast Mode prohibition
Operators can enable the Routing setting `prohibitFastMode` when qualified
diff --git a/openspec/specs/responses-api-compat/spec.md b/openspec/specs/responses-api-compat/spec.md
index a580853043..a56410d4de 100644
--- a/openspec/specs/responses-api-compat/spec.md
+++ b/openspec/specs/responses-api-compat/spec.md
@@ -5299,3 +5299,16 @@ only an inactive `unknown` operation may enter a fresh recovery attempt.
- **WHEN** a duplicate request finds a submitted operation still referenced by another pending request
- **THEN** the proxy refuses a second dispatch and preserves the existing spool
+### Requirement: Responses routes preserve the Ultrafast service tier
+
+Responses-compatible routes MUST accept the canonical `ultrafast` service tier and MUST forward it unchanged. When upstream reports the actual response tier, request logging MUST preserve `ultrafast` using the existing requested, actual, and billable tier contract.
+
+#### Scenario: Explicit Ultrafast request is forwarded
+
+- **WHEN** a client sends a Responses request with `service_tier: "ultrafast"`
+- **THEN** the forwarded upstream payload contains `service_tier: "ultrafast"`
+
+#### Scenario: Upstream confirms Ultrafast processing
+
+- **WHEN** upstream completes a request with `response.service_tier: "ultrafast"`
+- **THEN** the actual and billable request-log tiers are `ultrafast`
diff --git a/tests/integration/test_api_keys_api.py b/tests/integration/test_api_keys_api.py
index 2b976c34e3..4508b5dbe0 100644
--- a/tests/integration/test_api_keys_api.py
+++ b/tests/integration/test_api_keys_api.py
@@ -4,6 +4,7 @@
import base64
import contextlib
import json
+from dataclasses import replace
from datetime import timedelta
from types import SimpleNamespace
from typing import cast
@@ -778,10 +779,14 @@ async def fake_stream(payload, _headers, _access_token, _account_id, base_url=No
@pytest.mark.asyncio
-async def test_api_key_enforces_service_tier_for_responses(async_client, monkeypatch):
- await _populate_test_registry()
- model_ids = sorted(_TEST_MODELS)
- forced_model = model_ids[0]
+@pytest.mark.parametrize(
+ ("enforced_service_tier", "expected_service_tier"),
+ [("fast", "priority"), ("ULTRAFAST", "ultrafast")],
+)
+async def test_api_key_enforces_service_tier_for_responses(
+ async_client, monkeypatch, enforced_service_tier, expected_service_tier
+):
+ forced_model = "gpt-5.6-sol"
enable = await async_client.put(
"/api/settings",
@@ -794,27 +799,47 @@ async def test_api_key_enforces_service_tier_for_responses(async_client, monkeyp
)
assert enable.status_code == 200
+ account_id = await _import_account(
+ async_client,
+ f"acc_enforced_{expected_service_tier}_service_tier",
+ f"enforced-{expected_service_tier}-service-tier@example.com",
+ )
+ advertising_model = replace(
+ _make_upstream_model(forced_model),
+ raw={"service_tiers": [{"slug": expected_service_tier}]},
+ )
+ await get_model_registry().update(
+ {"pro": [advertising_model]},
+ per_account_results={account_id: ("pro", [advertising_model])},
+ active_account_plans={account_id: "pro"},
+ )
+
created = await async_client.post(
"/api/api-keys/",
json={
"name": "enforced-service-tier",
"allowedModels": [forced_model],
"enforcedModel": forced_model,
- "enforcedServiceTier": "fast",
+ "enforcedServiceTier": enforced_service_tier,
},
)
assert created.status_code == 200
key = created.json()["key"]
- assert created.json()["enforcedServiceTier"] == "priority"
-
- await _import_account(async_client, "acc_enforced_service_tier", "enforced-service-tier@example.com")
+ assert created.json()["enforcedServiceTier"] == expected_service_tier
seen: dict[str, str | None] = {}
async def fake_stream(payload, _headers, _access_token, _account_id, base_url=None, raise_for_status=False):
seen["service_tier"] = payload.service_tier
usage = {"input_tokens": 3, "output_tokens": 2}
- event = {"type": "response.completed", "response": {"id": "resp_enforced_service_tier", "usage": usage}}
+ event = {
+ "type": "response.completed",
+ "response": {
+ "id": "resp_enforced_service_tier",
+ "service_tier": expected_service_tier,
+ "usage": usage,
+ },
+ }
yield f"data: {json.dumps(event)}\n\n"
monkeypatch.setattr(proxy_module, "core_stream_responses", fake_stream)
@@ -834,7 +859,15 @@ async def fake_stream(payload, _headers, _access_token, _account_id, base_url=No
assert response.status_code == 200
_ = [line async for line in response.aiter_lines() if line]
- assert seen["service_tier"] == "priority"
+ assert seen["service_tier"] == expected_service_tier
+
+ async with SessionLocal() as session:
+ result = await session.execute(select(RequestLog).order_by(RequestLog.requested_at.desc()))
+ latest_log = result.scalars().first()
+ assert latest_log is not None
+ assert latest_log.requested_service_tier == expected_service_tier
+ assert latest_log.actual_service_tier == expected_service_tier
+ assert latest_log.service_tier == expected_service_tier
@pytest.mark.asyncio
diff --git a/tests/unit/test_api_keys_service.py b/tests/unit/test_api_keys_service.py
index 63fc9d9e1d..9a33fd47f1 100644
--- a/tests/unit/test_api_keys_service.py
+++ b/tests/unit/test_api_keys_service.py
@@ -848,6 +848,23 @@ async def test_create_key_normalizes_fast_service_tier_alias() -> None:
assert created.enforced_service_tier == "priority"
+@pytest.mark.asyncio
+async def test_create_key_preserves_ultrafast_service_tier() -> None:
+ repo = _FakeApiKeysRepository()
+ service = ApiKeysService(repo)
+
+ created = await service.create_key(
+ ApiKeyCreateData(
+ name="ultrafast-service-tier-policy",
+ allowed_models=None,
+ enforced_service_tier=" ULTRAFAST ",
+ expires_at=None,
+ )
+ )
+
+ assert created.enforced_service_tier == "ultrafast"
+
+
@pytest.mark.asyncio
async def test_update_key_normalizes_service_tier_alias() -> None:
repo = _FakeApiKeysRepository()
diff --git a/tests/unit/test_model_registry.py b/tests/unit/test_model_registry.py
index 2cc88b077e..fa3ed54477 100644
--- a/tests/unit/test_model_registry.py
+++ b/tests/unit/test_model_registry.py
@@ -253,6 +253,7 @@ def test_bootstrap_models_include_representative_upstream_metadata():
"ultra",
]
assert sol.raw["additional_speed_tiers"] == ["fast"]
+ assert "ultrafast" not in str(sol.raw["service_tiers"])
terra = models["gpt-5.6-terra"]
assert terra.display_name == "GPT-5.6-Terra"
diff --git a/tests/unit/test_openai_requests.py b/tests/unit/test_openai_requests.py
index 36d4e91af9..04e8cd6e60 100644
--- a/tests/unit/test_openai_requests.py
+++ b/tests/unit/test_openai_requests.py
@@ -175,17 +175,18 @@ def test_strip_unsupported_fields_namespace_flag_controls_replayed_calls(namespa
assert stripped["input"] == [{"type": "function_call"}]
-def test_responses_preserves_service_tier():
+@pytest.mark.parametrize("service_tier", ["priority", "ultrafast"])
+def test_responses_preserves_service_tier(service_tier: str):
payload = {
"model": "gpt-5.1",
"instructions": "hi",
"input": [],
- "service_tier": "priority",
+ "service_tier": service_tier,
}
request = ResponsesRequest.model_validate(payload)
dumped = request.to_payload()
- assert dumped["service_tier"] == "priority"
+ assert dumped["service_tier"] == service_tier
def test_responses_normalizes_fast_service_tier_to_priority_for_upstream():
@@ -579,16 +580,17 @@ def test_openai_compatible_top_level_verbosity_is_normalized():
assert "verbosity" not in dumped
-def test_v1_responses_preserves_service_tier():
+@pytest.mark.parametrize("service_tier", ["priority", "ultrafast"])
+def test_v1_responses_preserves_service_tier(service_tier: str):
payload = {
"model": "gpt-5.1",
"input": "hello",
- "service_tier": "priority",
+ "service_tier": service_tier,
}
request = V1ResponsesRequest.model_validate(payload).to_responses_request()
dumped = request.to_payload()
- assert dumped["service_tier"] == "priority"
+ assert dumped["service_tier"] == service_tier
def test_v1_responses_normalizes_fast_service_tier_to_priority_for_upstream():
diff --git a/tests/unit/test_proxy_load_balancer_refresh.py b/tests/unit/test_proxy_load_balancer_refresh.py
index f82d9b5fa8..6166c2e824 100644
--- a/tests/unit/test_proxy_load_balancer_refresh.py
+++ b/tests/unit/test_proxy_load_balancer_refresh.py
@@ -1237,26 +1237,26 @@ async def test_select_account_filters_requested_service_tier_plans(monkeypatch)
@pytest.mark.asyncio
async def test_select_account_filters_requested_service_tier_accounts(monkeypatch) -> None:
- no_fast = _make_account("acc-tier-pro-default", "tier-pro-default@example.com")
- no_fast.plan_type = "pro"
- fast = _make_account("acc-tier-pro-fast", "tier-pro-fast@example.com")
- fast.plan_type = "pro"
+ no_ultrafast = _make_account("acc-tier-pro-default", "tier-pro-default@example.com")
+ no_ultrafast.plan_type = "pro"
+ ultrafast = _make_account("acc-tier-pro-ultrafast", "tier-pro-ultrafast@example.com")
+ ultrafast.plan_type = "pro"
now = utcnow()
now_epoch = int(now.replace(tzinfo=timezone.utc).timestamp())
usage_repo = StubUsageRepository(
primary={
- no_fast.id: UsageHistory(
+ no_ultrafast.id: UsageHistory(
id=63,
- account_id=no_fast.id,
+ account_id=no_ultrafast.id,
recorded_at=now,
window="primary",
used_percent=1.0,
reset_at=now_epoch + 300,
window_minutes=5,
),
- fast.id: UsageHistory(
+ ultrafast.id: UsageHistory(
id=64,
- account_id=fast.id,
+ account_id=ultrafast.id,
recorded_at=now,
window="primary",
used_percent=2.0,
@@ -1272,7 +1272,7 @@ async def test_select_account_filters_requested_service_tier_accounts(monkeypatc
lambda: SimpleNamespace(
plan_types_for_model=lambda _model: frozenset({"pro"}),
account_ids_for_model_service_tier=lambda _model, tier: (
- frozenset({fast.id}) if tier == "priority" else None
+ frozenset({ultrafast.id}) if tier == "ultrafast" else None
),
plan_types_for_model_service_tier=lambda _model, _tier: frozenset({"pro"}),
),
@@ -1280,15 +1280,15 @@ async def test_select_account_filters_requested_service_tier_accounts(monkeypatc
balancer = LoadBalancer(
lambda: _repo_factory(
- StubAccountsRepository([no_fast, fast]),
+ StubAccountsRepository([no_ultrafast, ultrafast]),
usage_repo,
StubStickySessionsRepository(),
)
)
- selection = await balancer.select_account(model="gpt-5.5", service_tier="priority")
+ selection = await balancer.select_account(model="gpt-5.6-sol", service_tier="ultrafast")
assert selection.account is not None
- assert selection.account.id == fast.id
+ assert selection.account.id == ultrafast.id
@pytest.mark.asyncio