API Response Mock Generator
Generate mock API response JSON from your fields and response shape
Working…
0.0
It hasn't frozen — the result will appear when the calculation finishes.
About API Response Mock Generator
Front-end work rarely waits for the back end. When the API does not exist yet, or when it exists but you cannot easily make it return an empty list, the last page, or a 422, you build against fake responses. This generator takes a list of fields plus an envelope shape and prints a response in that shape. Six envelopes are available: a bare array, a data wrapper, a paginated response with meta and links, a single resource, JSON:API, and an error body.
Give it a seed and a small PRNG (mulberry32) draws values in the same order every time, so the same seed always produces the same response. Dates are generated relative to a fixed anchor, 2024-01-01 UTC, within the five years before it (2019 to 2023), rather than relative to today. That keeps snapshot tests stable. Dates only go backwards, so a “signed up on” field never lands in the future, but a view that filters on “the last 7 days” relative to today will find nothing.
What a mock can prove, and what it cannot
A mock answers one question well: does my UI behave correctly when it receives data shaped like this? Does the spinner stop, does the Next button disable when links.next is null, does a 40-character name wrap instead of breaking the card?
It cannot tell you whether the real server actually sends that shape. A mock is the API you imagined. If the back-end team renames user_name to username, every test built on your mock keeps passing while production breaks. Contract testing exists to close that gap. The Pact documentation describes it as checking each application in isolation to ensure the messages it sends or receives conform to a shared understanding documented in a contract. In Pact’s consumer-driven flow, the contract file is produced while the consumer’s tests run, and the provider later replays those interactions against its real code.
In practice teams use both. Mocks like these are for building screens quickly and reproducing edge states on demand. Contract tests, or validation against an OpenAPI schema, are what catch drift between client and server before a release. It helps to say explicitly that output from this tool is an illustrative example, not the contract.
How the pagination numbers are derived
total_pages is total divided by per_page, rounded up, and never less than 1. The number of items actually placed on the current page is total − (page − 1) × per_page, clamped between 0 and per_page. The id field is a collection-wide sequence, so page 3 at ten per page starts at id 21, which is what a real offset-based API would return.
Setting total to 0 gives an empty data array with total_pages of 1, which is handy for designing the “no results” state. Asking for a page beyond the last one gives an empty array with next set to null. Real APIs disagree on that case: some return an empty page, others return 404. Check which behavior your server has before you build error handling around it.
Links follow the page/per_page query style (…/users?page=2&per_page=10). If your API uses cursor pagination, the meta and links blocks here will not match it, and you should treat only the data array as reusable.
Error bodies have a real standard
The error envelope produced here is { error: { status, code, message, request_id } }, with a details array added for 422. That layout is common, but it is a convention, not a standard. The standard for HTTP API errors is RFC 9457, Problem Details: it uses the media type application/problem+json and the members type, title, status, detail, and instance, and a missing type is treated as about:blank. If the service you are integrating with follows RFC 9457, rename the keys so your error-handling code is tested against the right shape.
One naming detail: RFC 9110 renamed status 422 to “Unprocessable Content” (it used to be Unprocessable Entity), and this tool prints the new name. Clients are not supposed to interpret reason phrases, so a server that still sends the old one breaks nothing, but it is worth knowing if you compare output against a spec. The code value in the error body (unprocessable_entity) is an API-specific convention string, so it is left as is.
What changes in JSON:API mode
In JSON:API mode each record becomes { type, id, attributes }. Your id field is pulled out of attributes and emitted as a string, because the specification requires resource identifiers to be strings. The top level carries jsonapi.version set to 1.1, plus meta and links. Relationships and included resources are not generated, so if your screen renders related data you will need to add those blocks by hand.
Worked examples
Page 3 of 23 items, 10 per page, seed 42
- Input
Style: paginated / fields: id (id), name (fullName), status (pick: active,pending) / total 23, page 3, per_page 10, resource users- Output
data: 3 items (ids 21, 22, 23 — Noah Hernandez, Emma Jones, Michael Anderson); meta: {"page":3,"per_page":10,"total":23,"total_pages":3,"count":3}; links.prev: .../users?page=2&per_page=10; links.next: null
23 ÷ 10 rounds up to 3 pages, and only 3 items remain on the last one. Because next is null, this response is a direct test for a disabled Next button. Re-run with seed 42 and the names come back identical.
A 422 with the HTTP head included
- Input
Style: error / status 422 / include HTTP status line and headers / seed 7- Output
HTTP/1.1 422 Unprocessable Content Content-Type: application/json; charset=utf-8 ... {"error":{"status":422,"code":"unprocessable_entity","message":"The request was well-formed but contains semantic errors.","request_id":"9ed02560-...","details":[{"field":"id","issue":"is invalid"}]}}
details[0].field is a non-id field from your schema, picked by the seed, and issue matches its type (an email field gets must be a valid email address). With only an id field, as here, you get id and is invalid. The error style only offers 4xx and 5xx status codes. If you are testing inline form validation, make field the name of a real input so the error lands next to the right control.
How to use it
- Add resource fields and pick a type for each. integer and float take “min,max”; pick takes a comma-separated list of options.
- Choose the envelope style and set total, page, and per_page. For the error style, choose a status code and optionally a message.
- Enter a seed if you need the same output again, and switch on the HTTP head if your fixture needs it.
- Copy the result into your mock server (MSW, json-server, and so on) or a test fixture file.
Frequently asked questions
Is testing against mocks enough?
For UI behavior, usually yes. For compatibility with the real server, no: a mock keeps passing after the server changes its format. Add contract tests or schema validation for that.
If I choose 204, is the body empty?
Yes. Under RFC 9110 a 204 (or 304) response ends at the empty line after the header fields, so no body is generated whichever style you picked. With the HTTP head option on you get only the status line and headers (without Content-Type, since there is no body); with it off the output is empty.
Where do avatar URLs point?
To i.pravatar.cc, an external service. Rendering them makes network requests to that host, so swap in local image paths for offline tests or CI environments that block outbound traffic.
How large can a response be?
total is capped at 10,000 and per_page at 1,000. In paginated style only the items on the requested page are generated.
Why is my error body not application/problem+json?
The tool uses a common custom error shape with Content-Type application/json. If your API follows RFC 9457, change the media type and key names to match.
Sources
- Pact Docs — Introduction (contract testing)
- RFC 9457 — Problem Details for HTTP APIs
- RFC 9110 — HTTP Semantics (204, 422)
- JSON:API v1.1 specification
Last reviewed: