Same resources, same field names, same nested routes. The migration is one string in your code. What you get for it is the thing JSONPlaceholder cannot do: ask for the failure you are trying to test against.
- fetch('https://jsonplaceholder.typicode.com/posts') + fetch('https://flakyapi.dev/v1/posts')
Two differences in that line: the host, and a /v1 prefix. The
prefix exists so the API can change later without breaking the URLs you
have already published — the exact problem JSONPlaceholder has, having
never versioned.
A find-and-replace across a project is usually enough:
sed -i '' 's|jsonplaceholder.typicode.com/|flakyapi.dev/v1/|g' src/**/*.js
Every shared resource returns the same field names, so nothing downstream of the fetch has to change — not your types, not your components, not your tests.
| Resource | Fields | JSONPlaceholder | flaky |
|---|---|---|---|
| posts | id, userId, title, body | 100 | 100 |
| comments | id, postId, name, email, body | 500 | 500 |
| albums | id, userId, title | 100 | 100 |
| photos | id, albumId, title, url, thumbnailUrl | 5,000 | 1,000 |
| todos | id, userId, title, completed | 200 | 200 |
| users | id, name, username, email, address, phone, website, company | 10 | 10 |
| products | id, title, price, rating, stock, brand, category… | — | 100 |
Nested routes work the same way — /v1/posts/1/comments,
/v1/albums/1/photos, /v1/users/1/todos — and so
does filtering by any field, /v1/todos?userId=3&completed=true.
Paging accepts both styles. _start and _limit, the
json-server form JSONPlaceholder uses, work unchanged; _page and
_limit also work if you prefer pages. So do _sort
and _order.
Coming from DummyJSON instead? ?select=title,price works here too,
spelled either way — _select is the house style and bare
select is accepted so a pasted URL does not silently return an
empty array.
The dataset ships inside the Worker so a list request is an array slice rather than a database read. Five thousand photo rows would be two thirds of the bundle for a resource almost nobody paginates past the first page of. If you genuinely need 5,000, say so and it can go up.
1,000 requests a day anonymously — enough for development, and no signup.
A free key raises it to 10,000 and takes one request
with no confirmation email. JSONPlaceholder publishes no limit at all,
which sounds better until you need to know whether you are near one:
every response here carries x-ratelimit-remaining.
POST, PUT, PATCH and
DELETE are echoed and not stored, exactly as on
JSONPlaceholder. The difference is the response carries
x-mock-write: not-persisted, so nobody loses an afternoon
discovering it. When you need writes that stick, take a sandbox.
_param is an error
JSONPlaceholder treats ?_typo=1 as a filter on a field
named _typo, matches nothing, and returns [].
Here it returns a 400 naming the parameters that exist. An
empty array that means "you made a typo" costs more time than an error.
Every fake API hands you data. A couple will slow a response down —
DummyJSON takes a ?delay= — but none of them let you ask for the
part that actually finds bugs: a specific failure, and an
intermittent one. That is normally a local mock server, a branch in
your code, or a setTimeout you have to remember to delete.
# your loading state, with a real slow response GET /v1/posts?_delay=3000 # your error boundary, with a real 503 GET /v1/posts?_status=503 # your retry logic, failing one request in three GET /v1/posts?_fail_rate=0.3 # slow and unreliable at once, because that is what production is GET /v1/products?_delay=1500&_fail_rate=0.2
It works on every endpoint, including nested routes. No install, no config, no branch in your code that has to be removed before you ship — and it works from a browser console, a CodePen, or a colleague's machine with nothing set up.
Out-of-range values are rejected rather than ignored:
?_status=999 returns a 400, not a silent
200. A tool for testing failures should not fail quietly itself.
Paste either of these into a terminal — nothing to sign up for.
curl 'https://flakyapi.dev/v1/posts?_limit=2' curl -i 'https://flakyapi.dev/v1/posts?_status=503'
Or use the live inspector on the home page, which lets you set the delay, status and failure rate and watch the response change.
There is also an OpenAPI 3.1 spec — import it into Postman or Insomnia and every endpoint, including the chaos parameters, arrives already described. JSONPlaceholder does not publish one.