OffenderSearch
Criminal record verification API · for screening providers and CRAs

Criminal record verification API

Confirm a criminal record with the jurisdiction that holds it before it goes on a report. One live block on the search you already send; $0.02 per source that answers, never more than $2.00 a search, with the citation and the check time on each record.

Get a free API keyRead the docs25 free calls · no card

Updated November 8, 2026 · API changelog

The one change that makes it a verification
{
  "query": { "firstName": "Felony", "lastName": "Record", "dob": "1975-06-15" },
  "live": {
    "jurisdictions": ["US-DOC"],   // the systems to ask again, by code
    "evidence": "pdf"              // keep a document of what each one answered
  }
}
Run the cached version on the right; add the block when the answer must be defended.
POST /v1/criminal/search · sandbox
curl -X POST "https://sandbox.offendersearch.app/v1/criminal/search" \
  -H "X-API-Key: $OFFENDERSEARCH_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "query": {
        "firstName": "Felony",
        "lastName": "Record",
        "dob": "1975-06-15"
      }
    }'
One court case: a felony burglary conviction with case number, court, charges, plea, disposition and sentence. DOB-verified.Sandbox people are synthetic; production answers have the same shape.
1,934live jurisdictions a search can name, of 2,131 catalogued as of 2026-11-08
$0.02per completed live source, on top of the call
$2.00ceiling for live checks on one search
54statewide prison systems; courts in 48 states
$0.02per verification PDF of a search

A verified criminal record in JSON, from the sandbox

The same search as the hero, with live.jurisdictions set to the federal prison system. Read sourceStatus first: it says who was asked and who answered.

POST /v1/criminal/searchsandbox scenario “Felony conviction, verified live” · query {"firstName":"Felony","lastName":"Record","dob":"1975-06-15","live.jurisdictions":"US-DOC","live.evidence":"pdf"}
200 OK · the sandbox's answer, captured from its code
{
  "status": "complete",
  "counts": {
    "records": 1,
    "recordsReturned": 1,
    "sourcesQueried": 1,
    "sourcesComplete": 1,
    "sourcesIncomplete": 0,
    "candidatesCapped": false,
    "exclusionsIncluded": false,
    "sourcesOnFile": 1934,
    "sourcesPending": 197
  },
  "warnings": [],
  "page": 1,
  "perPage": 50,
  "totalPages": 1,
  "sourceStatus": [
    {
      "code": "US-DOC",
      "source": "US-DOC",
      "ok": true,
      "incomplete": false,
      "incompleteReason": null,
The usage block at the end is the bill for the live part: one completed check, $0.02. The sandbox person’s stored record is a county court case, so the federal system reports records: 0 and live: true: a defensible “not held there” rather than a blank.Run it yourself with a test key ›
FieldTypeWhat it tells you
sources[].codestringThe jurisdiction that holds the record, as a neutral code (US-DOC, OH-SAMPLE). The same code goes in live.jurisdictions.
sources[].levelstringcounty, state or federal: which tier of system answered.
sources[].recordUrlstringThe jurisdiction’s own page for the record, so a reviewer can open the original.
sources[].lastCheckedAtdatetimeWhen that system was last asked about this record. On a live check it is the moment of your request.
sources[].livebooleantrue when this answer came from the jurisdiction during your request; false when it is the stored copy.
sourceStatus[]arrayOne row per system named in live.jurisdictions: ok, incomplete, incompleteReason, records and live: true.
dobVerificationenumrecord when the record carries birth evidence; source_confirmed when the jurisdiction confirmed your date on a live check; source_not_confirmed when it did not.
usage.liveChecks, usage.liveChargeUsdnumberHow many live sources completed and what they cost on this search; a source that did not answer is not counted.
lifecycle.droppedOutbooleanWhether the jurisdiction has stopped listing the record. The record is kept and flagged, never silently removed.
personRefstringA stable handle for the person across searches and monitors, so a re-verification months later can be tied to the same subject.
These are the fields a verification reads. Every key is always present; a value the jurisdiction did not publish is null.The whole record object ›

How live re-verification of a criminal record works

Three steps inside one request. The cached answer is the baseline; the live block tells the API which systems to ask again, and the merged response says which ones did.

  1. The cached search runs first. Name, date of birth and the places you hold go in query; the stored records come back scored with matchState and matchConfidence. This is the $0.15 call.
  2. The live block names what to re-check. live.jurisdictions is a list of codes; live.scope: "matched" means “whichever systems hold a matching record”. Each named system is asked during your request, and its own candidates are scored against your query.
  3. The answers are merged and labelled. A record confirmed live carries sources[].live: true and a new lastCheckedAt; a system that did not answer is incomplete in sourceStatus and not billed. Up to two in-request systems answer inline (200); more run as a job you poll (202).
You asked forWhat you are billed
The cached search only$0.15 a call
Live, 1 system answered$0.15 + $0.02
Live, 3 named, 2 answered$0.15 + $0.04
Live, 120 answered$0.15 + $2.00 (the ceiling)

A failed live check is reported, not hidden, and not billed. The reference: live and async searches.

Provenance on each record: which system, which tier, which page, when

A CRA’s reviewer needs to open the original and write down when it was checked. Both are on the record, not in a separate report.

Each record lists the systems that hold it in sources[], and each entry names the jurisdiction by a neutral code, its tier (county, state, federal), the jurisdiction’s own page for the record and the time it was last asked. A person held by a county jail and later a state prison comes back as one record whose sources list both systems, each with its own link.

externalId is the jurisdiction’s own number prefixed with its code; personRef is a stable handle for the person that survives a renumbered listing, and the key a continuous criminal monitoring API alert carries back to the subject you verified.

Question a reviewer asksField that answers it
Where does this record come from?sources[].code, sources[].level
Can I see the original?sources[].recordUrl
When was it last confirmed?sources[].lastCheckedAt
Was it confirmed during my request?sources[].live, liveChecked
Is it still listed by the jurisdiction?lifecycle.presentInLastSweep, lifecycle.droppedOut
Did the jurisdiction confirm my date of birth?dobVerification
Is this the same person as last time?personRef, externalId

Why the date of birth decides whether a hit is an identification: date of birth in the criminal search.

Evidence a background check provider can hand to a client

Three artefacts, each from a documented endpoint, each priced. The one your client can check without trusting you is the signed receipt.

ArtefactHow you get itPriceWho can check it
Verification PDF of a searchPOST /v1/criminal/report with the searchId, within 7 days. Lists the criteria, each matching record and a source citation per record.$0.02 a documentYour reviewer and your client; the search was already billed, only the PDF is metered.
Registry evidence documentsPOST /v1/search with live.evidence: "pdf": one document per named registry, downloaded from GET /v1/searches/{id}/evidence/{jurisdiction}.pdf. Always asynchronous.$0.25 per completed document, $5.00 ceiling a searchAnyone you send the document to; the live evidence reference explains the hash on each.
FCRA report with a signed receiptGET /v1/fcra/orders/{id}/report?format=pdf for the stored PDF; GET /v1/fcra/receipts/{orderId} for the Ed25519-signed receipt over its fingerprints.Included in the $4.95 orderAnyone holding the PDF, with no key and no upload, at /verify or with OpenSSL against the published key.

The receipt is built for hand-offs: a report PDF passes from a screening company to an employer to an applicant, and each hop is a chance for the file to be edited or swapped. The receipt signs the order id, the completion time, the control version and the SHA-256 fingerprints of the report and the PDF; it holds no personal data, so it can be public.

The PDF response carries its fingerprint in an X-PDF-SHA256 header; the JSON report carries an integrity block with reportSha256, pdfSha256, receiptUrl and verifyUrl. A change to the report writes a new revision with its own receipt, and earlier revisions stay fetchable with ?revision=N.

The verification PDF is the lighter artefact for the data API: your report of public-record data, labelled as such, with a source-attribution section and a legal notice. Registry evidence documents belong to the sex offender API on the same key: a registry named in live.jurisdictions on POST /v1/search with evidence: "pdf" produces one document per registry, each with its own billed and chargeUsd.

Disputes and corrections on a verified criminal record

A verification API that cannot take a record back is half a product. Here is the path, endpoint by endpoint, and what each step does to the report.

Under FCRA Partner Access a consumer disputes a furnished record from the consumer portal or your own interface, and your system opens it with POST /v1/fcra/orders/{id}/disputes, naming the record ids, a reason and the consumer’s statement. The record is re-checked with the court or agency that holds it. The outcome arrives within 30 days; the consumer receives a receipt when the dispute opens and the resolution when it closes.

The result changes the report, not just a flag. A dispute resolved verified leaves the report as it was. One resolved modified, deleted or unable_to_verify rebuilds the report without the record, re-renders the PDF, and signs a new receipt for the new revision; order.revised tells your system it happened. Any adverse action pending on the order pauses while a dispute is open and is cancelled if the report it rested on changed.

The FCRA dispute API page documents the dispute object; a person described by a record found through the standard key can report a record problem.

StepEndpointWhat changes
Re-check one search on an orderPOST /v1/fcra/searches/{id}/reverifyA new search of the same type supersedes the old one; the order completes again with a new report, PDF and receipt.
Open a disputePOST /v1/fcra/orders/{id}/disputesThe record is re-checked with its jurisdiction; the consumer receives a receipt; adverse action pauses.
Read it backGET /v1/fcra/orders/{id}/disputesStatus, resolution and the record it concerns.
A changed reportGET …/report?revision=NEach revision keeps its PDF and its receipt; the latest is the default.
Its receiptGET /v1/fcra/receipts/{orderId}?revision=NPublic, no key, no personal data; signs the revision number.

Criminal record verification coverage by state

What a live block can name: county jail rosters, statewide prison systems, statewide courts and warrant systems. A live jurisdiction answers a search today.

The twelve states with the most live jurisdictions. Each state links to its criminal records by state page.

StateCounty jail rosters (live / catalogued)Prison systemCourtsWarrants
Kentucky119 / 121StatewideStatewide—
Texas84 / 104StatewideStatewideStatewide
Ohio82 / 86StatewideStatewideStatewide
South Carolina72 / 73StatewideStatewideStatewide
Indiana70 / 74StatewideStatewide—
Pennsylvania69 / 71StatewideStatewideStatewide
California66 / 71StatewideStatewideStatewide
New York65 / 67StatewideStatewideStatewide
Missouri66 / 68StatewideStatewide—
Montana61 / 72StatewideStatewide—
Virginia60 / 62StatewideStatewideStatewide
Florida57 / 63StatewideStatewideStatewide

Jurisdictions in our catalogue as of 2026-11-08; a live jurisdiction answers a search today. Approximate, not an official figure. Showing the 12 states with the most live jurisdictions; the full list is in the criminal coverage reference.

A verification can only confirm a record with a system that publishes it; coverage.sourcesPending on each response counts the catalogued systems not yet answering. A confirmation is also a statement about one moment, which is what a monitor is for afterwards.

Data API or FCRA Partner Access for a criminal record verification

The records and the live check are the same on both paths. What differs is whether the result may be furnished for a decision about a person.

Path 1

Data API, not FCRA

$0.15a call, 25 free, no card
  • For: visitor and volunteer screening, trust and safety, research, monitoring, and software that shows a public record to the person who asked for it.
  • Must not decide: whether someone is hired, housed, insured or given credit. The response is a public-records lookup, not a consumer report, and the key is not approved for those uses.
  • Example: An admissions desk screens a visitor against the registries before a visit; no hiring, housing or credit decision is involved.

Self-serve: get a key, then POST /v1/search or /v1/criminal/search.

Path 2

FCRA Partner Access

$4.95per order, searches and live checks included, no court fees
  • Built in: end-user registration with a permissible purpose, consent on every order, the pre-adverse and adverse-action notices with the consumer’s copy, and a consumer portal.
  • Disputes: a dispute endpoint; the record is re-checked with the registry or court that holds it, with an outcome inside 30 days, and a correction reaches every partner that received it.
  • Example: A screening company furnishes a report an employer or landlord will act on; the order runs the consent, notice and dispute steps.

Under a written agreement: Request FCRA Partner Access.

The records can be the same; the process around them is not. How the program works: FCRA Partner Access · the orders endpoint: FCRA orders API · reference and statute citations: FCRA docs. This page describes the product, not legal advice.

Criminal record verification API pricing

The call, the live check and the artefacts are separate lines, each metered only when it completes.

ItemPriceUnit
Live re-verification+$0.02per completed live source, $2.00 ceiling per search; a source that did not answer is not billed
Criminal search (cached answer)$0.15per call, the first 2,000 in a calendar month
Free to start25 callsonce per account, on production data, no card
Sandbox$060 calls a minute and 2,000 a day per test key
FCRA order$4.95per order; sex offender and criminal court search included, with no court fees or extra charges

No minimum on search. The Map API has its own $300 monthly minimum. No seats, no platform fee, no per-state fee; a batch row is billed as one call.

Verification PDF of a search: $0.02 a document. Registry evidence document: $0.25 each, $5.00 ceiling a search. Sandbox searches, live blocks and reports are never billed.

Worked examples by volume: background check API pricing · every rate: pricing.

Where a verification API fits in a screening provider’s pipeline

Three places teams put the live block, and the one field each one reads.

Before furnishing a hit

A stored record matched a candidate. The pipeline re-sends the search with live.scope: "matched" and furnishes only records whose sources[].live is true. The field that decides: sourceStatus[].ok.

FCRA-compliant background check data ›

Refreshing an old hit

A record first seen a year ago comes up again. Rather than trusting lastCheckedAt, the provider names the jurisdiction in live.jurisdictions and reads lifecycle.droppedOut to learn whether the jurisdiction still lists it.

criminal records API ›

A date of birth the record lacks

A county publishes no birth dates. The live check asks the county whether it holds the record under the date you sent; dobVerification: source_confirmed lifts it to dob_match, source_not_confirmed keeps it ranked below.

matching rules ›

Whole rosters start from the workforce screening API; an open-warrant question from the warrant search API; both share the key and record object of the background check API hub.

Limits of a criminal record verification API

Rate limits, the response cap, what a 429 looks like, and what the API does not return.

LimitValue
Sandbox, per test key60 calls a minute, 2,000 a day; nothing billed
Production, per keyNo published ceiling. A 429 only when the service is at capacity, with Retry-After; a 429 is never billed
Records per responseUp to 4,000 in one answer; above that capped: true, and perPage pages through the rest
Batch1,000 rows a call; a failing row is reported in place and never stops the batch
DeadlinedeadlineMs bounds the wait for slow jurisdictions; an unanswered one is named in sourceStatus and the answer says partial
EndpointsPOST /v1/criminal/search; one X-API-Key header
  • No civil cases, no traffic citations. Criminal records only: jail bookings, prison custody, court cases with dispositions, warrants, and the registries.
  • No international records. US county, state and federal sources, and the 58 US registries.
  • Not a consumer report. A hiring, housing, credit or insurance decision runs as an order through FCRA Partner Access, not through the standard key.
  • No SSN, no credit, no verifications, no drug or driving records. Scope comes from the name, the date of birth and the places you already hold.
  • No verification of a record the jurisdiction does not publish. A live check asks a system about what it lists; it cannot confirm a sealed or unpublished case.
  • Live checks are not offered inside a batch. POST /v1/batch reads the stored answer; send the rows that need confirming one at a time with a live block.

Retry rules and backoff: rate limits, retries and idempotency · every status code: errors.

What a rate-limit answer looks like
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
  "detail": {
    "code": "overloaded",
    "retryAfterSeconds": 12
  }
}
Nothing was searched and nothing was billed; wait retryAfterSeconds and send the same request again.

Criminal record verification API questions

Billing, scopes, status codes, evidence and disputes: the questions a CRA’s engineering team asks before a pilot.

What does "completed source" mean on the invoice?

A live source is billed only when the jurisdiction answered inside your request. One that timed out, refused or returned an error is named in sourceStatus with incomplete: true and costs nothing. The charge is $0.02 per completed source with a $2.00 ceiling on one search, on top of the $0.15 call.

Can I re-verify only the jurisdictions where the cached search found something?

Yes. Send live: { "scope": "matched" } instead of a jurisdictions list and only the systems holding a matching record are re-checked. If the cached answer found nothing, the API returns 422 no_live_sources rather than billing an empty live pass.

Why did my live search come back 202 instead of 200?

Up to two systems that can answer inside a request run inline and return 200. More systems, or one that cannot answer in-request, run as a job: 202 with a searchId, polled at GET /v1/criminal/searches/{searchId}. Most jurisdictions are in the second group, so build for 202.

How long can I make the verification PDF after a search?

For 7 days. POST /v1/criminal/report takes the searchId and returns a document that lists the criteria, each matching record and a source citation per record, billed at $0.02. Because the search was already billed, only the PDF is metered.

Who can check a signed receipt, and what does it reveal?

Anyone with the report ID, without a key: GET /v1/fcra/receipts/{orderId} is public, and the verify page runs the same check in a browser. The receipt holds the order id, the completion time, the control version and the report and PDF fingerprints. It contains no name, date of birth or record.

What happens to a record a consumer disputes?

On an FCRA order, POST /v1/fcra/orders/{id}/disputes opens the dispute. The record is re-checked with the court or agency that holds it, the outcome arrives within 30 days, and a record that is modified or deleted produces a revised report with its own receipt. Any adverse action on the order pauses while the dispute is open.

Is a verification through the standard key a consumer report?

No. The response carries a legal.notice saying so. A record that will be furnished for a hiring, housing, credit or insurance decision runs as an order through FCRA Partner Access at $4.95, which runs the live re-verification, the evidence and the receipt as part of the order.

Learn the API by example

Runnable guides that use this endpoint as the worked example.

Criminal records by name and date of birth ›Why the date of birth decides whether a hit is an identification or a lead.
Background check API response explained ›Every field of a real sandbox response, group by group.
No-match and multiple-match results ›The three shapes of "nothing", possibles, and a decision table per matchState.
FCRA adverse action with an API ›Adverse items, the pre-adverse notice, the waiting period and the post-adverse notice, endpoint by endpoint.
Test a background check integration ›The sandbox scenario matrix, a test suite, CI and the switch to production.
Rate limits, retries and idempotency ›429 semantics, backoff that honours Retry-After, and why a repeated POST is a second search.

All guides: Learn APIs by example · reference: developer docs · packages: SDKs and CLI.

Related background check API pages

The rest of the developer surface, one anchor per page.

Background check API ›Criminal records and 58 US sex offender registries on one key, per call.
Criminal records API ›Court cases, jail bookings, prison custody and warrants as JSON.
Sex offender API ›One POST across 58 US registries, scored and cited.
Free background check API ›25 free calls on real data, no card, plus the free sandbox.
Employment screening API ›The public-records stage of a hiring pipeline, and the FCRA path for the decision.
Tenant screening API ›The registry and criminal layer behind a rental application.
Inmate search API ›State prison and county jail custody records.
Background check API pricing ›Costs from 100 to 100,000 searches a month.
Public API for testing ›A free sandbox with documented test people in the production shape.
SDKs: Python, Node, CLI ›Client status and the method surface, one per endpoint.
Postman collection ›Every endpoint with sandbox bodies pre-filled.
MCP server ›Registry and criminal lookups as tools for Claude, Cursor and agents.

Verify your first criminal record against the sandbox

Mint an os_test_ key, send the felony scenario with a live block, and read usage.liveChecks. Nothing is billed.