Generate seeded rows of sample data from a JSON Schema, Zod or Pydantic model — names, emails, addresses, Luhn-valid cards, IBANs, ISBNs — as JSON, CSV or SQL.
How it works
Paste a JSON Schema, Zod or Pydantic model and the batch appears beside it, rebuilt as you type. Every row is a function of the seed, the schema and the settings beside them, and nothing else, so the same seed gives the same batch byte for byte, including from a shared link. The dice draws a new seed; Rows goes up to 1,000.
A schema says a field is a string, not that it is a surname, so the page reads the schema's format first, then the property name, then the type. fullName, first_name and FIRST-NAME get names; email an address; postcode a postcode for the locale; cardNumber a Luhn-valid number with a real issuer prefix; iban an IBAN whose check digits hold. A name never overrides the type: an email declared as a number gets a number.
Rows satisfy their schema: enums, lengths, bounds, oneOf, not, if, contains and property counts are honoured, and a string is drawn from its pattern. Anything unmet is listed above the panes. Optional fields can be Always filled, Sometimes, or Left out.
The locale sets names, cities, postcodes, phone numbers and bank details, for seven countries, Japan among them, where names come family name first; a UK postcode is a real district with letters Royal Mail allows. Hosts, URLs and email addresses sit under example.com, example.net, example.org, .example and .test, and IP addresses in the documentation ranges. Phone numbers use the drama ranges regulators keep in the US, the UK, Germany and France; Spain, Italy and Japan keep none, so theirs start with digits their numbering plan gives no service, which a strict validator rejects.
Output is JSON, NDJSON, CSV or SQL, to copy or save as a file named after the rows. CSV and SQL give a nested object a column per leaf, address.city in CSV and address_city in SQL, and keep a list whole as JSON text.
Examples
Two customers from a JSON Schema
{
"title": "Customer",
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"fullName": { "type": "string" },
"email": { "type": "string" },
"reference": { "type": "string", "pattern": "^[A-Z]{3}-[0-9]{6}$" },
"balance": { "type": "number", "minimum": 0, "maximum": 500, "multipleOf": 0.01 },
"address": {
"type": "object",
"properties": { "city": { "type": "string" }, "postcode": { "type": "string" } },
"required": ["city", "postcode"]
}
},
"required": ["id", "fullName", "email", "reference", "balance", "address"]
}
With seed utils, 2 rows and the United Kingdom locale:
[
{
"id": "40547d4e-1e45-4db3-876b-07ec714de539",
"fullName": "William Hughes",
"email": "[email protected]",
"reference": "ZTD-446969",
"balance": 283.25,
"address": {
"city": "Oxford",
"postcode": "EH10 1LY"
}
},
{
"id": "950f8f48-f195-4413-8d53-9b19d4974d34",
"fullName": "Charlie Young",
"email": "[email protected]",
"reference": "URV-398129",
"balance": 459.79,
"address": {
"city": "Glasgow",
"postcode": "SE1 6SE"
}
}
]
The same batch as SQL
INSERT INTO "customer" ("id", "full_name", "email", "reference", "balance", "address_city", "address_postcode") VALUES ('40547d4e-1e45-4db3-876b-07ec714de539', 'William Hughes', '[email protected]', 'ZTD-446969', 283.25, 'Oxford', 'EH10 1LY');
INSERT INTO "customer" ("id", "full_name", "email", "reference", "balance", "address_city", "address_postcode") VALUES ('950f8f48-f195-4413-8d53-9b19d4974d34', 'Charlie Young', '[email protected]', 'URV-398129', 459.79, 'Glasgow', 'SE1 6SE');
The table is named after the schema's title, the columns are snake_case and double-quoted, so a column called order cannot break the statement. There is no CREATE TABLE.
Checking a number
Check mode takes a payment card, an IBAN, an ISBN, an EAN or UPC barcode or an IMEI, ignoring spaces and hyphens, and offers every format the value could be:
| Number | Result |
|---|---|
4111 1111 1111 1112 | Payment card, Visa: fails; 1 is the check digit that would hold |
GB82 WEST 1234 5698 7654 33 | IBAN, United Kingdom: fails; its check digits are the 82 after GB, where 55 would hold |
378282246310005 | Payment card, American Express: valid. IMEI: also valid |
978-0-306-40615-7 | ISBN-13 and EAN-13 barcode: both valid |
Common problems
A value that ignores its pattern
A pattern is drawn from if it uses the syntax people usually write: literals, classes, groups, alternation and counted repeats. A backreference, a lookaround or a word boundary cannot be generated from, so ^(a)\1$ gives the note “The pattern ^(a)\1$ is not one this page can generate from, so those values are ordinary text.”, and those rows will fail that pattern.
A timestamp in the future
Dates come from a window around 1 January 2025 rather than from today, so a batch is the same whenever it is opened. A name that says when keeps its range under any format: createdAt and updatedAt fall in the five years before, expiresAt in the five after, and birthDate 18 to 80 years before; format: date-time or date only decides how it is written. A name such as timestamp lands anywhere five years either side.
Empty cells in the CSV
With Optional fields on Sometimes, an optional key is in some rows and not others. Every key any row has gets a column, and CSV cannot tell an absent key from a null, so both are an empty cell rather than the word null. SQL writes NULL.
Frequently asked questions
Is the same seed always the same data?
Yes, with the same schema and settings. Each row is drawn from its own stream keyed by the seed and its position, so going from 10 rows to 50 leaves the first ten as they were. The generator is not cryptographic, and the UUIDs repeat with the seed; for fresh random ones use the UUID generator.
Are the card numbers real cards?
No. They pass the Luhn check and start with a prefix a real network uses, so a library that checks the format accepts them, but no account stands behind them. For a payment provider's sandbox, use the test numbers that provider publishes.
What if the root of the schema is an array?
Then each row is one element of it: a schema for a list of customers produces customers, not lists. The SQL table and the saved file are named after the element's title or model.