Offendersearch
API Reference · v1.0.0

Freshness tiers & source coverage

Per-request freshness tiers, per-record lastCheckedAt, and the live coverage catalog.

Base URL https://api.offendersearch.appThis page as Markdown/docs/freshness.md

Freshness tiers

Freshness is an optional per-request freshness parameter with two values. It defaults to daily — the most current tier — billed at the base rate plus $0.01 per call. Pass weekly for the same dataset one tier behind, with no surcharge. Every record returns a lastCheckedAt either way, so currency is a value on the response rather than an assumption about the service.

TierWhat you getPriceBest for
daily (default)The most current coverage tierBase + $0.01 / callAnything where currency decides the outcome: pre-employment screening, tenant checks, live compliance
weeklyOne tier behind daily — identity fields are equivalentIncluded at base rate (no surcharge)Bulk and batch work, and periodic re-screens

Base is $0.15 per call, dropping to $0.11 after 2,000 calls a month; the default daily freshness adds $0.01 per call, and weekly freshness has no surcharge. See pricing for full details.

Which one to send

Send daily — the default — when currency decides the outcome. Pre-employment screening, tenant checks and live compliance all turn on the answer being current at the moment you ask.

Send weekly for bulk and periodic work. It is the same nationwide dataset one tier behind: identity fields — name, date of birth, offence history, aliases — are equivalent. For a nightly re-screen of a large roster, or a quarterly re-check, that is the right trade and it carries no surcharge.

Freshness is a per-request choice
{
  "query": { "firstName": "John", "lastName": "Doe", "dob": "1980-04-12" },
  "freshness": "daily"
}

Currency is answered per request, not per claim

Two fields carry it, and both are on every response. sources[].lastCheckedAt is when that jurisdiction’s copy of the record was last confirmed, and sourceStatus[].lastCheckedAt is the same question at the jurisdiction level for every jurisdiction the search touched — including the ones that returned no match. Read them rather than a general statement about the dataset: they are contract fields, and they answer the question for the exact record and the exact request in front of you.

Provenance on a record
{
  "source": {
    "jurisdiction": "NJ",
    "registryName": "State Sex Offender Registry",
    "recordUrl": "https://…",
    "scrapedAt": "2026-08-13T04:12:00Z",
    "lastCheckedAt": "2026-08-13T04:12:00Z",
    "sourceUpdatedAt": "2026-08-11T00:00:00Z"
  },
  "sources": [ /* one entry per corroborating jurisdiction */ ]
}

sourceUpdatedAt is the date the jurisdiction itself states it last changed the record; it is null where a jurisdiction publishes no such date. Running at volume? POST /v1/searches has no request-timeout ceiling, so every named jurisdiction runs to completion.

GET/v1/sourcesAuth: X-API-Key

List sources

The coverage catalog: every jurisdiction we cover, by code, name, and live health.

The live coverage catalog: every jurisdiction the API covers, with its code, display name, and health signals such as typical latency and last successful refresh. Use it to render your own coverage UI or to decide which jurisdictions to name.

What you can do
  • Coverage. Every jurisdiction with its code and name.
  • Health. Typical latency and last successful refresh timestamps, per jurisdiction.
Request
curl https://api.offendersearch.app/v1/sources \
  -H "X-API-Key: $OFFENDERSEARCH_KEY"
Response
200 OK
[
  {
    "id": "NJ",
    "name": "State Sex Offender Registry",
    "covers": ["NJ"],
    "health": { "lastSuccessAt": "2026-07-25T09:14:00Z", "typicalLatencyMs": 380 }
  },
  {
    "id": "CA",
    "name": "State Sex Offender Registry",
    "covers": ["CA"],
    "health": { "lastSuccessAt": "2026-07-25T09:14:00Z", "typicalLatencyMs": 410 }
  }
]