Searching by date of birth
Labelled match strength on every record, and how dob, birthYear and dobPrecision fit together.
Base URL https://api.offendersearch.appThis page as Markdown/docs/date-of-birth.mdSearching by date of birth
A date of birth is the strongest identity verifier. Add dob (YYYY-MM-DD) to your query and every returned record carries a matchState telling you exactly how it matched. A record with no date of birth published is never silently dropped: if there is nothing to confirm the date but the name matched, you still get the record, labelled as unverified. Only a true date-of-birth conflict is excluded.
matchState names which one verified this record. That lets you set your own threshold for auto-accept versus review, rather than inherit one.matchState — how each record matched
| matchState | Meaning |
|---|---|
| dob_match | The record has a full date of birth on file and it equals the DOB you queried — the strongest confirmation. |
| year_match | The record has NO full DOB (a year-only source, e.g. Massachusetts), but its birth year equals your DOB’s year. |
| age_match | No DOB or birth year is published, but the record’s age matches the age implied by your DOB (±1 year for birthday drift). |
| no_dob_age_year | The record has no DOB, year, or age to verify against — yet it is still returned because the name matched. Check matchBasis for name_match or alias_match. This is the “no DOB on file, but the name matches” case. |
| dob_mismatch | The record HAD a DOB, year, or age and it did NOT match your query, so it is filtered OUT of the results. You will not normally see this state — it is documented so you know a true conflict is excluded, never silently shown. |
| null | You did not send a dob or an age, so there was nothing to verify the record against and this field carries no information. It is null, not a string — do not treat it as a failed verification. |
matchState is null when you did not supply a dob or age — it is only meaningful on a date-of-birth or age search. A record whose date, year or age actively conflicts with your query is filtered out of records[], so a mismatch is excluded rather than shown as a false hit.
dobVerification — the same signal, backward-compatible
dobVerification carries the raw token for integrations written before matchState existed. New code should read matchState.
| dobVerification | Meaning |
|---|---|
| dob_match | The record’s full date of birth equals the DOB you supplied — the strongest identity confirmation. |
| year_match | The record is year-only (dobPrecision: year) and its year equals your DOB’s year. |
| age_match | No full DOB was available, but the published age matched yours within ±1 year (birthday drift). |
| no_dob_age_year | The record had no DOB, age, or year to check against — kept and flagged (unverified: true). |
| dob_mismatch | The record had a DOB/age that did NOT match; such records are filtered out of records[], so you normally never see this. |
What comes back on the record: dob, birthYear, age
Jurisdictions differ in how much of a birth date they publish, so three fields carry the answer and which of them is populated is itself information. Read dobPrecision to know which case you are in.
| What the jurisdiction publishes | dob | birthYear | dobPrecision | Matches your dob query as |
|---|---|---|---|---|
| A full calendar date | "1961-09-25" | 1961 | "exact" | dob_match |
| A birth year only | null | 1961 | "year" | year_match — any date you query inside that year |
| An age only | null | null | "unknown" | age_match — a date consistent with the published age |
| Neither date, year nor age | null | null | "unknown" | no_dob_age_year — kept on the name, unverified: true |
dob is a full YYYY-MM-DD date or null — never a bare year, never a partial date, and never a day and month chosen to fill the field. You can hand it straight to a date parser without a shape check. Where a jurisdiction publishes only the year, that year is in birthYear as an integer, and the record still matches a full-date query. Read birthYear for any year logic — it is populated both from a published year and from the year of a published date, so your code never has to branch on which kind of record it is looking at. It is never inferred from an age: an age is not a date, and this field is served as fact rather than as an estimate.Age tolerance
Where a jurisdiction publishes an age and no date, a name + dob search compares your date against that published age, and ageTolerance (0–10, default 1) sets how much slack that comparison allows — a risk decision that belongs to you. onAgeMismatch decides what happens to a record that matches on name but whose published age contradicts your date: "drop" omits it, "flag" returns it labelled matchState: "age_mismatch" and always unverified, so you can judge it yourself.
{
"query": {
"firstName": "John",
"lastName": "Doe",
"dob": "1980-04-12",
"ageTolerance": 2,
"onAgeMismatch": "flag"
},
"match": "balanced"
}matchBasis — why each record is in the results
Alongside matchState, every record carries a matchBasis array explaining why it is in the result set. When there is no date of birth to verify, this is how you tell a name hit apart from a verified one:
| matchBasis value | Meaning |
|---|---|
| lastName:exact / firstName:exact | The field equals the name you sent. |
| lastName:prefix / firstName:prefix | The field starts with the name you sent — a partial-name hit. See Partial name search. |
| firstName:nickname | Matched through a nickname equivalence (bob → Robert). |
| lastName:fuzzy / firstName:fuzzy | Matched through a spelling variant or typo. |
| firstName:absent | The record publishes no first name, so your first name could not be disproved — kept and flagged rather than dropped. |
| alias:exact / alias:prefix | An alias matched, not the registered name. Read matchedName to see which alias. |
| name_match | The record matched on its primary name — the name you searched. |
| alias_match | The record matched on one of its aliases rather than its primary name. |
| unverified_no_dob_or_age | The record was kept without DOB/age verification because there was nothing on file to check against — paired with matchState = no_dob_age_year. |
matchBasis also carries lastName, firstName, and dob tokens indicating which identity fields the record itself provides. So a name hit with no date of birth reads as matchState: "no_dob_age_year" with matchBasis: ["...", "name_match"] (or alias_match when the match was on an alias).
matchState: "no_dob_age_year" and a name_match/alias_match basis. Only a genuine conflict (dob_mismatch) is excluded from the results.{
"matchState": "no_dob_age_year",
"matchBasis": ["lastName", "firstName", "unverified_no_dob_or_age", "name_match"],
"unverified": true,
"name": { "first": "John", "last": "Doe", "full": "John Doe" },
"dob": null,
"dobPrecision": "unknown"
}Jurisdiction is a filter too. Name the jurisdiction(s) you want with jurisdictions (e.g. ["MA", "NY"]), or set query.state with locationScoped: true to run only the jurisdictions covering that state. Omit jurisdictions to search the full dataset.