# Gateway refusals

> The six typed refusals: who decides, which HTTP status, whether it recovers.


Refusals are answers. Only the caller's mistakes are 4xx; a domain's refusal is an answer with a body; an exhausted budget stays 200 because it does not recover with time.

| `error` | Who decides | HTTP (JSON shell) | Recovers |
|---|---|---|---|
| `not-found` | the domain | 200 | no, the question was wrong |
| `invalid-input` | the domain, before any query | 200 | no |
| `upstream-unavailable` | the domain: the Confederation did not answer or answered wrongly | 200 | maybe, state of the source |
| `upstream-busy` | the polite brake against the federal endpoint | 200 + `retry_after_ms` | yes, the weight is refunded |
| `budget-exhausted` | the gateway | 200 | no, new session |
| `rate-limited` | the gateway | 429 + `Retry-After` | yes, after `retry_after_ms` |

The one refusal with its own HTTP status:

```text
HTTP/1.1 429 Too Many Requests
Retry-After: 2

{"error": "rate-limited", "detail": "…", "retry_after_ms": 1500}
```

The values are an example, the shape is the gateway's.

---

Source: docs/en/reference/refusals.md
