📦 JSON API Mock Test Data Generator
Generate realistic mock JSON data arrays for frontend testing and prototyping. Includes User Profiles, Ecommerce Products, and Order schemas.
Generated Mock API JSON
What JSON API Mock Test Data Generator Does
This tool generates a JSON array of fake records for one of three fixed schemas — user profiles, ecommerce products, or orders — entirely in your browser. Pick a schema, set a record count from 1 to 50, and copy the array straight into a test file, a fixture, or a frontend you are building ahead of a real backend. Nothing is uploaded and no account is required.
The generator is seeded rather than truly random. It uses a small pseudo-random number generator called mulberry32, started from a numeric seed that begins at 1 and only changes when you click Regenerate. Because the seed is fixed on first load, the first array you see for a given schema and record count is identical every time you load the page — the same names, the same prices, the same dates, in the same order. This matters for a page built with static export: generating data with an unseeded source like Math.random() during render would make the server-built HTML and the client-hydrated HTML disagree, which is exactly the kind of mismatch React warns about when server and client output diverge. Seeding the generator instead of the clock or Math.random() removes that mismatch, and as a side effect gives you output you can reproduce on demand rather than a fresh random draw every time.
Typing a non-numeric value into the record count field, or a value outside 1–50, does not error. The field clamps to the nearest valid count and an unparseable value falls back to 5 records, so the array always renders something rather than breaking.
This is a different tool shape from a hosted mock server. Mockaroo, mockapi.io, Beeceptor, Retool and JSONPlaceholder all give you a URL your code can fetch over real HTTP. This tool gives you a static array to paste directly into your own code — there is no endpoint, no CORS to configure, and nothing to keep running. Use it when you want fixture data baked into a test or a documentation example; use a hosted mock server when you need something your frontend can actually call.
How to Use JSON API Mock Test Data Generator
- Select a schema template (Users, Products, or Orders)
- Specify the number of records to generate (1 to 50)
- Click Copy JSON Array to use in your mock API or unit tests
Formula Used by JSON API Mock Test Data Generator
Record count clamps to 1–50
n = min(50, max(1, isNaN(parseInt(input)) ? 5 : parseInt(input)))
- input
- The raw text typed into the Number of Records field
- n
- The record count actually generated
Worked example
Four values typed one after another into the same field: "0", "500", "abc", "17"
- parseInt("0") = 0 → max(1, 0) = 1 → min(50, 1) = 1
- parseInt("500") = 500 → max(1, 500) = 500 → min(50, 500) = 50
- parseInt("abc") = NaN → falls back to 5 → min(50, max(1, 5)) = 5
- parseInt("17") = 17 → max(1, 17) = 17 → min(50, 17) = 17
Result: "0" generates 1 record, "500" is capped at 50, "abc" defaults to 5 records, and "17" passes through unchanged. No input value can produce 0 records, more than 50, or an error.
Seeded generation with mulberry32
rand = mulberry32(seed × 2654435761); each field draws its value by calling rand() again
- seed
- Starts at 1 on page load; increases by 1 each time Regenerate is clicked
- 2654435761
- A fixed constant (0x9e3779b1) the component multiplies the seed by, so that consecutive seed values (1, 2, 3…) land on well-separated starting states instead of adjacent ones
- mulberry32
- A 32-bit pseudo-random function that returns the same sequence of floats every time it starts from the same input
Worked example
Default page state on first load: seed = 1, Users schema, 5 records
- rand = mulberry32(1 × 2654435761) = mulberry32(2654435761)
- Record 1 draws firstName, lastName, city, isActive and createdAt by calling rand() five times in sequence
- Because seed is always 1 on a fresh load, this exact sequence of rand() outputs is reproduced every time, on every device
Result: Record 1 is always { id: 1001, firstName: "Olivia", lastName: "Jones", email: "olivia.jones@example.com", city: "San Francisco", isActive: true, createdAt: "2025-09-20T01:45:15.809Z" } — verified by running the generation function twice with seed 1 and diffing the output, which is byte-for-byte identical both times.
Users Profile Schema — Field Reference
Every field the Users schema produces, with its exact generation logic, verified against the component source.
| Field | Type | Generation logic | Range / pool |
|---|---|---|---|
| id | integer | 1000 + record position | 1001–1050 |
| firstName | string | Random pick from a fixed pool | 10 names: Alex, Emma, Liam, Sophia, Noah, Olivia, Ethan, Ava, Mason, Isabella |
| lastName | string | Random pick from a fixed pool | 10 surnames: Smith, Johnson, Williams, Brown, Jones, Miller, Davis, Wilson, Anderson, Taylor |
| string | firstname.lastname@example.com, lowercased | Derived from firstName and lastName, not its own pool | |
| city | string | Random pick from a fixed pool | 8 cities: New York, San Francisco, London, Berlin, Tokyo, Toronto, Sydney, Paris |
| isActive | boolean | true when a random draw exceeds 0.2 | True for roughly 80% of records, false for the rest |
| createdAt | ISO 8601 timestamp | Fixed reference date minus a random offset of up to 10,000,000,000 ms | September 7, 2025 to January 1, 2026 — a roughly 116-day window |
Ecommerce Products Schema — Field Reference
Every field the Products schema produces.
| Field | Type | Generation logic | Range / pool |
|---|---|---|---|
| id | string | "prod_" + 2000 + record position | prod_2001–prod_2050 |
| title | string | Random pick from a fixed pool | 5 products: Wireless Noise-Canceling Headphones, Ergonomic Mechanical Keyboard, 4K Ultra HD Monitor, USB-C Fast Charging Hub, Smart Fitness Watch |
| price | number | Random value × 200 + 29.99, rounded to 2 decimals | $29.99 to $229.99 |
| rating | number | Random value × 1.5 + 3.5, rounded to 1 decimal | 3.5 to 5.0 |
| inStock | integer | Random value × 150, floored, + 5 | 5 to 154 units |
| category | string | Fixed literal on every record | Always "Electronics", regardless of the product title |
Orders & Invoices Schema — Field Reference
Every field the Orders schema produces.
| Field | Type | Generation logic | Range / pool |
|---|---|---|---|
| orderId | string | "ord_" + 5000 + record position | ord_5001–ord_5050 |
| customerId | integer | 1000 + a random value × 10, floored, + 1 | 1001 to 1010 |
| totalAmount | number | Random value × 350 + 49.99, rounded to 2 decimals | $49.99 to $399.99 |
| status | string | Random pick from 4 fixed values | Pending, Processing, Shipped, Delivered — each appears roughly 25% of the time |
| itemCount | integer | Random value × 4, floored, + 1 | 1 to 4 |
| orderDate | date (YYYY-MM-DD) | Fixed reference date minus a random offset of up to 5,000,000,000 ms | November 4, 2025 to January 1, 2026 — a roughly 58-day window |
A Copy-Paste Array vs. a Hosted Mock Endpoint
When this tool fits and when a hosted mock server is the right choice instead.
| This tool | A hosted mock server (Mockaroo, mockapi.io, Beeceptor, JSONPlaceholder) | |
|---|---|---|
| What you get | A JSON array you copy into your own code | A URL your code sends real HTTP requests to |
| Setup | None — pick a schema and a count | An account, a project, or a running server on most of them |
| Network calls in a test suite | None — the array is already inline | A live request every run, so CORS, latency and uptime all apply |
| Reproducibility | Same seed always returns the same array | A fresh random draw on every request unless the provider persists one dataset |
| Best for | Unit test fixtures, static docs examples, offline prototyping | A frontend that needs to exercise real GET/POST/PUT/DELETE calls |
How to Read Your Result
The same seed always gives the same array
Reloading the page, or opening it in a different browser, reproduces the identical first array for a given schema and record count, because the seed starts at 1 every time rather than being drawn from the clock. Clicking Regenerate advances the seed by 1 and produces a new array — still reproducible if you needed to get back to it, but only by tracking which click count you were on. There is no way to type in a specific seed value directly.
Orders do not reference Users
The Orders schema's customerId field is drawn independently from its own 1001–1010 range. It is not pulled from the id values the Users schema produces, and the two schemas are generated separately with no shared state. If you generate a Users array and an Orders array and try to join them by ID, the join will not reflect anything real — there is no relational integrity between the three schemas.
Every product is "Electronics"
The category field on the Products schema is a fixed string, not a generated value — every record gets "Electronics" no matter which of the 5 product titles was picked. A dataset that needs multiple categories will need that field edited after copying the array out.
Dates cluster inside a fixed historical window, not around today
createdAt and orderDate are computed by subtracting a random offset from a reference date hardcoded in the component as January 1, 2026, not from the current date. That means every generated timestamp falls inside a fixed window ending on that date — roughly the 116 days before it for Users, roughly the 58 days before it for Orders — and that window does not move forward as real time passes. If you need timestamps that look recent relative to today, generate them and then shift them programmatically after copying the array out.
Limitations & Accuracy Notes
- Only three schemas exist: user profiles, ecommerce products, and orders. There is no field editor, no way to add or remove a field, and no way to define your own schema.
- Record count is capped at 50 per generation. Larger fixture sets need multiple generations pasted together, or a different tool.
- Output is JSON only. There is no CSV, SQL, or spreadsheet export — copy the JSON array and convert it elsewhere if you need another format.
- No locale or internationalization options. Names are drawn from a single pool of 10 first names and 10 surnames, cities from a fixed pool of 8, and every date and currency value is presented in ISO 8601 / plain USD-style decimal notation regardless of locale.
- The three schemas do not reference each other. An Orders record's customerId is not tied to any id produced by the Users schema — treat each generated array as standalone, not as a relational dataset.
- Everything runs client-side in your browser. Nothing is uploaded, logged, or stored, which also means there is no server-side persistence or shareable link to a generated dataset — copy the array before you navigate away.
- The reference date behind createdAt and orderDate is fixed in the code rather than computed from the current date, so generated timestamps always fall inside the fixed historical windows described above, not around whatever "today" happens to be when you use the tool.
Frequently Asked Questions
What schemas can I generate?
How many records can I generate at once?
Is the generated data safe to use?
Will the same data be generated twice?
Does it produce realistic edge cases?
Can I use this data in a demo?
How much data can I generate?
Is anything sent to a server?
References & Further Reading
- MDN Web Docs — Math.random() — Confirms Math.random() is not seedable, which is why a separate seeded generator (mulberry32) is used instead to get reproducible output
- React documentation — hydrateRoot, handling different client and server content — Official explanation of why server-rendered and client-rendered output must match, and what happens when data generated during render differs between the two