How to generate mock json for api development and prototyping
- Step 1Decide which endpoint shape you are mocking — The generator fits a person/user collection. If your endpoint returns users, you can use the output nearly as-is; for other resources, plan to rename and trim fields after generating.
- Step 2Choose id style to match your routing — For json-server's path routing (
GET /users/1), turn Sequential IDs on so ids are integers. For a UUID-keyed API, leave it off. Set this before locking the seed. - Step 3Set count and seed — Use 1 for a detail endpoint, 10–50 for a list. Pick a seed (default
42) and keep it fixed so the mock collection is reproducible. Free plan caps at 500 records, Pro at 10,000. - Step 4Generate and download — Click Generate Mock Data. Output is pretty-printed JSON. Download
mock-data-<count>.jsonor Copy straight into your mock setup. - Step 5Wire into json-server or MSW — For json-server, place the array under a resource key in
db.json({ "users": [ ...generated ] }) and runnpx json-server db.json. For MSW, return the array from a handler:http.get('/users', () => HttpResponse.json(users)). - Step 6Swap to the real API when ready — Remove the MSW handler or repoint the base URL. If the real contract differs from the fixed shape, you will already have aligned field names via json-key-renamer — keep that reshape step in a small script so it is repeatable.
Mock setups and which id mode they want
How the generated array slots into common front-end mocking tools.
| Tool | How the array is used | Recommended id mode |
|---|---|---|
| json-server | Array under a resource key in db.json; gives REST routes automatically | Sequential IDs ON (integer path params) |
| MSW | Returned from http.get handler via HttpResponse.json() | Either — match your real API's id type |
| Vite/CRA static import | import users from './users.json' used directly in a hook | Either |
| Mirage JS | Seed the in-memory DB from the array | Sequential IDs ON if Mirage expects numeric ids |
| Plain fetch stub | Promise.resolve(users) in a dev-only branch | Either |
What you build by hand vs what the generator gives
The generator produces the record array. Envelope, paging, and error shapes are yours to wrap around it.
| Need | From generator? | How to get it |
|---|---|---|
| List of records | Yes | Set count, generate the array |
| Single record (detail) | Yes | Count 1, or take array[0] |
Pagination envelope (data, total, page) | No | Wrap the array manually: { data: users, total: 250, page: 1 } |
| Error response (4xx/5xx) | No | Author by hand — the generator only emits success records |
| Custom resource fields | No | Reshape with json-key-renamer / json-key-filter |
| Nested relations | Partial | Only the built-in address sub-object; add relations manually |
Cookbook
Recipes for standing up a deterministic mock API from the generated array.
json-server db.json with integer ids
ExampleWith Sequential IDs on, json-server's path routing works immediately because ids are integers.
// Generated: count 25, seed 42, Sequential IDs ON → paste under 'users'
// db.json
{
"users": [
{ "id": 1, "index": 1, "name": "Grace Davis", "email": "grace.davis@mock.dev", "status": "pending", ... },
{ "id": 2, "index": 2, "name": "Frank Wilson", "email": "frank.wilson@sample.io", "status": "suspended", ... }
]
}
// $ npx json-server db.json
// GET /users → the full array
// GET /users/1 → Grace's record (path routing by integer id)MSW handler returning a stable collection
ExampleThe seed keeps the mocked response identical across reloads, so component tests against MSW do not flake on data order.
import { http, HttpResponse } from 'msw';
import users from './users.json'; // count 20, seed 42
export const handlers = [
http.get('/api/users', () => HttpResponse.json(users)),
http.get('/api/users/:id', ({ params }) =>
HttpResponse.json(users.find(u => String(u.id) === params.id))
),
];Wrap the array in a pagination envelope
ExampleThe generator gives the records; the envelope is yours. Build the contract shape around the array by hand.
import users from './users.json'; // count 50, seed 42
const page1 = {
data: users.slice(0, 10),
pagination: { page: 1, perPage: 10, total: users.length }
};
// http.get('/api/users', () => HttpResponse.json(page1))Rename fields to match a snake_case contract
ExampleIf the real API uses snake_case, align the mock now so the swap-over needs no front-end changes.
Step 1 — generate count 30, seed 42 here.
Step 2 — json-key-renamer:
name → full_name
createdAt → created_at
active → is_active
Result per record:
{ "id": 1, "full_name": "Grace Davis", "created_at": "2024-01-17", "is_active": false, ... }Detail endpoint from a single record
ExampleFor GET /users/:id mocks, generate one record (or slice the first from a larger array).
// Generated: count 1, seed 99
const user = {
id: 1, name: "Alice Smith", email: "alice.smith@mock.dev",
status: "active", score: 97.8, address: { city: "Capitol City" }
};
// http.get('/api/users/1', () => HttpResponse.json(user))Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
You pointed it at your OpenAPI spec
Not supportedThe generator does not read OpenAPI, JSON Schema, or an example object. It emits the fixed person shape and ignores any input. Generate the base array and reshape it to your contract with json-key-renamer and json-key-filter.
Front-end expected a { data, total, page } envelope
Build by handThe generator emits a bare array, not a paginated envelope. Wrap it yourself: { data: users.slice(0, 10), total: users.length, page: 1 }. The generator's job is the record list; the response shape is yours.
json-server GET /users/abc-uuid returned nothing
Id type mismatchjson-server path routing keys on the id field. If you generated UUID ids but request an integer path (or vice versa), the lookup misses. Match the id mode to your routing: Sequential IDs on for integer paths, off for UUID paths.
Need a 404 / 500 error response
Not generatedThe generator only emits success records. Author error bodies by hand in your MSW handler or json-server middleware — e.g. HttpResponse.json({ error: 'Not found' }, { status: 404 }). There is no error-shape mode.
Real API returned camelCase but mocks were snake_case (or vice versa)
Reshape upstreamDecide the casing once and align the mock to the real contract before you build against it. Run the generated array through json-key-renamer so the field names match — then swapping in the real API needs no front-end changes.
Duplicate emails across a large collection
ExpectedEmails derive from a 100-combination name pool plus 5 domains, so collections over ~100 records will contain duplicate emails. If your mocked endpoint enforces unique emails, keep the count small or de-duplicate the array before serving.
Toggling Sequential IDs reshuffled the whole dataset
By designThe id mode shifts the random stream, so the non-id fields change too at the same seed. Lock your id mode before committing to a seed, otherwise a teammate who flips it gets different mock data.
Free plan blocked a 750-record list
Plan limitFree caps at 500 records. For prototyping you rarely need more — paginate the array client-side instead. Pro raises the cap to 10,000 if you genuinely need a large mock collection.
Wanted nested related resources (orders inside a user)
PartialThe only nesting the generator produces is the built-in address object. It cannot generate related collections (a user's orders, a post's comments). Generate each resource separately and stitch the relations by hand or in json-server's relationship config.
Frequently asked questions
Can it generate responses from my OpenAPI / contract?
No. The generator emits a fixed person-record shape and ignores any spec or example you provide. It is a strong stand-in for a /users collection; for other contracts, generate the base array and reshape it with json-key-renamer and json-key-filter, then wrap it in your envelope by hand.
How do I get json-server routing to work?
Turn on Sequential IDs so the id field is an integer, place the array under a resource key in db.json ({ "users": [...] }), and run npx json-server db.json. You then get GET /users and GET /users/1 automatically. If your real API uses UUID ids, leave Sequential IDs off and request UUID paths instead.
Will the mock data stay the same across reloads?
Yes, as long as the seed and count are unchanged. The generator is deterministic, so a committed db.json or MSW fixture returns the identical collection every reload and on every machine — no flaky ordering, stable screenshots, repeatable tests.
How do I add pagination metadata?
Build it around the array yourself. Slice the generated records and wrap them: { data: users.slice(0,10), total: users.length, page: 1 }. The generator produces the record list; the pagination envelope is part of your contract, not the data.
Can it produce error responses?
No — it only emits success records. Author 4xx/5xx bodies in your mock layer, e.g. HttpResponse.json({ error: 'Not found' }, { status: 404 }) in MSW. Pair real success records from the generator with hand-written error shapes.
How do I keep mocks in sync as the contract evolves?
Keep the reshape (rename/filter) as a small repeatable step: generate the base array at a fixed seed, then run it through json-key-renamer with your current field mapping. When the contract changes, update the mapping and regenerate — the deterministic source plus a scripted reshape keeps it cheap.
Are the emails and phone numbers safe in a dev environment?
Yes. Emails use non-routable test domains and phones are always in the reserved +1-555 range, so mock data can never trigger a real email or SMS during front-end testing. Note emails repeat at large counts, so do not rely on uniqueness.
How many records can I generate for a list endpoint?
Up to 500 on free and 10,000 on Pro. For prototyping, generate a few dozen and paginate client-side. The hard internal ceiling is 100,000 records.
Can I generate related resources like a user's orders?
Not as relations. The only nesting is the built-in address object. Generate each resource as its own array and link them manually (matching ids) or via json-server's relationship configuration.
Can I turn the mock into TypeScript types or a schema?
Yes — paste a record into json-to-typescript for an interface to type your fetch layer, or into json-schema-generator for a JSON Schema. Validate edited mocks with json-validator.
Is the output minified for a compact db.json?
No — it is always 2-space pretty-printed. Run it through json-minifier if you want a compact db.json. The pretty form is usually easier to scan during development.
Does my contract or prototype data get uploaded?
No. Generation is fully browser-local. The tool ignores input and never sends generated data to JAD Apps servers. Only an anonymous usage counter is recorded for signed-in dashboard stats.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.