# Lock down OpenAI service tiers per project before costs drift

URL: https://infro.io/blog/lock-down-openai-service-tiers-per-project-before-costs-drift
Author: INFRO Editorial (https://infro.io/blog/editorial)
Publisher: INFRO
Published: 2026-10-28
Last modified: 2026-10-28
Last reviewed: 2026-10-28 (next review due 2026-11-27)
Topic: Security and governance
Format: Checklist

> OpenAI added per-project service tier settings and an organization-wide restriction on 21 October 2026 [^openai-changelog]. Allow Standard everywhere, Flex for background work, Fast only on named user-facing projects and Ultrafast by exception, then probe every project key to confirm the restriction holds.

Key takeaways:
- OpenAI shipped project-level service tier choice and an organization-level restriction on 21 October 2026; the org setting restricts tiers for all projects.
- Fast costs twice Standard and Ultrafast six times Standard on GPT-6.1 Sol list rates, so an unrestricted project default is a silent multiplier.
- Allow Standard and Flex in development and staging, and add Fast or Ultrafast in production only for named projects with an owner.
- Do not trust the settings page: send one tiny request per tier through every project key and record the status and the returned service_tier.
- Check aliases (priority, fast, auto, omitted), both Chat Completions and Responses, and the Agents API, because each is a separate way to ask for a tier.

## What changed on 21 October, and what it does not tell you

OpenAI's changelog for 21 October 2026 says you can now choose which service tiers projects can use in Platform settings, and that organization settings can restrict service tiers for all projects.[1] That is the whole announcement. It points to a "service tier errors" section of the error codes guide, which this article did not read, so the exact status code and error code a blocked request returns are left for you to capture in the probe below.

Two facts matter for the rest of this checklist. First, a tier is chosen per request with the `service_tier` parameter or by a project default. For Fast mode, setting **Project Service Tier** to **Fast** in project settings makes requests that omit `service_tier` default to Fast, and the project transitions gradually over time.[2] A project can therefore change its own cost profile without any code change. Second, Fast accepts both `fast` and `priority` as values, so a policy that only thinks about one spelling is incomplete.[2]

This article is for teams that share one OpenAI organization across many projects. It does not repeat the tier comparison in [LLM service tiers compared](https://infro.io/blog/llm-service-tiers-compared-2026) or the cap mechanics in [provider spend limits compared](https://infro.io/blog/provider-spend-limits-compared). It covers where to set the restriction, what to allow in each environment, and how to prove it holds.

## Why an unrestricted tier is a cost multiplier

The list rates make the case. For GPT-6.1 Sol, up to 272K input tokens, OpenAI's pricing page lists these per-million-token rates by tier.[3]

| Tier | Input | Output |
| --- | --- | --- |
| Flex | $1.00 | $5.00 |
| Standard | $2.00 | $10.00 |
| Fast | $4.00 | $20.00 |
| Ultrafast | $12.00 | $60.00 |

Table: GPT-6.1 Sol list rates per 1M tokens, short context, from OpenAI's pricing page read 2026-10-28.

The same page lists GPT-6 Astra at $10 and $50 on Standard, $20 and $100 on Fast, and $60 and $300 on Ultrafast, and lists no Ultrafast row for GPT-6 Luna.[3] These are OpenAI's list rates; your own contract may differ.

> **Example: Illustrative: one project, one setting**
> Assume a project sends 500M input and 100M output tokens a month on GPT-6.1 Sol. These volumes are made up. At the list rates above, Standard comes to $2,000, Fast to $4,000 and Ultrafast to $12,000 for identical traffic. If someone flips the project default to Fast, the next invoice doubles with no change in usage.

Fast also bills Standard when it silently downgrades. If traffic ramps too quickly, some Fast requests are downgraded to standard speed and charged standard rates, and the response carries `service_tier: "default"`.[2] That protects you from a surprise in one direction, but it means "we are on Fast" and "we are billed Fast" are not the same claim. Verify from the response, not from the setting.

## Decide which tiers each environment may use

The restriction is set per project, so the first design decision is the project layout: one OpenAI project per team per environment, for example `payments-dev`, `payments-staging` and `payments-prod`. That recommendation is ours, not an OpenAI requirement, but without it you cannot give production a different policy from development.

| Environment | Allow | Do not allow | Reason |
| --- | --- | --- | --- |
| Development | Standard, Flex | Fast, Ultrafast | Nobody is waiting on a person-facing latency target. |
| Staging | Standard, Flex | Fast, Ultrafast, unless a named load test needs them | Staging should match production behaviour, not production spend. |
| Production, background jobs | Standard, Flex | Fast, Ultrafast | Flex bills at Batch rates but may return 429 when capacity is short.[4] |
| Production, user-facing | Standard, plus Fast on named projects | Ultrafast by default | Fast is a pay-as-you-go tier for user-facing applications.[2] |
| Production, approved exception | Ultrafast on one named project | Everything else is unchanged | Six times Standard on GPT-6.1 Sol needs an owner and a measured reason.[3] |

Table: A starting policy; adjust per team after you measure where output speed is the bottleneck.

Set the organization restriction to the union of what any project legitimately needs, and keep it narrower than "everything". Because the organization setting restricts tiers for all projects,[1] it is your ceiling: if Ultrafast is off there, no project can use it. Whether an exception for one project can sit under an organization-level block is not described in the changelog entry, so test it rather than assume.

## Set the restrictions

Do this in order, outside peak hours, and write down each change with its owner.

- [ ] List every project in the organization with its owner team and environment. Projects nobody can name are the first ones to restrict.
- [ ] For each project, open its settings and choose the allowed service tiers according to the table above.
- [ ] In each project's **General** settings, check that **Project Service Tier** is not set to Fast unless the project is on your approved list.[2]
- [ ] In organization settings, restrict tiers to the union you decided on, and leave Ultrafast off until a project has an approved exception.
- [ ] Restrict who can create keys. OpenAI's 15 September change lets administrators allow only service-account keys, allow only user-owned project keys or disable new key creation at organization and project level, and organization restrictions take precedence over project settings; existing keys are unaffected.[1]
- [ ] Set a maximum key lifetime where your policy requires one. Administrators can enforce it at organization or project level, which limits how long a forgotten key keeps its tier access.[1]
- [ ] Record the change, the date and the approver in your change log. Treat the tier list like a budget: it needs an owner and a review date.

## Prove traffic cannot bypass the policy

A settings page shows intent. A probe shows behaviour. For each project key, send the smallest request you can on every tier, through every endpoint your teams use, and record the result.

```python
import os
from openai import OpenAI, APIStatusError

# One key per project, supplied by the project owner for this test.
KEYS = {
    "payments-dev": os.environ["KEY_PAYMENTS_DEV"],
    "payments-prod": os.environ["KEY_PAYMENTS_PROD"],
}
TIERS = [None, "auto", "default", "flex", "fast", "priority", "ultrafast"]

for project, key in KEYS.items():
    client = OpenAI(api_key=key)
    for tier in TIERS:
        kwargs = {} if tier is None else {"service_tier": tier}
        try:
            r = client.responses.create(
                model="gpt-6.1-sol",
                input="ping",
                max_output_tokens=16,
                **kwargs,
            )
            print(project, tier, "OK", "served as", r.service_tier)
        except APIStatusError as e:
            # Capture status and body; do not assume a specific code.
            print(project, tier, "REFUSED", e.status_code, e.response.text[:200])
```

Each allowed request is real, billed traffic, so keep the prompt trivial and the output capped. Compare the table the probe prints with your policy.

- [ ] A tier you blocked is refused, and you have saved the status code and error body so alerting can match it.
- [ ] A tier you allowed succeeds, and the returned `service_tier` is what you expected. Fast can return `default` when it was downgraded, billed at standard rates.[2]
- [ ] `fast` and `priority` behave identically under the policy. They are the same behaviour for supported models.[2]
- [ ] An omitted `service_tier` and `auto` resolve to a tier your policy allows, including in a project whose default you changed.
- [ ] Run the probe through both Chat Completions and Responses. Fast is documented for either API,[2] but Ultrafast for GPT-6.1 Sol was added to the Responses API on 8 October.[1]
- [ ] Probe the Agents API too. Ultrafast was added there on 16 October through `agent.service_tier`, a separate place to ask for a tier.[1]
- [ ] Repeat the probe with a key from a project you did not configure, and with a key created after the policy, to catch projects that inherited a default.
- [ ] If your applications reach OpenAI through a gateway or proxy, run the same probe through it with a real gateway key. The gateway must forward or refuse `service_tier` the way you expect.

## Failure modes to design around

**A default you did not choose.** The Fast project setting changes the tier for every request that omits the field.[2] Review project settings after any reorganization, not only API code.

**Retry logic that rewrites the tier.** OpenAI's Flex guidance, as summarized in INFRO's tier comparison, suggests retrying with `service_tier: "auto"` when finishing matters more than price.[4] Under a restriction, check what `auto` resolves to before you ship that fallback, and make a blocked-tier error alert instead of retry.

**Mislabelled usage on older models.** For GPT-5.6 and earlier, Fast requests appear as `priority` in the usage dashboard even when the request said `fast`. To review them, group usage by service tier, and group costs by line item.[2] Match your report filters to both labels.

**Ramp limits shared across projects.** All your traffic contributes to the same Fast ramp limit, across projects and organizations.[2] One team ramping Fast can push another team's Fast requests into Standard-speed, Standard-priced processing.

**Models without the tier.** GPT-6 Luna has no Ultrafast row on the pricing page.[3] A policy that allows Ultrafast does not make it available on every model, so keep the model dimension under its own control.

## Keep the policy from drifting

A one-time probe decays. Schedule it after every project creation, key rotation and settings change, and keep a weekly check of usage grouped by service tier against the allowed list.

If you route OpenAI calls through INFRO, a few shipped pieces cover the neighbouring controls. [Model allowlists](https://infro.io/docs/org/model-allowlists) restrict which models an organization, project or key may call, with a denied model returning a 403 `model_not_allowed`.[5] They restrict models, not tiers, so the tier restriction stays in OpenAI's settings. [Spend controls](https://infro.io/docs/org/spend-controls) add organization, project, member and key budgets on estimated spend, alongside your provider's own limits.[6] Every request also records its estimated provider cost by project and key, and daily reconciliation against OpenAI's cost API can show whether the tier mix you intended is the one you were billed for. Traffic that never touches the gateway is invisible to these, which is why the provider-side restriction and the probe come first.

## Questions

### Does INFRO's model allowlist also restrict service tiers?

The allowlist documentation describes restrictions by model, using catalog ids and vendor wildcards, at organization, project and key scope [5]. It does not describe a service tier restriction, so treat OpenAI's project and organization setting as the tier control and use INFRO's allowlist for the model dimension.

### Should a blocked-tier error trigger a retry on a different tier?

Only if you decided that on purpose. A blocked tier is a policy decision, not a capacity failure, so an automatic retry that rewrites service_tier can hide the misconfiguration. Log it, alert on it, and fix the request or the policy through the person who owns the project.

## Sources

1. Changelog | OpenAI API — OpenAI. https://developers.openai.com/api/docs/changelog.md (accessed 2026-10-28)
2. Fast mode — OpenAI. https://developers.openai.com/api/docs/guides/priority-processing.md (accessed 2026-10-28)
3. Pricing — OpenAI. https://developers.openai.com/api/docs/pricing.md (accessed 2026-10-28)
4. LLM service tiers compared: Flex, Fast, Ultrafast and Priority — INFRO. https://infro.io/blog/llm-service-tiers-compared-2026 (accessed 2026-10-28)
5. Model allowlists — INFRO. https://infro.io/docs/org/model-allowlists (accessed 2026-10-28)
6. Spend controls — INFRO. https://infro.io/docs/org/spend-controls (accessed 2026-10-28)
