Rowsmith
Fake test data (CSV, JSON, SQL) from a schema, a catalogue of invalid values with reasons, and a payment sandbox that never moves money. Free, no key.
Documentation
Rowsmith
Fake test data from a table schema, as CSV, JSON or SQL INSERTs. Free and rate-limited, with no account and no API key.
For fixtures, seed data, demos and CI. Send a schema, get rows back.
Quickstart (60 seconds)
1. Add Rowsmith to Claude Desktop, Cursor or another MCP client:
{"mcpServers":{"rowsmith":{"command":"npx","args":["-y","rowsmith-mcp"]}}}
2. Ask: Generate 20 orders with a fixed seed as CSV
3. Or call the API directly:
curl -s https://testdata-api.re-jam620.workers.dev/v1/generate -H 'content-type: application/json' \
-d '{"rows":20,"seed":42,"format":"csv","columns":[{"name":"order_id","type":"sequence","prefix":"ord_","pad":4},{"name":"email","type":"email"},{"name":"total_usd","type":"decimal","min":1,"max":500}]}'
curl -s 'https://testdata-api.re-jam620.workers.dev/v1/invalid?kind=email&count=5&seed=42'
ID=$(curl -s https://testdata-api.re-jam620.workers.dev/v1/sandbox -H 'content-type: application/json' -d '{"seed":42}' | sed -E 's/.*"id":"([^"]+)".*/\1/')
curl -s https://testdata-api.re-jam620.workers.dev/v1/sandbox/$ID/charges -H 'content-type: application/json' \
-d '{"amount":1999,"currency":"usd","card":"4242424242424242"}'
Python's standard-library urllib is blocked by Cloudflare before it reaches the API (403, error code 1010) when it sends its default User-Agent. Set your own, e.g. User-Agent: my-tests/1.0. In our tests on 2026-10-18, requests, httpx, aiohttp, Node and curl worked with their defaults.
- Free, rate-limited, no account, no API key.
- The same schema and seed give byte-identical output for the same generator version.
- An invalid-values catalogue with the reason each value is invalid.
- A payment sandbox that never moves money: a sandbox and everything in it is deleted 1 hour after it is created. It accepts only card numbers from Stripe's published testing list and stores no free text you send.
- Listed on the official MCP Registry as io.github.meiorz/rowsmith.
Try it
curl -s https://testdata-api.re-jam620.workers.dev/v1/generate \
-H 'content-type: application/json' \
-d '{"table":"orders","rows":3,"seed":42,"format":"csv","columns":[{"name":"order_id","type":"sequence","prefix":"ord_","pad":4},{"name":"email","type":"email"},{"name":"total_usd","type":"decimal","min":1,"max":500},{"name":"status","type":"enum","values":["paid","refunded","partially_refunded"],"weights":[8,1,1]}]}'
What comes back
order_id,email,total_usd,status
ord_0001,amara.weber561@mail.test,230.25,paid
ord_0002,maya.wang873@mail.test,17.04,paid
ord_0003,jin.weber19@mail.test,92.51,paid
That request, run now by the service itself. The same schema and seed give byte-identical output for the same generator version (generator 1, sfc32-splitmix32, sent as x-generator-version), so a CI run is reproducible.
Use it from an AI agent
The rowsmith-mcp server gives MCP clients a generate_test_data tool. It is listed on the official MCP Registry as io.github.meiorz/rowsmith.
{
"mcpServers": {
"rowsmith": { "command": "npx", "args": ["-y", "rowsmith-mcp"] }
}
}
For more than about 50 rows, the tool can write a file instead of putting the data in the model's context.
Column types
- uuid
- sequence
- integer
- decimal
- boolean
- enum
- date
- datetime
- first_name
- last_name
- full_name
- phone
- test_card
- ssn_invalid
- iban_invalid
- text
Options per type: /v1/types. Full request schema: /openapi.json.
What the data is
- Every value is generated by a program from a seed. No real person's data is used as input, and no record is derived from a real person.
- Identifiers come only from reserved or invalid ranges: example.com, example.org, example.net and.test email domains; 555-0100 to 555-0199 phone numbers; card numbers published for testing; SSN-shaped and IBAN-shaped values in ranges that can never be valid.
- A generated name can still match a real person's by chance.
- Send schemas only, never real data.
Limits
Up to 500 rows and 50 columns per call, with daily limits per caller (200) and overall. Over a limit you get HTTP 429 with Retry-After. The current limits are in /openapi.json.