For testing error handling and resilience

A mock API that fails on purpose

Static mock APIs like JSONPlaceholder only ever return the happy path, so your retry, backoff, and timeout code goes untested until it breaks in production. ReqRes serves 15 deliberate failures on demand, plus scripted multi-step outages. Deterministic, so a flaky failure is finally reproducible.

Free tier is open, no signup. Three failure scenarios are free; all 15 plus scripted chains are on a paid plan. Full tour at reqres.in/agents.

You can't test error handling against data that never errors.

Most mock APIs are fixtures: they return the same 200 OK forever. That is fine for building a happy-path UI, but it means the code that actually matters when things go wrong, your retries, your exponential backoff, your timeout budgets, your error boundaries, your 429 handling, never runs until a real outage triggers it in front of a real user.

ReqRes gives you failure as a first-class input. Ask for a 429, a truncated JSON body, a gateway timeout, or a five-step degrading outage, and you get exactly that, on demand, the same way every time. Point your integration tests at it and the unhappy paths finally get exercised.

Make it fail right now

No signup, no key. Paste this into your terminal to get a real 429 with a Retry-After header:

curl -i https://reqres.in/agent/v1/scenarios/rate-limited

Or the cruellest bug to catch, a 200 OK whose JSON body is truncated mid-object:

curl -i https://reqres.in/agent/v1/scenarios/malformed-json

Every deliberate failure carries X-Agent-Sandbox-Intentional: <name>. Tell your error reporter (Sentry, Bugsnag) to ignore responses with that header so your test failures never pollute your alert queue.

Fifteen failures you can call on demand

Every scenario is a real HTTP response, not a description of one. Free tier unlocks rate-limited, validation-error, and malformed-json; the rest are on a paid plan.

Scenario Status What it exercises
rate-limited429Throttling with a Retry-After header. Your backoff logic.
server-error500Generic 5xx. Your retry path.
bad-gateway502Upstream returned garbage. Fallback and backoff.
timeout504Gateway timeout. Your timeout budget.
slow200Returns a simulated-delay header. Client-side timeouts without the wait.
validation-error422Multi-field failure with a field_errors object.
unauthorized401Missing or invalid token, with WWW-Authenticate.
forbidden403Authenticated but missing scope.
not-found404Not found with a "Did you mean?" hint.
conflict409Optimistic-concurrency clash with current and your versions.
too-large413Payload over the max size, with max_bytes.
partial-content206Partial response with Content-Range. Range handling.
redirect-loop302A 3-hop redirect chain. Your follow-redirect cap.
malformed-json200200 OK with a truncated JSON body. Your parser's error path.
empty-response200200 OK, Content-Length 0, no body.

Programmatic list: GET /agent/v1/scenarios returns the same catalog as JSON.

Real outages are sequences, not single errors

A single 500 is easy. What breaks systems is the pattern: fine, fine, throttled, throttled, timeout, recover. Send an X-Agent-Chain header and each call walks one step through a scripted sequence. Deterministic per call count, so the step that fails your test fails it every time.

flaky-then-recover

Intermittent failures that resolve. Proves your retries actually recover instead of giving up.

rate-limit-storm

Sustained 429s. Proves your backoff widens and honours Retry-After.

degrading-upstream

Latency climbs until it tips into errors. Proves your timeouts and circuit breaker trip in time.

auth-expiry-mid-session

A token that expires partway through. Proves your refresh-and-replay works under load.

Five presets, or define your own with POST /agent/v1/chains. Reset a chain's position with DELETE /agent/v1/chains/<name>/state.

Why not just a static mock?

Need Static mock (JSONPlaceholder, fixtures) ReqRes
Trigger a 429 / 500 / timeoutHand-roll and maintain it yourselfOne URL, on demand
Malformed / truncated bodyNot possible/scenarios/malformed-json
Multi-step outageNot possibleScripted chains
Reproducible in CIDepends on your setupDeterministic, pinnable world version
Servers to runYours to hostNone, or self-host the Docker image

Start testing the unhappy paths

The first three scenarios are free and need no signup. Unlock all 15 plus scripted chains and trajectory logs on a paid plan.