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.mdFreshness 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.
| Tier | What you get | Price | Best for |
|---|---|---|---|
| daily (default) | The most current coverage tier | Base + $0.01 / call | Anything where currency decides the outcome: pre-employment screening, tenant checks, live compliance |
| weekly | One tier behind daily — identity fields are equivalent | Included 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.
{
"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.
{
"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.
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.
- Coverage. Every jurisdiction with its code and name.
- Health. Typical latency and last successful refresh timestamps, per jurisdiction.
curl https://api.offendersearch.app/v1/sources \
-H "X-API-Key: $OFFENDERSEARCH_KEY"[
{
"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 }
}
]