Workforce screening API
Screen a worker at sign-up, re-screen the roster on your schedule and hear about a new record in between, through one key. Criminal records from 1,934 live jurisdictions and 58 sex offender registries, $0.15 a search, monitors $3.00 a worker a month.
Updated November 8, 2026 · API changelog
POST /v1/criminal/search and /v1/search at sign-up$0.15 a searchPOST /v1/criminal/batch, 1,000 rows a call$0.11 past 2,000 a monthPOST /v1/monitors, signed webhooks$3.00 a worker a monthcurl -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" } }'
What does a workforce screening API return at sign-up?
The sandbox’s answer for its felony persona: one court case with a conviction, scored against the name and date of birth the worker typed.
{
"status": "complete",
"counts": {
"records": 1,
"recordsReturned": 1,
"sourcesQueried": 0,
"sourcesComplete": 0,
"sourcesIncomplete": 0,
"candidatesCapped": false,
"exclusionsIncluded": false,
"sourcesOnFile": 1567,
"sourcesPending": 347
},
"warnings": [],
"page": 1,
"perPage": 50,
"totalPages": 1,
"sourceStatus": [],
"cappedOmittedSources": [],
"omittedFields": [
"sourceData"
],
"legal": {
"notice": "Not a consumer report. This information may not be used for any purpose under the Fair Credit Reporting Act (15 U.S.C. § 1681 et seq.)."matchState (dob_match here), normalized.hasConviction and normalized.topSeverity. The cases[].charges[].disposition says how the case ended; a booking with no disposition is an arrest, not a conviction.Run it yourself with a test key ›A sign-up form gives you a name, a date of birth and usually a city or state. That is the whole query: it goes in query, the date of birth as YYYY-MM-DD, and the answer comes back in the same round trip with a status, the counts, one row per system in sourceStatus and the records. A platform that also wants the registries sends the same body to POST /v1/search; the two responses share the match fields, so one decision function serves both.
The rule that keeps a marketplace out of trouble is in the status and counts before any record: counts.sourcesIncomplete above zero means a system did not answer, and the response says partial. A worker is cleared on a complete answer, routed to review on a partial one, never cleared on silence.
| Onboarding question | Field |
|---|---|
| Is this record this applicant? | matchState, matchConfidence, matchBasis |
| Was anyone convicted of anything? | normalized.hasConviction, normalized.convictionCount |
| How serious? | normalized.topSeverity, cases[].charges[].severity |
| Is it open, pending or closed? | cases[].status, normalized.outcomes |
| Is the person in custody or wanted now? | currentStatus, currentlyIncarcerated |
| Did every system answer? | status, counts.sourcesIncomplete |
How do you screen a workforce in three API calls?
Sign-up, the scheduled re-screen, and the monitor. Each stage reuses the previous one’s identifiers.
- Stage 1, onboarding. One
POST /v1/criminal/searchand, where the role calls for it, onePOST /v1/searchfor the registries. StoresearchIdand each record’spersonRefwith the worker. - Stage 2, the re-screen. On your own schedule, send the active roster to
POST /v1/criminal/batchas aqueriesarray in a known order. Each result carries itsindex; diff the row’s records against the storedpersonRefset, and a newpersonRefis a new record to review. - Stage 3, the monitor. For workers who keep working between re-screens,
POST /v1/monitorswithproduct: "criminal". The201returns the webhook secret once; alerts arrive signed, and the history endpoint is the record.
The background checks for marketplaces tutorial walks all three stages against the sandbox; the bulk background checks from a CSV guide covers the batch endpoint’s CSV form for teams that export a roster from a spreadsheet.
curl -X POST https://api.offendersearch.app/v1/criminal/batch \
-H "X-API-Key: $OFFENDERSEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{
"queries": [
{ "firstName": "Felony", "lastName": "Record", "dob": "1975-06-15" },
{ "firstName": "Clear", "lastName": "Record", "dob": "1990-02-02" }
],
"match": "balanced"
}'
# results[] in input order, each with its 0-based index; a failing row is status "error" in place
# the registries: the same envelope to POST /v1/batchA batch runs on the stored answer, so there is no live charge inside it; a row that needs a confirmation with the jurisdiction goes through the criminal record verification API one at a time.
When is a re-screen a batch, and when is it a monitor?
They answer different questions. A batch says what is true on the day you run it; a monitor says when something changed.
| Scheduled re-screen (/v1/criminal/batch) | Person monitor (/v1/monitors) | |
|---|---|---|
| What it tells you | The state of the record on the day of the run | That a record appeared, changed or was removed since the last evaluation |
| Who it suits | The whole roster, including inactive workers | Active workers whose next shift is before your next batch |
| Unit of billing | One call per row: $0.15, $0.11 past 2,000 in the month | $3.00 a person a month, alerts included |
| How you learn | Results in the response, in input order | A signed monitor.alert webhook, plus GET /v1/monitors/{id}/alerts |
| Identity key | results[].index → personRef | monitor id → personRef |
| Live re-verification | Not offered inside a batch | Not part of a monitor; confirm a hit with a live search |
| Where to read more | Batch reference | Monitoring reference |
The cost table below works out both lines. The continuous criminal monitoring API page documents the webhook, the event catalogue and delivery in full.
What does a worker monitor look like when it is created?
The sandbox’s 201 for a criminal person monitor on the felony persona. The id is the handle for every later call.
{
"product": "criminal",
"type": "person",
"person": {
"firstName": "Felony",
"lastName": "Record",
"dob": "1975-06-15"
},
"channels": {
"email": "alerts@your-app.example.com"
}
}{
"id": "mon_5f67d9bde1f79980",
"product": "criminal",
"type": "person",
"minConfidence": null,
"label": null,
"status": "active",
"channels": {
"emails": [
"alerts@your-app.example.com"
]
},
"createdAt": "2026-11-08T15:49:29.914226+00:00",
"canceledAt": null,
"person": {
"firstName": "Felony",
"lastName": "Record",
"dob": "1975-06-15"
},
"sandbox": true
}product picks the dataset, type: "person" the predicate, and person is the same name and date of birth the onboarding search used. channels takes an email, several, or a webhookUrl; with a webhook the 201 also carries channels.webhookSecret, shown once. minConfidence is unset here, which means the default floor: year_match when a date of birth was sent. A platform that wants only identifications sets it to dob_match. The monitor a person with webhooks tutorial has the Express and FastAPI receivers.
Is a workforce screening API an FCRA consumer report?
It depends on what the platform does with the answer, not on the data. Two paths, two prices, the same records.
Data API, not FCRA
- 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: A trust-and-safety team re-screens a marketplace account after a report; nothing about a job depends on it.
Self-serve: get a key, then POST /v1/search or /v1/criminal/search.
FCRA Partner Access
- 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 staffing platform decides whether to place a candidate; the candidate consented and can dispute what came back.
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.
What does screening 1,000, 10,000 or 100,000 workers cost?
The graduated rate applied to a month’s searches, then the monitor line beside it. Change the volume in the calculator.
| Workers searched in a month | Search cost | If every one is also monitored | Total |
|---|---|---|---|
| 1,000 | $150.00 | $3,000.00 | $3,150.00 |
| 10,000 | $1,180.00 | $30,000.00 | $31,180.00 |
| 100,000 | $11,080.00 | $300,000.00 | $311,080.00 |
| Item | Price | Unit |
|---|---|---|
| Criminal or registry search, one worker | $0.15 | per call, the first 2,000 in a calendar month |
| Volume rate | $0.11 | per call past 2,000 in a calendar month |
| Free to start | 25 calls | once per account, on production data, no card |
| Sandbox | $0 | 60 calls a minute and 2,000 a day per test key |
| Person monitor | $3.00 | per person a month |
| FCRA order | $4.95 | per 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.
The first 2,000 calls in a calendar month are $0.15 each, every one after that $0.11. The 25 free calls on a new account are not subtracted here. Live re-verification, monitors and FCRA orders are billed separately.
A batch row is a call. The first 2,000 calls in a calendar month are $0.15; each one after is $0.11, which is why 100,000 searches cost $11,080.00 rather than 100,000 times the first-tier rate.
Worked examples by volume: background check API pricing · every rate: pricing.
How does it compare with Checkr for workforce screening?
Checkr sells finished consumer reports by package; this is a per-call records API with an FCRA path beside it. Both from the published pages, with the read date.
| Aspect | Checkr | OffenderSearch API |
|---|---|---|
| What you pay for | A finished consumer report, per report, by package; court and database fees passed through at cost | One API call: scored public records for a name and date of birth, in the same HTTP response |
| Published entry price | $29.99 a report (Basic) | $0.15 a call, $0.11 past 2,000 in a month |
| County courthouse searchwhere another vendor does more | Included in Essential ($59.99); as an add-on $25 a check, plus pass-through fees | No courthouse pulls. Statewide court sources in 48 states, plus live re-verification of named jurisdictions at +$0.02 a source |
| Free tierwhere another vendor does more | No free trial listed on its pricing page; a staging environment with mocked data is available on request | 25 calls on production data, no card; the sandbox at 60 calls a minute, 2,000 a day per test key, nothing billed |
| Test environment | a staging environment with mocked data, available once Checkr grants access (api.checkr-staging.com) | Self-serve sandbox with documented test people; mint an os_test_ key in the dashboard |
| Webhooks | webhooks signed with HMAC-SHA256 in an X-Checkr-Signature header; retries every minute for 10 minutes, then every hour for 24 hours | Async searches post the finished envelope to a webhookUrl; monitor and FCRA deliveries carry X-Offendersearch-Signature (HMAC-SHA256 over t.body), are retried and can be replayed |
| FCRA consumer reports | Yes: every report is a consumer report, $29.99 to $94.99 by package | Through FCRA Partner Access: $4.95 an order, searches and live checks included, no court fees |
| Continuous monitoring | Checkr offers continuous criminal search at $1.70 per individual a month and continuous MVR at $2.50 per driver a month | $3.00 a month per person, $10.00 per location, alerts by signed webhook |
Checkr: checkr.com/pricing and docs.checkr.com, read 2026-11-08. Each vendor’s pages are the authority on its product and change without notice; a blank is a fact the vendor does not publish, not a zero. A consumer report and a public-records lookup are different products.
The county row is the one to read honestly: a Checkr county criminal search is a courthouse pull, and this API does not do those. What it offers instead is statewide court sources in 48 states and live re-verification of a named jurisdiction. The Checkr API alternative page sets the two models side by side.
Where does a workforce screening search reach?
County jail rosters, statewide prison systems and statewide courts, by state; the registry column is the sex offender search on the same key.
The twelve states with the most live jurisdictions. A gig platform whose workers cluster in a few states should read those rows first.
| State | County jail rosters (live / catalogued) | Prison system | Courts | Registry |
|---|---|---|---|---|
| Kentucky | 119 / 121 | Statewide | Statewide | Kentucky registry |
| Texas | 84 / 104 | Statewide | Statewide | Texas registry |
| Ohio | 82 / 86 | Statewide | Statewide | Ohio registry |
| South Carolina | 72 / 73 | Statewide | Statewide | South Carolina registry |
| Indiana | 70 / 74 | Statewide | Statewide | Indiana registry |
| Pennsylvania | 69 / 71 | Statewide | Statewide | Pennsylvania registry |
| California | 66 / 71 | Statewide | Statewide | California registry |
| New York | 65 / 67 | Statewide | Statewide | New York registry |
| Missouri | 66 / 68 | Statewide | Statewide | Missouri registry |
| Montana | 61 / 72 | Statewide | Statewide | Montana registry |
| Virginia | 60 / 62 | Statewide | Statewide | Virginia registry |
| Florida | 57 / 63 | Statewide | Statewide | Florida registry |
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.
Which workforce platforms read which field?
Three shapes of workforce, and the one response field each one acts on.
Gig and marketplace platforms
Thousands of sign-ups a week and a shift tomorrow. The onboarding search runs inline; the field that gates activation is status: complete activates, partial queues for review. Active drivers and couriers get a monitor.
Staffing agencies
A candidate pool placed into many client sites with different rules. The agency re-screens by client with POST /v1/criminal/batch and reads normalized.topSeverity per row to apply each site’s threshold. Placement decisions run through FCRA Partner Access.
Contractor onboarding
A vendor portal that onboards technicians and caregivers. The registry search matters as much as the criminal one, so both endpoints run at sign-up and matchState on each decides between auto-clear and a human review.
Applicants rather than workers: the tenant screening API. Behind every stage here sit the criminal records API and the background check API hub.
Limits of a workforce screening API
Rate limits, the batch size, the response cap and what is not returned. Honest zeros are part of the product.
| Limit | Value |
|---|---|
| Sandbox, per test key | 60 calls a minute, 2,000 a day; nothing billed |
| Production, per key | No published ceiling. A 429 only when the service is at capacity, with Retry-After; a 429 is never billed |
| Records per response | Up to 4,000 in one answer; above that capped: true, and perPage pages through the rest |
| Batch | 1,000 rows a call; a failing row is reported in place and never stops the batch |
| Deadline | deadlineMs bounds the wait for slow jurisdictions; an unanswered one is named in sourceStatus and the answer says partial |
| Endpoints | POST /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 identity, employment or education verification, no drug or driving records. A workforce platform that needs those adds another vendor; this API is the criminal and registry layer.
Retry rules and backoff: rate limits, retries and idempotency · every status code: errors.
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.Workforce screening API questions
Batch mechanics, monitors, staging, billing and the FCRA line, in the words platform teams use.
How do I run a re-screen across the whole active roster?
Send the roster to POST /v1/criminal/batch (or /v1/batch for the registries) in chunks of up to 1,000 rows. Results come back in input order, each with its 0-based index, and a row that fails validation is reported in that position as status: "error" without stopping the rest and without being billed. Each row is billed as one call at the graduated rate, so a re-screen of 10,000 workers costs the same as 10,000 single searches in that month.
When should a worker get a monitor instead of a re-screen?
When waiting for the next batch is the risk. A person monitor costs $3.00 a month and reports a new, changed or removed record as a signed webhook when it is next evaluated; a batch tells you only on the day you run it. Many platforms monitor the active workers and batch the inactive ones.
Can one key serve sign-up, batch and monitoring?
Yes. The same X-API-Key header authenticates /v1/criminal/search, /v1/search, the two batch endpoints and /v1/monitors, and the sandbox mirrors all four with an os_test_ key. Keys carry no entitlements, so you can issue one per environment and revoke any one alone.
What does the platform receive when a monitor fires?
A monitor.alert POST signed with the monitor’s own secret, carrying event (new, changed, removed), the match label, the record summary and the personRef. The same alert is listed at GET /v1/monitors/{id}/alerts, so a missed delivery can be reconciled from the history.
How does the sandbox fit a staging environment?
Point staging at sandbox.offendersearch.app with an os_test_ key. The documented personas return the same shapes as production, including a felony conviction, an open warrant and a clear result; the sandbox allows 60 calls a minute and 2,000 a day per test key and bills nothing.
Which stage is a consumer report?
None of them through the standard key: each response says so in legal.notice. A platform that decides whether to activate, deactivate or place a worker on the strength of a record runs that step as an order through FCRA Partner Access at $4.95 an order, which adds consent, the notices and the dispute path.
Does a clear result cost the same as a hit?
Yes, a search is a search. A clear answer carries the evidence that makes it worth paying for: sourceStatus says which systems answered and counts.sourcesIncomplete says how many did not, so “clear” is never read off a search that was only partly answered.
Learn the API by example
Runnable guides that use this endpoint as the worked example.
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.
Screen your first worker on the sandbox
A key in seconds, the felony and clear personas, a two-row batch and a monitor. Nothing is billed until you switch to a live key.
The OffenderSearch APIs
One account, one key, one bill.