Searching by date of birth
Labelled match strength on every record, and how one dob query reaches date, year and age evidence.
Base URL https://api.offendersearch.appOne query reaches every kind of birth evidence
A date of birth is the strongest identity verifier available. Jurisdictions do not all publish one: some publish only a birth year, many jail and inmate records publish only an age, a few publish neither.
dob you send is matched against a full date, else a year, else an age — so one query reaches all of them. There is no second, weaker search to run. Widening happens when we match; it never happens in what we store or send.matchState — how each record matched
| matchState | The record holds | Meaning | unverified |
|---|---|---|---|
dob_match | a full date | The record’s full date of birth equals yours. Strongest confirmation. | false |
year_match | a year (and maybe a month) | The birth years agree (months too, if both publish one). Never a full-date confirmation. | false |
age_match | only an age | The age is consistent with the date you sent (within ±1 year). A plausibility check, not a confirmation. | false |
no_dob_age_year | nothing comparable | Nothing to check against — returned because the name matched. | true |
dob_mismatch | conflicting evidence | A date, year or age that conflicted with your query. Dropped — you never see this in records[]. | — |
matchState is "" when you queried no dob/age/birthYear. Every record also carries unverified, a coarse boolean twin: true iff matchState == "no_dob_age_year".
What you can send
dob(YYYY-MM-DD) — a full date. Matched against a full date, else a year, else an age; year and month are derived from it automatically.birthYear(integer) — a year on its own.birthMonth(1–12) — refines a year match when both sides publish a month; ignored unless a year is in play.age(integer) — checked against age-only records, ±1-year tolerance.dobtakes precedence;ageis consulted only when a record has no date and no year.
dobPrecision — what kind of birth evidence a record carries
Every record reports the precision of its own date of birth. dob.date is a full YYYY-MM-DD date or it is null — never a fabricated day. A source that publishes a 1/1 sentinel collapses to year (or age, or none); the January-1st is never emitted as a real birthday, so you can hand dob.date to a date parser without a length check.
| dobPrecision | dob.date | birthYear | age |
|---|---|---|---|
full | "1989-04-23" | 1989 | usually set |
month_year | null | 1989 | maybe |
year | null | 1989 | maybe |
age | null | null | the published age |
none | null | null | null |
Records we could not verify are KEPT and flagged, not dropped
When you filter by date of birth, a record with no date, year or age is returned anyway, because the name matched (matchState: "no_dob_age_year", unverified: true). Dropping it would hide a possible person just because a source is incomplete. So a DOB-filtered response is a mixture — dob_match, year_match, age_match and no_dob_age_year records side by side. Only a genuine conflict (dob_mismatch) is excluded.
const verified = res.records.filter(r => !r.unverified);
const candidates = res.records.filter(r => r.unverified);If you present the result as “confirmed matches”, the unverified records make that claim false. Branch on matchState for the full picture, or on unverified for the coarse one — and see Matching & confidence for how the state feeds matchConfidence.