> For the complete documentation index, see [llms.txt](https://docs.auray.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.auray.ai/changelog/readme.md).

# Changelog

The surface answers `503 api_disabled` today, so none of this is reachable yet. It is recorded anyway: it is the state you will integrate against when the switch is flipped, and two of these change what a request may say.

{% updates %}
{% update date="2026-08-27" %}

## The 2K upscale pass was switched off on every plan

`upscale_2k: true` now answers `403 upscale_not_in_plan` on all four plans, `max` and `ultimate` included. Before this, those two accepted the flag, charged the surcharge — five credits per second of finished video, per variant — dispatched, were refused by the video service's own validator, and refunded. A round trip through the customer's wallet for a pass that cannot run, live for eleven days.

The service had 2K off the whole time: the deployment of 16 August reports `upscale_2k_available: false`. The repository said otherwise, and nothing recorded the difference. The plan table now says what the service does.

**What to change:** drop the flag. There is no upgrade that accepts it, and retrying does not help. Callers who never sent it are unaffected — the field is read as a boolean, so anything that is not `true` is still taken as false.

No bill moves: zero jobs have ever requested 2K, in the entire history of the table. That is luck rather than design, which is why this is worth an entry rather than a quiet fix.
{% endupdate %}

{% update date="2026-08-27" %}

## Video's `standard` tier was retired, and its containers went to `pro`

Video has two tiers now, `fast` and `pro`. `standard` and `pro` were the same render — 50 steps, turbo off, quality "lossless", the same base checkpoint — and the only difference was hardware. Measured warm on a 5-second clip: `standard` 78.0 s at $0.3935 of GPU and 33 credits, `pro` 24.7 s at $0.3431 and 29 credits. Three times slower, 15% dearer to run and 14% dearer to buy, for identical output. There was never a customer for whom it was the right choice.

`fast` stays because it is a different product rather than a slower one: eight steps against fifty, a Turbo adapter rather than the base checkpoint, and 8 credits for the same 5 seconds.

**What to change:** stop sending `tier: "standard"`. v1 parses tiers strictly and does not coerce them, so it now answers `400 unknown_tier` with the accepted values in `tiers`. If you send no tier at all, the default is `pro` — the same 50 steps a caller who named nothing already got, faster and for four credits less.

Jobs already stored under `standard` still read back and re-render; they map to `pro`, which is an honest destination rather than a convenient one for exactly the reasons above.

Capacity moved with the tier. `H3_MAX_CONTAINERS_PRO` goes 2 to 4 while `fast` stays at 4, so the GPU footprint is unchanged at 48 units and the 50-step pool — the tightest on the platform — doubled. The platform video cap follows its pools down from 10 to 8, divided six to the browser, one to the API, one floating.

Every paid plan now carries both tiers. `pro` plan held `["fast","standard"]`, and `fast` cannot take reference images or dialogue, so dropping `standard` without promoting them would have removed both from that plan.
{% endupdate %}

{% update date="2026-08-27" %}

## Video admission became per tier

The tiers are independently scaled pools of containers, not one product with one number: different cards, different checkpoints chosen at server start, and a free `fast` container cannot take a `pro` job. Admission counted video rows against the sum, so a burst of `pro` requests passed a global cap comfortably and then queued behind a pool that was full, while `fast` sat idle.

`admit_job` now counts the tier as well, in the same scan and under the same advisory lock.

**What to change:** nothing in a request. A client that switches on error codes should learn one new one — `429 tier_busy`, carrying `tier` and `limit`. It is deliberately not `service_busy`: which lane filled the product is our problem, but which tier filled is yours, and the obvious next move is the other tier. `fast` is roughly a quarter of the price and usually has room when `pro` does not.

`too_many_jobs` now carries `tier` too, and the per-account allowance is held against the pool that will actually run the job rather than the platform: one below the pool, or your plan's allowance, whichever is smaller.

Two quieter parts of the same change. All three submit paths — single clip, storyboard, revision — now check capacity, where only the first of them did; a job refused for capacity has never taken money first, and now that is true from every direction. And the count is bounded at two hours against the attempt clock rather than the row's creation, so a re-render of an old chain stops being invisible to it.
{% endupdate %}

{% update date="2026-08-27" %}

## Music concurrency was raised to ten

The platform admitted five music jobs at once against a service that has always been willing to run ten: `MAX_CONTAINERS` defaults to 10 and the model class carries no `@modal.concurrent`, so that is ten containers each serving one job. Half the ceiling this platform was already paying to have available was being refused at admission, and while the two numbers lived in two repositories nobody could see it.

**Nothing changes for an API caller, and that is deliberate.** The raise went to the browser: its lane goes from four to nine. The API lane stays exactly where it was at two — one reserved seat plus the float — because `API_V1_ENABLED` is unset and reserving more seats for traffic that cannot arrive yet would move a ceiling nothing is reaching. The per-account wait cap is derived from the four API lanes, so it did not move either.

Worth knowing before the arithmetic looks wrong: raising the global cap alone would have delivered almost nothing. Admission checks the lane before the global, so the lane was the binding number the whole time.
{% endupdate %}
{% endupdates %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.auray.ai/changelog/readme.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
