The three 429s
Backing off
Both retryable cases setRetry-After in seconds. Honour it — it is the platform telling
you what it knows, and it beats a fixed guess:
Retry-After is absent, exponential backoff with jitter is the right fallback. Retrying
immediately, in a loop, across every worker you have, turns a brief upstream wobble into a
sustained one.
Money, not speed
Three more codes stop you for billing reasons rather than throughput. None of them are retryable, and none of them are billed:
Auto-reload, spending limits and the current balance all live in the console under
Billing. Setting a spending limit is what produces
TENANT_BUDGET_EXCEEDED — it is a
guardrail you asked for, not a failure.
Reducing the pressure
- Stream.
stream: truedoes not change your token cost, but it frees the connection sooner and gets the first token to your user much earlier. - Cap
max_tokens. An unbounded generation occupies capacity until the model decides to stop, and you pay for all of it. - Retry the right thing. A retry after
UPSTREAM_RATE_LIMITEDmay well land on a different provider for the same model — that is whatx-provider-class: fallbackon the response is telling you.
Seeing your own usage
Every response carries ausage object with the token counts you were billed on. The
console shows the same figures per request, per model and per day, so reconciling what you
measured against what you were charged does not require an export.
Next
Errors
All 28 codes, with retryability and billing.
Authentication
What a key is allowed to reach in the first place.