---
title: "OpenRouter 429 \"Provider returned error\": meaning and fix"
canonical: https://relayswitch.io/fix/openrouter-429-provider-returned-error
generated: 2026-11-02T10:52:04.588Z
source: https://api.relayswitch.io/v1/catalog
base_url: https://api.relayswitch.io/v1
---

Fix

# OpenRouter 429 "Provider returned error": what it means and the fix

The 429 that SillyTavern, JanitorAI and every OpenAI-compatible client print the same way. What OpenRouter’s docs say it is, which limit it usually is, and the switch to a key where a failed route is retried before you see it.

[Get a key](https://app.relayswitch.io/console)[The switch](#switch)

The error

## What the client prints

json

1`HTTP 429`

2`{`

3 `"error": {`

4 `"message": "Provider returned error",`

5 `"code": 429,`

6 `"metadata": {`

7 `"raw": "...",`

8 `"provider_name": "..."`

9 `}`

10 `}`

11`}`

## What it means

OpenRouter's [error reference](https://openrouter.ai/docs/api-reference/errors) (read 2026-10-31) lists 429 as "You are being rate limited", 502 as "Your chosen model is down or we received an invalid response from it" and 503 as "There is no available model provider that meets your routing requirements". The words "Provider returned error" are the message text; the `metadata` names the provider in `provider_name` and carries its verbatim payload in `raw`.

Two limits produce it. The provider's own: the model's host refused the request and OpenRouter passed the status through. And OpenRouter's: its [limits page](https://openrouter.ai/docs/api/reference/limits) (2026-10-31) lists 20 requests a minute on free models, 50 free-model requests per UTC day for accounts with under 10 credits purchased and 1,000 with at least 10, and says a negative balance fails requests, free models included.

A 402 is the other near neighbour: the same page defines `openrouter_key_limit` as the key's credit limit exhausted and `openrouter_credits` as a balance that cannot cover the request.

## The retry rule

"Rate limits are transient; wait and retry rather than immediately re-sending" (OpenRouter's limits page, 2026-10-31). Back off with jitter and read a `Retry-After` header when one is present; the page says the in-flight-budget 402 carries one.

A 429 whose `provider_name` is set will repeat for as long as that provider is limited, because the retry goes to the same place. A daily cap on free models will not clear until the UTC day does.

The fix is a request that has somewhere else to go: another route for the same model, then another model, chosen before the error is yours.

The structural fix

## A key that fails over, with limits you set

A retry loop treats the symptom. On this key the next route is tried before the error reaches you, every limit is per key, and a failed request costs nothing. From the OpenAPI document, read 2026-10-31.

Failover before you see it

A route that fails with a 5xx or a 429 is retried on the next route for the same model. x-uplink-attempts on the answer counts the tries; the price is the model’s own either way.

Your own fallback list

models: \[...\] names up to 5 models tried in order once every route of the one before has failed before a byte was sent. Each bills at its own price when it answers.

Failed requests are not charged

A 429, 502 or 503 from this API charges nothing and carries retry-after: back off that long before trying again.

Limits per key, set by you

rpm from 1 to 100,000, tpm from 1 to 50,000,000 and concurrency from 1 to 10,000 on each key. Default: 600 requests a minute per key, 50 in flight per account.

A budget per key

budget\_usd plus a daily, weekly or monthly spend limit. The key stops at its own line with a 402; the rest of the balance is untouched.

One request id

x-uplink-request-id on every answer, errors included. Quote it and we find the call.

Live

## API route, right now

From `GET https://api.relayswitch.io/v1/status`, the public feed behind [/status](https://relayswitch.io/status), generated 2026-11-02T10:05:34.759Z.

| Service | State | Last check | Latency | Checks today | Failures today |
| --- | --- | --- | --- | --- | --- |
| API | Operational | Nov 2, 2026, 9:07 AM UTC | 1277 ms | 10 | 0 |

Every hour the gateway counts the past hour’s real requests to this route: answered or failed. A request answered after a retry counts as answered.

The daily real-model check: 305 of 339 models answered as before, generated 2026-11-02T10:05:34.758Z. Every verdict is on [/proof](https://relayswitch.io/proof).

Live prices

## The ids this page is about, per million tokens

Four of the ids on this key, read from the catalog at render, with the developer’s list price beside ours where the catalog has it.

| Model | Input | Output | Developer list in / out |
| --- | --- | --- | --- |
| [Claude Sonnet 5.5](https://relayswitch.io/models/claude-sonnet-5-5)claude-sonnet-5-5 | $1.20 | $3.00 | $2.00 / $10.00 |
| [GPT-6.1 Sol](https://relayswitch.io/models/gpt-6.1-sol)gpt-6.1-sol | $0.60 | $3.00 | $2.00 / $10.00 |
| [DeepSeek V4.1 Flash](https://relayswitch.io/models/deepseek-v4.1-flash)deepseek-v4.1-flash | $0.06 | $0.18 | $0.30 / $1.20 |
| [GLM 5.3](https://relayswitch.io/models/glm-5.3)glm-5.3 | $0.3276 | $1.0296 | $1.092 / $3.432 |

Read from the catalog at render. A request that fails over bills at the price of the model that answered.

The switch

## OpenAI SDK: change base\_url, keep the client

python

1`from openai import OpenAI`

2`import os`

3

4`client = OpenAI(`

5 `base_url="https://api.relayswitch.io/v1",`

6 `api_key=os.environ["RELAYSWITCH_API_KEY"],`

7`)`

8

9`reply = client.chat.completions.create(`

10 `model="claude-sonnet-5-5",`

11 `messages=[{"role": "user", "content": "Continue the scene."}],`

12 `extra_body={"models": ["gpt-6.1-sol", "deepseek-v4.1-flash"]}, # tried in order if claude-sonnet-5-5 fails`

13`)`

14`print(reply.model) # the model that answered; billed at its own price`

Every OpenAI-compatible client takes a base URL and a key, so the switch is those two values. `models` is this API's fallback list, up to 5 ids tried in order; the answer names which one replied in `model`, and `x-uplink-attempts` says how many routes it took.

In SillyTavern or JanitorAI, pick the OpenAI-compatible or custom endpoint, paste the base URL and the key, and type the model id. The [roleplay page](https://relayswitch.io/roleplay) lists the uncensored builds on the same key.

Related

-   [OpenRouter alternative](https://relayswitch.io/alternatives/openrouter)
-   [Routing and fallbacks](https://relayswitch.io/features/routing)
-   [Key budgets and limits](https://relayswitch.io/features/key-budgets)
-   [Roleplay chat](https://relayswitch.io/roleplay)
-   [Models and prices](https://relayswitch.io/models)
-   [Live status](https://relayswitch.io/status)

Other errors

-   [Claude Code: API Error: Rate limit reached](https://relayswitch.io/fix/claude-code-rate-limit-reached)
-   [Gemini API 429 RESOURCE\_EXHAUSTED](https://relayswitch.io/fix/gemini-api-429-resource-exhausted)
-   [Anthropic 529 overloaded\_error](https://relayswitch.io/fix/anthropic-529-overloaded)
-   [OpenRouter: No endpoints found](https://relayswitch.io/fix/openrouter-no-endpoints-found)
-   [All fix guides](https://relayswitch.io/fix)

FAQs

## Questions

From what people ask about this error.

Open the console

A key in under a minute

[Get a key](https://app.relayswitch.io/console)

Or email [hello@relayswitch.io](mailto:hello@relayswitch.io)

### 

### 

### 

### 

## A key that does not stop at one host

Failover at the same price, limits and a budget per key, failed requests not charged. Card or crypto, no KYC, no subscription.

[Live status](https://relayswitch.io/status)[Get a key](https://app.relayswitch.io/console)

