Whole synthetic records for QA, staging and CI: name, company, address, email and phone, reproducible from a seed.
Name, company, address, email and phone, generated together and consistent with each other — a Quebec record gets a French-form address and a name that reads naturally alongside it.
Everything runs on the same seeded generator as the address tool, so a record set is reproducible from its seed.
These are not settings. They are constraints on what the tool is, and they are the reason it is safe to paste output into a ticket or commit it to a repository.
The point of a seed is that a fixture stops being a snapshot and becomes a recipe. Instead of committing five hundred records, commit the seed and the options that produced them.
A record set is identified by three things: the seed, the options, and the data version. Same three, same records, permanently. Every export and every API response carries all three.
// Instead of a 500-record JSON fixture in your repository:
const FIXTURE = { seed: 20260904, province: "ON", count: 500, dataVersion: 1 };
beforeAll(async () => {
const res = await fetch(`/api/v1/addresses?province=${FIXTURE.province}` +
`&count=100&seed=${FIXTURE.seed}`);
const { data, meta } = await res.json();
// If this ever fails, the generator data changed — that is the explanation
// for records differing, and the reason to pin it.
expect(meta.dataVersion).toBe(FIXTURE.dataVersion);
records = data;
});
A seed selects a path through the generator’s data. Change the data — add a city, correct a postal district, extend the street vocabulary — and the same seed lands somewhere else.
That is not a bug, it is unavoidable, and the only honest response is to make it visible. Assert on the data version in your fixture setup and a change announces itself as a clear failure rather than as a diff you have to explain.
| Field | Example | Notes |
|---|---|---|
| name | Priya Sandhu | Given and family names drawn independently; never a real person |
| company | Northwind Logistics Inc. | Optional; French suffixes for Quebec records |
| addressLine1 | 100-1234 Yonge St W | Unit-hyphen-civic, or a rural or PO box form |
| addressType | civic | civic, rural, poBox or generalDelivery |
| locality | Toronto | Real municipality, mapped to its real region |
| province / provinceType | ON / province | Branch on provinceType rather than a list of three codes |
| postalCode | M5V 3L9 | String, always. Valid first letter for the region |
| p.sandhu@example.com | Reserved domains only | |
| phone | 555-0142 | Reserved range only |
No, and the tool will not be extended to provide them. For payment testing, use the test card numbers your payment provider publishes — they are designed for it and are safe in a way a generated number is not.
They are in the 555-01XX range, which is reserved for fictional use and not allocated to subscribers, so they do not reach anyone. That is why the range is the only one used.
Yes — the data is synthetic and represents no one. Better still, commit the seed and the options instead of the records, and regenerate. A recipe stays small and stays honest about where the data came from.
Almost certainly because the data version changed. Compare the dataVersion in your stored response with the current one. If they match and the records differ, that is a bug worth reporting.
No. Given names and family names are drawn independently from separate pools, so a full name is a combination rather than a person. Any resemblance to a specific individual is coincidence.
Everything this site generates is synthetic, produced for development, QA, testing, demos and staging. The records do not represent real people, and the addresses are not verified deliverable addresses.