Table of Contents

Person

Generates a person, with names, a sex, a date of birth, a US race and ethnicity, and text values built from them.

Use it for a row that represents a person, such as a customer, an employee or a patient. Every mapped sub-field in a row describes the same person:

  • The first name and middle names match the row's sex. In a country whose surnames have separate male and female forms, lastName has the form that matches it too.
  • race and ethnicity are generated from the row's own first name and last name.
  • Every name in a row is from the same country, also when countries contains more than one.
  • custom, derivedId and derivedId2 are built from the row's other values.

Separate Name and Date fields are generated independently of each other, so none of this applies to them. Use Name for a column that contains a name on its own.

Sub-fields: at least one must be mapped. See Sub-fields.

Every JSON block on this page is a single field object, one entry in a table's fields array. See Building a Request for the full request structure.

Sub-fields

A Person field has eleven sub-fields. Only the mapped sub-fields are generated, and at least one must be mapped.

Sub-field Example value Description
custom Hindle, Revel - DOB 1986-01-19 (Male) A text value built from the row's other sub-fields by customFormat. See customFormat.
derivedId X-1986-1901-HINDL-5342 An identifier built from sections of the row's person. See derivedId.
derivedId2 RHGN0685 A second identifier, built by the same rules from the same person. See derivedId2.
dob 1986-01-19 The date of birth. Must be mapped to a Date column. See Date of birth.
ethnicity NonHispanic Hispanic or NonHispanic. US only. See Race and ethnicity.
firstName Revel The first name.
lastName Hindle The last name. In pl, cz, gr and ie, it has the form that matches the row's sex.
middleName Robles A middle name, from the first-name or the last-name list. See Middle names.
middleName2 Roswell A second middle name, with settings of its own. See Middle names.
race White One of five race categories. US only. See Race and ethnicity.
sex Male The generated sex, Male or Female, or M or F. See Sex.

custom, derivedId and derivedId2 are built from the other sub-fields. A sub-field used in customFormat, derivedId or derivedId2 is generated whether or not it is mapped, so an identifier can contain a date of birth that is not a column of its own.

The name sub-fields and race, ethnicity and sex must be mapped to a text column such as VarChar.

Properties

Property Type Default Description
countries NameCountryWeight[] none The countries the names are from. Required unless dob is the only sub-field generated. See NameCountryWeight.
customFormat string? none The template for custom, such as "{lastName}, {firstName}". Required when custom is mapped. See customFormat.
derivedId array? none The sections of derivedId. Required when derivedId is mapped. See derivedId.
derivedId2 array? none The sections of derivedId2. Required when derivedId2 is mapped. See derivedId2.
dobEnd string? (date) 2006-12-31 The latest date of birth. The default applies only when dobMean is not set. See Date of birth.
dobMean string? (date) none The center of a normal distribution of dates of birth. See Date of birth.
dobStart string? (date) 1940-01-01 The earliest date of birth. The default applies only when dobMean is not set. See Date of birth.
dobStdDev number? none The standard deviation of the distribution, in days. Required when dobMean is set, and must be greater than 0.
firstNameBeginsWith string[]? none The first letters a first name can start with. See Name beginsWith.
firstNameCaseOutput CaseOutput "None" The case of the first name.
firstNameMaxLength integer? none The maximum length of a first name.
firstNameMinLength integer? none The minimum length of a first name.
firstNamePopularityMax number? none The maximum popularity (0-100) of a first name. See Name popularityMax.
firstNamePopularityMin number? none The minimum popularity (0-100) of a first name. See Name popularityMin.
firstNamePopularityRamp number 0 How strongly the selection of a first name is weighted toward popular names (0-100). See Name popularityRamp.
firstNameRaces NameRaceWeight[]? none The race categories of the first names, weighted. US only. Replaces races for the first name.
lastNameBeginsWith string[]? none The first letters a last name can start with.
lastNameCaseOutput CaseOutput "None" The case of the last name.
lastNameMaxLength integer? none The maximum length of a last name.
lastNameMinLength integer? none The minimum length of a last name.
lastNamePopularityMax number? none The maximum popularity (0-100) of a last name.
lastNamePopularityMin number? none The minimum popularity (0-100) of a last name.
lastNamePopularityRamp number 0 How strongly the selection of a last name is weighted toward popular names (0-100).
lastNameRaces NameRaceWeight[]? none The race categories of the last names, weighted. US only. Replaces races for the last name.
map object required Maps the sub-fields to destination columns. See Building a Request.
middleName2CaseOutput CaseOutput "None" The case of the second middle name.
middleName2PercentageFirstName number 50 The percentage (0-100) of second middle names from the first-name list.
middleName2PopularityMax number? none The maximum popularity (0-100) of a second middle name.
middleName2PopularityMin number? none The minimum popularity (0-100) of a second middle name.
middleName2PopularityRamp number 0 How strongly the selection of a second middle name is weighted toward popular names (0-100).
middleName2Races NameRaceWeight[]? none The race categories of the second middle names, weighted. US only. Replaces races for the second middle name.
middleNameCaseOutput CaseOutput "None" The case of the middle name.
middleNamePercentageFirstName number 50 The percentage (0-100) of middle names from the first-name list. The rest are from the last-name list.
middleNamePopularityMax number? none The maximum popularity (0-100) of a middle name.
middleNamePopularityMin number? none The minimum popularity (0-100) of a middle name.
middleNamePopularityRamp number 0 How strongly the selection of a middle name is weighted toward popular names (0-100).
middleNameRaces NameRaceWeight[]? none The race categories of the middle names, weighted. US only. Replaces races for the middle name.
nullPercentageMax number 0 Upper bound (0-100) of the percentage of rows that should be null. See nullPercentageMin.
nullPercentageMin number 0 Lower bound (0-100) of the percentage of rows that should be null. The rate is fixed once for the whole field from this range, not recalculated per row. Set equal to nullPercentageMax for an exact rate. A null row has every mapped sub-field empty.
percentageMaleMax number 50 Upper bound (0-100) of the percentage of rows with a male sex. See percentageMaleMin.
percentageMaleMin number 50 Lower bound (0-100) of the percentage of rows with a male sex. The percentage is fixed once for the whole field from this range, not recalculated per row. Set equal to percentageMaleMax for an exact split.
races NameRaceWeight[]? none The race categories of every name, weighted. US only. A name's own setting, such as firstNameRaces, replaces it for that name.
seed integer random Per-field seed, overriding the request's own seed for this field only.
sex "Any" / "Male" / "Female" "Any" Limits every row to one sex without generating a sex value. Ignored when sex is mapped. See Sex.
sexOutputFormat "FullWord" / "Abbreviated" "FullWord" Male and Female, or M and F. See Sex.
unique boolean false Whether every row must have a different combination of the mapped values. See Unique rows.

Properties by sub-field

A property that applies only to a sub-field that is not generated has no effect.

Sub-field Properties
custom customFormat
derivedId derivedId
derivedId2 derivedId2
dob dobEnd, dobMean, dobStart, dobStdDev
firstName countries, firstNameBeginsWith, firstNameCaseOutput, firstNameMaxLength, firstNameMinLength, firstNamePopularityMax, firstNamePopularityMin, firstNamePopularityRamp, firstNameRaces, races, sex
lastName countries, lastNameBeginsWith, lastNameCaseOutput, lastNameMaxLength, lastNameMinLength, lastNamePopularityMax, lastNamePopularityMin, lastNamePopularityRamp, lastNameRaces, races, sex
middleName countries, middleNameCaseOutput, middleNamePercentageFirstName, middleNamePopularityMax, middleNamePopularityMin, middleNamePopularityRamp, middleNameRaces, races
middleName2 countries, middleName2CaseOutput, middleName2PercentageFirstName, middleName2PopularityMax, middleName2PopularityMin, middleName2PopularityRamp, middleName2Races, races
race, ethnicity countries
sex percentageMaleMax, percentageMaleMin, sexOutputFormat

map, nullPercentageMin, nullPercentageMax, seed and unique apply to the whole field.

A set of name filters that no name matches, such as a firstNameMinLength longer than every first name, is rejected before any data is generated.

NameCountryWeight

countries contains one or more entries, with at most one entry per country:

Property Type Default Description
country string required A two-letter country code, such as us or pl. See GET /v1/names/countries for the countries available.
weight number 1 The country's weight relative to the other entries in the list. Must be greater than 0.
greekScript boolean false Greek names in Greek script. gr only. See Name.
japaneseScript "Romaji" / "Kanji" / "Hiragana" "Romaji" The script of Japanese names. jp only. See Name.
koreanScript boolean false Korean names in Hangul. kr only. See Name.

Weights are relative, not percentages, so they do not need to total any particular number. 3 and 1 give the same distribution as 30 and 10. With no weights set, every country is equally likely.

Each row is from one country, selected by weight, and every name in the row is from that country. Three quarters of these rows are from the US and one quarter from Poland:

{
  "type": "Person",
  "countries": [
    { "country": "us", "weight": 3 },
    { "country": "pl" }
  ],
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name
Mansour Sierzputowski
Elunia Pawul
Rachael Hoffstatter
Ayumi Steingart
Lukrecja Słomczewski
Pelayo Rushmore

Middle names

middleName and middleName2 are each selected from either the country's first names or its last names. middleNamePercentageFirstName and middleName2PercentageFirstName set the percentage from the first-name list, and the rest are from the last-name list. A middle name from the last-name list is typical of a family name used as a middle name.

The two middle names are selected separately, from their own settings. The firstName and lastName settings do not apply to them.

When the row has a sex, from the sex sub-field or the sex property, a middle name from the first-name list is a male or female name to match. In pl, cz, gr and ie, a middle name from the last-name list has the matching form.

Race and ethnicity

race is one of five race categories: White, Black, AmericanIndianAlaskaNative, AsianPacificIslander and TwoOrMoreRaces. ethnicity is Hispanic or NonHispanic.

Every US name has a percentage breakdown across these five categories and Hispanic. A row's race is selected using the combined breakdown of its first name and its last name, so a name that is common in a category makes that category more likely. ethnicity is selected separately from the same breakdown, so a row can be Hispanic with any race.

races, firstNameRaces, lastNameRaces, middleNameRaces and middleName2Races limit which names are used, by the category with the largest share of each name. Each contains { race, weight } entries, with the five race categories and Hispanic. See Name for how the weights work. races applies to every name, and a name's own setting replaces it for that name.

A name limited to one category still has percentages in the others, so a row with names limited to Hispanic can have a NonHispanic ethnicity. See Name.

race, ethnicity and the race filters require countries to contain exactly one entry, us. A list with more than one entry is rejected, even when one of them is us.

Sex

sex is both a property and a sub-field.

The sex sub-field generates a sex for each row. The first name and the middle names match it, and in pl, cz, gr and ie the last name has the matching form. Two properties apply:

  • percentageMaleMin and percentageMaleMax set the percentage of male rows. The percentage is fixed once for the whole field from that range. Set both to the same number for an exact split.
  • sexOutputFormat writes the value as Male and Female (FullWord, the default) or M and F (Abbreviated).

The sex property limits every row to Male or Female names without generating a value. It applies to the first name and the middle names and, in pl, cz, gr and ie, to the last name. It is ignored when the sex sub-field is mapped.

Date of birth

dob is generated in one of two ways:

  • A range. Without dobMean, every date from dobStart to dobEnd is equally likely. An unset dobStart is 1940-01-01 and an unset dobEnd is 2006-12-31. A range that is empty, such as a dobEnd earlier than the default dobStart, is rejected.
  • A distribution. With dobMean set, dates of birth have a normal distribution around dobMean, with a standard deviation of dobStdDev days. dobStart and dobEnd are optional and have no default. When set, dobMean must be within them.
most half none rows value -3 -2 -1 mean +1 +2 +3 standard deviations from the mean stdDev min max within 1 stdDev of mean, about 68% of rows within 2 stdDev, about 95% outside min..max moved onto the boundary instead
How mean, stdDev, min and max affect the output. The curve is the number of rows with each value. Most values are near mean, and fewer are further away, at a rate set by stdDev. A value beyond min or max is set to that boundary, shown by the solid bar at each one.

mean sets the center and stdDev sets the width, both in the field's own units. About 68% of values are within one stdDev of mean, about 95% within two, and about 99.7% within three. A larger stdDev spreads the values further from mean, and a smaller one keeps them closer to it.

min and max are optional. Without them, a value can be any distance from mean within the range the field supports. With them, a value outside the range is set to the nearer of min or max. It is not generated again. The solid bars in the diagram are these values.

When the range is narrow relative to stdDev, many rows have a value of exactly min or max. In the diagram, the range is one and a half standard deviations either side of mean. To reduce the number of rows on the boundaries, widen the range or reduce stdDev.

For a date of birth, a dobStdDev of 3650 is about ten years, so about 95% of dates of birth are within twenty years of dobMean.

customFormat

customFormat builds one text value from the row's other sub-fields, such as a display name.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "customFormat": "{lastName}, {firstName} - DOB {dob} ({sex})",
  "dobStart": "1960-01-01",
  "dobEnd": "2005-12-31",
  "seed": 1,
  "map": { "custom": { "column": "display", "dataType": "VarChar" } }
}

Sample output:

display
Gaugh, Rory - DOB 1988-09-19 (Male)
Ocallaghan, Guinevere - DOB 1985-05-13 (Female)
Zigrang, Allysa - DOB 1994-04-08 (Female)
Cantoni, Jaswinder - DOB 1987-07-25 (Female)
Bregel, Resse - DOB 1965-08-10 (Female)

Each {name} is replaced with that sub-field's value for the row. The names are firstName, lastName, middleName, middleName2, dob, race, ethnicity and sex, and an unknown name is rejected. A date is written as yyyy-MM-dd, and every other value as it would be written in its own column. The rest of the template is written as it is.

{{ and }} write a literal brace, so "{{{firstName}}}" writes the first name inside braces. A { that is not closed is rejected. These are the same rules as a calculated Template.

A sub-field used in the template is generated whether or not it is mapped. In the example above, the date of birth and the sex are part of display and are not columns of their own.

derivedId

derivedId builds an identifier from sections, written in the order given. A bare string is fixed text. An object is a section with a source.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "dobStart": "1960-01-01",
  "dobEnd": "2005-12-31",
  "derivedId": [
    "X-",
    { "source": "Dob", "part": "Year", "length": 4 },
    "-",
    { "source": "Dob", "part": "Day", "length": 2 },
    { "source": "Dob", "part": "Month", "length": 2 },
    "-",
    { "source": "LastName", "length": 5, "case": "Upper", "pad": "X" },
    "-",
    { "source": "Number", "length": 4 }
  ],
  "seed": 2,
  "map": {
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "dob": { "column": "date_of_birth", "dataType": "Date" },
    "derivedId": { "column": "person_id", "dataType": "VarChar" }
  }
}

Sample output:

last_name date_of_birth person_id
Verdi 1969-10-11 X-1969-1110-VERDI-3842
Wilckens 1962-07-30 X-1962-3007-WILCK-0532
Fritsch 1990-05-22 X-1990-2205-FRITS-3788
Hribar 1968-11-25 X-1968-2511-HRIBA-6991
Tree 1984-05-14 X-1984-1405-TREEX-2495

The identifier is X-, the year of birth, the day and the month of birth, the first five letters of the last name in upper case, and four random digits. Tree has four letters, so pad adds an X to make TREEX. The day is before the month, so 1110 in the first row is October 11.

Sources

source Produces
Checksum A check character for the digits before it. See Check characters.
Dob The year, month or day of the date of birth, set by part.
Ethnicity The generated ethnicity.
FirstName The generated first name.
LastName The generated last name.
Letters length random letters from A to Z, in upper case unless case is set.
Literal The text in value. A bare string is the same as a Literal section.
Lookup One entry from lookupValues, selected by weight for each row. See Lookup sections.
MiddleName The generated middle name.
MiddleName2 The generated second middle name.
Number length random digits, from 0 to 9. The first digit can be 0.
Race The generated race.
Sex The generated sex.

FirstName, LastName, MiddleName, MiddleName2, Race, Ethnicity and Sex are the text sources.

Settings

Setting Applies to Description
add Dob A number added to the year, month or day.
addWhenFemale Dob A number added when the row's sex is female, in addition to add. See Offsets.
case text sources, Letters None, Upper, Lower or Proper. Applied last. Defaults to None.
length every source except Literal, Lookup and Checksum The number of characters. Required for Dob, Number and Letters. Optional for a text source, which uses the whole value from start when it is not set.
lookupValues Lookup The entries, each { value, weight }. Required, with at least one entry.
method Checksum Luhn, Mod11 or Verhoeff. Required. See Check characters.
pad text sources A single character added to the right of a value shorter than length. Requires length. Defaults to no padding.
part Dob Year, Month or Day. Required.
phonetic FirstName, LastName, MiddleName, MiddleName2 None, Soundex, RefinedSoundex, Metaphone or Nysiis. Defaults to None. See Phonetic encoding.
sanitize text sources None, Ascii, Letters or LettersAndDigits. Applied first. Defaults to None. See Sanitizing a name.
start text sources, Dob The position of the first character, counting from 1. Defaults to 1. See Widths.
value Literal The text, written exactly as given. Required.

A text section is processed in this order: sanitize, phonetic, start and length, pad, then case.

A setting on a section it does not apply to is rejected, and the message identifies the section by its position, such as derivedId section 3 (Literal): length has no meaning on a Literal, whose width is its own text.

Widths

Without start, a Dob section is padded on the left with zeros to length, and then only the rightmost length digits are used. length: 2 on Year is the last two digits of the year, and length: 2 on Month or Day is a two-digit month or day.

With start, the year is written with four digits and the month and day with two. The section starts at start and contains length digits. start: 3 with length: 1 on Year is the third digit of the year, 8 for 1986.

A text section starts at start and contains length characters, or the rest of the value when length is not set. A character with an accent counts as one character, whether it is stored as one character or as a letter and a separate accent. A value shorter than length is padded only when pad is set. Without pad, the section is shorter than length. With pad set to X, a last name of Ng and a length of 5 produce NgXXX, and NGXXX with case set to Upper.

Lookup sections

A Lookup section selects one entry from a weighted list for each row. Use it for a part of an identifier that is not from the person, such as a mail domain or an office code.

{
  "source": "Lookup",
  "lookupValues": [
    { "value": "@example.com", "weight": 6 },
    { "value": "@example.net", "weight": 3 },
    { "value": "@example.org", "weight": 1 }
  ]
}

Weights are relative, so 6, 3 and 1 give the same distribution as 60, 30 and 10. An entry with no weight has a weight of 1. Every weight must be greater than 0. An entry is written exactly as given, so a Lookup section has no length.

Sanitizing a name

Names can contain accents, spaces, apostrophes, hyphens and letters from other scripts. sanitize removes the characters an identifier cannot contain, such as in the local part of an email address.

sanitize Keeps Ferreira-Gonçalves
None Every character. The default. Ferreira-Gonçalves
Ascii ASCII characters, including punctuation and spaces, with accents removed. Ferreira-Goncalves
Letters The letters A to Z, with accents removed. FerreiraGoncalves
LettersAndDigits The letters A to Z and the digits 0 to 9, with accents removed. FerreiraGoncalves

With accents removed, José is Jose and Müller is Muller. A letter with a stroke or a ligature is replaced with plain letters: Nørgaard is Norgaard, Łukasz is Lukasz, and ß, æ, œ and þ are ss, ae, oe and th. Any other character outside the kept set is removed, so a name in another script produces an empty value. Set pad to fill the section to its length.

Phonetic encoding

A phonetic encoding converts a name into a code based on its pronunciation, so that names that sound alike can have the same code. phonetic is applied before start and length.

phonetic Produces Whitfield
Soundex The first letter and three digits, padded with zeros. W314
RefinedSoundex The first letter and a digit for each letter, with repeated digits combined. W062076
Metaphone Letters based on English pronunciation. 0 is the th sound and X is the sh sound. WTFLT
Nysiis Letters produced by a fixed set of spelling rules for surnames. WATFALD

The code is not shortened, so use start and length to select part of it. A section with length: 1 on the last name followed by a section with phonetic: "Soundex" and start: 2 produces the Soundex code.

Check characters

A Checksum section adds one check character, calculated from the digits before it in the identifier. A system that validates the identifier calculates the check character again from the same digits and rejects the identifier when the two are different. This detects most typing errors, such as a wrong digit or two digits in the wrong order.

All three methods use only the digits 0 to 9 before the section, including digits in Literal and Lookup sections, and ignore every other character. Letters from a name section do not change the result. When there is no digit before the section, the check character is 0.

A Checksum section has no length, because a check character is always one character. It cannot be the first section. Sections after it do not affect it.

method Check character Detects any single wrong digit Detects two adjacent digits swapped Used by
Luhn 0 to 9 Yes Yes, except a swap of 09 and 90 Payment card numbers, IMEI numbers
Mod11 0 to 9, or X Yes, for up to nine digits Yes ISBN-10
Verhoeff 0 to 9 Yes Yes Aadhaar numbers in India

Luhn

  1. Starting with the rightmost digit before the check character and moving left, double every second digit. The rightmost digit is doubled, the one to its left is not, and so on.
  2. When doubling gives a number greater than 9, subtract 9 from it. This is the same as adding its two digits together, so 16 becomes 7.
  3. Add up all the digits, doubled and not doubled.
  4. The check digit is the amount that brings the total up to the next multiple of 10, or 0 when the total is already a multiple of 10.

For 7992739871:

Digit 7 9 9 2 7 3 9 8 7 1
Doubled 18 4 6 16 2
Value added 7 9 9 4 7 6 9 7 7 2

The total is 67. The next multiple of 10 is 70, so the check digit is 3 and the full number is 79927398713.

A swap of 0 and 9 is not detected because the pair adds 9 to the total in either order. A doubled 0 is still 0, and a doubled 9 is 18, which becomes 9.

Mod11

  1. Give each digit a weight. The rightmost digit before the check character has a weight of 2, the next digit to the left has a weight of 3, and so on.
  2. Multiply each digit by its weight and add the results.
  3. Divide the total by 11 and take the remainder.
  4. The check character is 11 minus the remainder. A result of 11 is written as 0, and a result of 10 is written as X.

For 030640615, the digits of the ISBN 0-306-40615-2 without its check character:

Digit 0 3 0 6 4 0 6 1 5
Weight 10 9 8 7 6 5 4 3 2
Product 0 27 0 42 24 0 24 3 10

The total is 130. 130 divided by 11 is 11 with a remainder of 9, and 11 minus 9 is 2, so the check character is 2. For 080442957 the total is 199, the remainder is 1, and 11 minus 1 is 10, so the check character is X, giving the ISBN 0-8044-2957-X.

Every single wrong digit is detected for up to nine digits, which is the length ISBN-10 uses. With ten digits, the leftmost digit has a weight of 11. Any multiple of 11 leaves the remainder unchanged, so a wrong digit in that position is not detected. With more than ten digits, weights above 11 have the same effect as weights 11 lower, so a swap of two digits eleven positions apart is not detected either. A swap of two adjacent digits is detected at any length, because their weights always differ by 1.

Verhoeff

The Verhoeff method uses arithmetic based on the symmetries of a regular pentagon, a set of ten values with a multiplication table. Unlike ordinary addition, the result of combining two values in this table depends on their order. This is how the method detects every swap of two adjacent digits.

  1. Read the digits from right to left. The rightmost digit before the check character is position 1.
  2. Replace each digit with another digit using a substitution that depends on its position. The substitution repeats every eight positions.
  3. Combine the substituted digits one at a time, starting from 0, using the multiplication table.
  4. The check digit is the inverse of the final result in the same table. The same calculation over the full number, check digit included, gives 0.

The substitution and multiplication tables are the standard ones defined for the method. For 236:

Position Digit Substituted digit Result so far
1 6 3 3
2 3 3 1
3 2 1 2

The final result is 2. Its inverse is 3, so the check digit is 3 and the full number is 2363.

See A member number with a check digit for a Verhoeff section in a complete identifier.

Offsets

add adds a fixed number to the year, month or day. addWhenFemale adds a number only when the row's sex is female. Some license number formats use this to include the sex in the month. With an addWhenFemale of 50 on Month, January is 51 for a female row and 01 for a male row.

addWhenFemale generates a sex for each row whether or not sex is mapped. It works with either sexOutputFormat.

derivedId2

derivedId2 is a second identifier, built by the same rules from the same person and mapped to its own column. Everything in derivedId applies to it. Either one can be mapped without the other.

Use it for a person with two identifiers in different formats, such as an employee number and a login code.

{
  "type": "Person",
  "countries": [{ "country": "gb" }],
  "derivedId": ["EMP-", { "source": "Number", "length": 6 }],
  "derivedId2": [
    { "source": "FirstName", "length": 1, "case": "Upper" },
    { "source": "LastName", "length": 1, "case": "Upper" },
    { "source": "Letters", "length": 2 },
    { "source": "Number", "length": 4 }
  ],
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "derivedId": { "column": "employee_number", "dataType": "VarChar" },
    "derivedId2": { "column": "login_code", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name employee_number login_code
John-Luke Mohandas EMP-643916 JMAG3966
Humza Sherred EMP-267790 HSEJ7173
Viansh Eastgate EMP-885760 VEZU8055
Dacia Daish EMP-296346 DDRM2351
Leif Chegg EMP-363190 LCZM6012

The login code starts with the initials of the same first name and last name as the name columns.

Unique rows

With unique set, no two rows have the same combination of mapped values.

For some fields, the number of different values is calculated before any data is generated, and a request for more rows than that is rejected, stating how many are available:

  • A field with only firstName or only lastName mapped, limited to the number of names that match its filters.
  • A field with only derivedId or only derivedId2 mapped, when every section has a fixed number of values. A Literal or a Checksum has one value, a Number of length 4 has 10,000, a Lookup has one value for each different entry, and a Dob section without start has the years from dobStart to dobEnd, 12 months or 31 days. A text section, or a Dob section with start, has no fixed number.

For any other field, a request that runs out of different values is rejected during generation.

Only Number, Letters and Lookup sections vary independently of the person. An identifier with none of them is the same for two rows with the same name and date of birth.

Examples

Each example below is a single field object, one entry in a table's fields array within a full request, not a complete request on its own. See Building a Request for how it fits into a full DatasetRequest.

A first and last name

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name
Libertad Hullinger
Rory Brewbaker
Eliz Cosco
Talmage Juckett
Deondrea Eaglin

A generated sex with Polish surname forms

{
  "type": "Person",
  "countries": [{ "country": "pl" }],
  "dobStart": "1960-01-01",
  "dobEnd": "2005-12-31",
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "dob": { "column": "date_of_birth", "dataType": "Date" },
    "sex": { "column": "sex", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name date_of_birth sex
Wojtek Pełka 1982-04-02 Male
Mikael Kotara 1968-05-18 Male
Filip Naglik 1975-03-16 Male
Ulcia Dziekańska 1998-12-19 Female
Sandi Kwiatuszek 1981-12-08 Female
Jurij Zapałowski 1991-02-03 Male

Dziekańska is the female form of Dziekański, and Zapałowski is the male form of Zapałowska. Pełka, Kotara, Naglik and Kwiatuszek have one form for both sexes.

Names limited to one sex

With the sex property set and the sex sub-field not mapped, every row has female names and no sex column.

{
  "type": "Person",
  "countries": [{ "country": "pl" }],
  "sex": "Female",
  "seed": 12,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name
Emka Waśkowska
Anna Katarzyna Kwapień
Lilly Zimecka
Liana Klinowska
Gaba Chachaj
Malwinka Gorynia

Waśkowska, Zimecka and Klinowska are female forms. Kwapień, Chachaj and Gorynia have one form for both sexes.

A middle name, mostly from last names

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "middleNamePercentageFirstName": 20,
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "middleName": { "column": "middle_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" }
  }
}

Sample output:

first_name middle_name last_name
Libertad Amreen Hullinger
Rory Siena Brewbaker
Eliz Cenovia Cosco
Talmage Arizola Juckett
Deondrea Defenbaugh Eaglin

Two middle names from different lists

The first middle name is mostly from the first-name list and the second mostly from the last-name list.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "middleNamePercentageFirstName": 90,
  "middleName2PercentageFirstName": 10,
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "middleName": { "column": "middle_name", "dataType": "VarChar" },
    "middleName2": { "column": "middle_name_2", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" }
  }
}

Sample output:

first_name middle_name middle_name_2 last_name
Libertad Amreen Richie Hullinger
Rory Shalandra Horowitz Brewbaker
Eliz Cenovia Bosques Cosco
Talmage Argel Kunath Juckett
Deondrea Defenbaugh Victo Eaglin

US race and ethnicity

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "race": { "column": "race", "dataType": "VarChar" },
    "ethnicity": { "column": "ethnicity", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name race ethnicity
Romas Ceglarek White NonHispanic
Javontae Yuki Black NonHispanic
Brenetta Murai TwoOrMoreRaces NonHispanic
Kahdijah Trofa Black NonHispanic
Leilany Platter White Hispanic
Ruger Pietruszka TwoOrMoreRaces NonHispanic

Dates of birth in a range

Every date from dobStart to dobEnd is equally likely.

{
  "type": "Person",
  "countries": [{ "country": "gb" }],
  "dobStart": "1955-01-01",
  "dobEnd": "2006-12-31",
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "dob": { "column": "date_of_birth", "dataType": "Date" }
  }
}

Sample output:

first_name last_name date_of_birth
John-Luke Mohandas 1986-10-07
Humza Sherred 1983-09-20
Viansh Eastgate 1963-05-19
Dacia Daish 1982-07-25
Leif Chegg 2004-11-27

Dates of birth around a mean

Dates of birth have a normal distribution around June 1, 1985, with a standard deviation of about ten years, from 1960 to 2004.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "dobMean": "1985-06-01",
  "dobStdDev": 3650,
  "dobStart": "1960-01-01",
  "dobEnd": "2004-12-31",
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "dob": { "column": "date_of_birth", "dataType": "Date" }
  }
}

Sample output:

first_name date_of_birth
Libertad 1974-04-23
Rory 1991-05-31
Eliz 1982-03-10
Talmage 1981-10-24
Deondrea 1987-10-29
Rashunda 1984-11-07

Five of the six dates of birth are within ten years of dobMean.

A percentage of male rows

percentageMaleMin and percentageMaleMax set 80% male rows, and sexOutputFormat writes the sex as M or F.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "percentageMaleMin": 80,
  "percentageMaleMax": 80,
  "sexOutputFormat": "Abbreviated",
  "seed": 1,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "sex": { "column": "sex", "dataType": "Char" }
  }
}

Sample output:

first_name sex
Rory M
Talmage M
Hernandez M
Jaswinder F
South M
August M
Mosi M
Burrell M
Kerwyn M
Parichehr F

Null rows

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "nullPercentageMin": 25,
  "nullPercentageMax": 25,
  "seed": 5,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" }
  }
}

Sample output. A null row has every mapped sub-field empty:

first_name last_name
Catherine Campagnola
Aurore Esber
Muon Rapant
Vagner Brewin
Idiana Lapsansky
Aril Wimley

A formatted record label

The template uses sub-fields that are not mapped. first_name and last_name are mapped for comparison with the label, and the middle name, sex, date of birth, race and ethnicity are only in the label.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "customFormat": "{lastName}, {firstName} {middleName} | {sex} | DOB {dob} | {race} / {ethnicity}",
  "lastNameCaseOutput": "Upper",
  "sexOutputFormat": "Abbreviated",
  "dobMean": "1975-06-01",
  "dobStdDev": 5475,
  "dobStart": "1930-01-01",
  "dobEnd": "2006-12-31",
  "seed": 2,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "custom": { "column": "label", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name label
Gustave MARSDEN MARSDEN, Gustave Franciszek | M | DOB 1963-10-21 | White / Hispanic
Haskel MORAITIS MORAITIS, Haskel Cyrille | M | DOB 1987-05-14 | White / NonHispanic
Maryem JAYJOHN JAYJOHN, Maryem Gormley | F | DOB 1995-06-07 | White / NonHispanic
Yarisel BINNEY BINNEY, Yarisel Maisy | F | DOB 1978-12-15 | TwoOrMoreRaces / NonHispanic
Lucelia SLESSER SLESSER, Lucelia Llagas | F | DOB 1977-01-30 | White / NonHispanic
Sheriff ZOSEL ZOSEL, Sheriff Vandriessche | M | DOB 1977-07-10 | White / NonHispanic

Each value in the label is the value the sub-field has as a column. lastNameCaseOutput applies to the last name in both last_name and the label, and sexOutputFormat applies to the sex in the label.

A JSON value

{{ and }} write a literal brace, so a template can produce JSON. The braces around the JSON object are written as {{ and }}, and each {name} inside them is replaced with the row's value.

{
  "type": "Person",
  "countries": [
    { "country": "gb", "weight": 2 },
    { "country": "fr" }
  ],
  "customFormat": "{{\"name\": \"{firstName} {lastName}\", \"born\": \"{dob}\", \"sex\": \"{sex}\"}}",
  "dobStart": "1950-01-01",
  "dobEnd": "2000-12-31",
  "seed": 1,
  "map": {
    "custom": { "column": "profile", "dataType": "VarChar" }
  }
}

Sample output:

profile
{"name": "Chhavi Kompus", "born": "1975-05-14", "sex": "Female"}
{"name": "Jeanne-Hélène Woo", "born": "1984-04-08", "sex": "Female"}
{"name": "Lunah Narraway", "born": "1977-07-25", "sex": "Female"}
{"name": "Riga Lavigne", "born": "1955-08-11", "sex": "Female"}
{"name": "Gulcan Meziri", "born": "1988-12-19", "sex": "Female"}

A staff code from initials

The first initial, the first three letters of the last name, and five random digits. pad fills a last name shorter than three letters, so every code has the same length.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "derivedId": [
    { "source": "FirstName", "length": 1, "case": "Upper" },
    { "source": "LastName", "length": 3, "case": "Upper", "pad": "X" },
    "-",
    { "source": "Number", "length": 5 }
  ],
  "seed": 57,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "derivedId": { "column": "staff_code", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name staff_code
Greyson Eh GEHX-93400
Tajuanna Marynowski TMAR-22981
Yoshimi Swanger YSWA-86832
Takelia Karos TKAR-33869
Adalberta Ihasz AIHA-21902
Bathsheba Hatley BHAT-92424

Eh has two letters, so pad adds an X to make EHX.

A UK driving license number

This identifier follows the layout of a UK driving license number, sixteen characters: five letters of the last name, the decade digit of the year of birth, the month of birth with 50 added for a female person, the day of birth, the last digit of the year of birth, the first and middle initials, two random digits and a Luhn check digit.

{
  "type": "Person",
  "countries": [{ "country": "gb" }],
  "dobStart": "1960-01-01",
  "dobEnd": "2005-12-31",
  "middleNamePercentageFirstName": 100,
  "derivedId": [
    { "source": "LastName", "length": 5, "pad": "9", "case": "Upper" },
    { "source": "Dob", "part": "Year", "start": 3, "length": 1 },
    { "source": "Dob", "part": "Month", "addWhenFemale": 50, "length": 2 },
    { "source": "Dob", "part": "Day", "length": 2 },
    { "source": "Dob", "part": "Year", "length": 1 },
    { "source": "FirstName", "length": 1, "case": "Upper" },
    { "source": "MiddleName", "length": 1, "case": "Upper" },
    { "source": "Number", "length": 2 },
    { "source": "Checksum", "method": "Luhn" }
  ],
  "seed": 2,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "dob": { "column": "date_of_birth", "dataType": "Date" },
    "sex": { "column": "sex", "dataType": "VarChar" },
    "derivedId": { "column": "license_number", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name date_of_birth sex license_number
Addy Bolat 1990-05-22 Male BOLAT905220AB372
Yanet McBurney 1968-11-25 Female MCBUR661258YE699
Sophie-Louise Landles 1984-05-14 Female LANDL855144SA242
Sughra Satterly 1990-09-13 Female SATTE959130SL469
Merin Igwe 1998-10-15 Female IGWE9960158MZ047

In the first row, 9 after BOLAT is the decade digit of 1990 and 0 after the day is its last digit. The second row is female, so November is written as 61. Igwe has four letters, so pad adds a 9 to make IGWE9.

A license number with a phonetic code

The first letter of the last name, then three digits of the last name's Soundex code, three digits of the first name's Soundex code, and the date of birth with 50 added to the month for a female person.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "dobStart": "1960-01-01",
  "dobEnd": "2005-12-31",
  "derivedId": [
    { "source": "LastName", "length": 1, "case": "Upper" },
    { "source": "LastName", "phonetic": "Soundex", "start": 2, "length": 3 },
    { "source": "FirstName", "phonetic": "Soundex", "start": 2, "length": 3 },
    { "source": "Dob", "part": "Year", "length": 2 },
    { "source": "Dob", "part": "Month", "addWhenFemale": 50, "length": 2 },
    { "source": "Dob", "part": "Day", "length": 2 },
    { "source": "Number", "length": 1 }
  ],
  "seed": 9,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "derivedId": { "column": "license_number", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name license_number
Markiya Hospodar H2136206551115
Rogers Meres M6202628907195
Jacquelin Haspel H2142459753052
Marqui Asi A2006206205044
Geremiah Argaw A6206508811049

In the first row, Hospodar has the Soundex code H213 and Markiya has M620, so the number starts with H213620. The next digits are the year 65, the month 51, which is January with 50 added for a female person, and the day 11.

A member number with a check digit

A Verhoeff check digit lets a system that reads the member number detect a mistyped number.

{
  "type": "Person",
  "countries": [{ "country": "us" }],
  "dobStart": "1950-01-01",
  "dobEnd": "2006-12-31",
  "derivedId": [
    "MB-",
    { "source": "Dob", "part": "Year", "length": 2 },
    { "source": "Number", "length": 6 },
    "-",
    { "source": "Checksum", "method": "Verhoeff" }
  ],
  "seed": 1,
  "map": { "derivedId": { "column": "member_number", "dataType": "VarChar" } }
}

Sample output:

member_number
MB-91764391-9
MB-72396626-3
MB-84717388-5
MB-96529634-1
MB-92235136-2

The final digit is calculated from the eight digits before it. A wrong digit, or two adjacent digits swapped, produces a number that fails the check.

An email address that matches the person

The email address is built from the row's own first name and last name, so it matches the first_name and last_name columns. sanitize removes accents, apostrophes and hyphens, which the local part of an email address cannot contain.

{
  "type": "Person",
  "countries": [
    { "country": "pt", "weight": 2 },
    { "country": "no" },
    { "country": "ie" },
    { "country": "pl" },
    { "country": "de" }
  ],
  "derivedId": [
    { "source": "FirstName", "sanitize": "Letters", "case": "Lower" },
    ".",
    { "source": "LastName", "sanitize": "Letters", "case": "Lower" },
    { "source": "Number", "length": 2 },
    {
      "source": "Lookup",
      "lookupValues": [
        { "value": "@example.com", "weight": 6 },
        { "value": "@example.net", "weight": 3 },
        { "value": "@example.org", "weight": 1 }
      ]
    }
  ],
  "seed": 19,
  "map": {
    "firstName": { "column": "first_name", "dataType": "VarChar" },
    "lastName": { "column": "last_name", "dataType": "VarChar" },
    "derivedId": { "column": "email", "dataType": "VarChar" }
  }
}

Sample output:

first_name last_name email
Aleida Barnabé aleida.barnabe52@example.net
Jass Martins Ferreira jass.martinsferreira57@example.com
Claudia Ottesen claudia.ottesen47@example.com
Inocencio Martins Da Silva inocencio.martinsdasilva24@example.org
Sali Stolarski sali.stolarski42@example.com
Helena Isabel Lopes Ribeiro helenaisabel.lopesribeiro73@example.com

é in Barnabé is e, and the spaces in Martins Ferreira, Martins Da Silva, Helena Isabel and Lopes Ribeiro are removed. The name columns are not changed, because sanitize applies only to the section.

The two random digits make two people with the same name less likely to have the same address. The domain is a weighted Lookup section. Set unique to reject any row with an address that is already used.

An email address not linked to a person

For an email address that does not need to match a name in the row, use Identifier.