How to integrate a background check API
Eight steps from an empty project to a production integration: keys, the first call, matching rules, async and webhooks, batch, monitoring, errors, and keeping the evidence. Every step links to the reference.
curl https://api.offendersearch.app/v1/search \
-H "X-API-Key: $OFFENDERSEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{ "query": { "firstName": "John", "lastName": "Doe", "dob": "1980-04-12" } }'The eight steps
1. Create a key and keep it server-side
Sign up and create a key in the dashboard — it works immediately on the 25-search free trial. Send it as X-API-Key from your server, never from a browser or mobile app. Use one key per environment so you can rotate staging without touching production. Details: authentication.
2. Make the first call
POST /v1/search searches the sex offender registries; POST /v1/criminal/search searches criminal records. Same key, same request shape. Send a first and last name and — whenever you have it — a full date of birth. See the quickstart.
3. Decide with the match state, not the name
Every record says how it matched: full date of birth, birth year, age, or name only. Automate only on full-date matches and route everything else to a person. Treat any source in sourceStatus that did not answer as “not clear”. The matching rules and result completeness pages cover each case.
4. Use async for long searches
Live re-verification and broad searches can take longer than a request should wait. POST /v1/searches returns a searchId at once; poll GET /v1/searches/{id} or pass a webhookUrl and the finished result is posted to it. See async and webhooks.
5. Batch your lists
Screen a roster in one request with POST /v1/batch — CSV or JSON, up to 1,000 rows per call, billed per row. Criminal records have their own POST /v1/criminal/batch. See batch.
6. Monitor instead of re-screening
For people you keep — long-term staff, volunteers, contractors in a program you are entitled to screen — a monitor watches for changes and alerts you, for $3 a person a month. Locations can be watched too. See the Monitoring API.
7. Handle errors like a payment API
A 422 means the input was rejected — fix it, don’t retry. A 429 carries Retry-After. A 200 can still describe an incomplete search, which is why step 3 reads sourceStatus. See errors.
8. Store the evidence with the decision
Keep the record identifiers and source citations with whatever your team decided, so a later review can see exactly what was found. Request a verification PDF only when a document is needed for a file.
The integration in code
The pieces most integrations need, in the order you will write them.
// One rule set for every record the API returns.
function triage(record) {
if (record.matchState === 'dob_match') return 'auto'; // full date of birth agreed
if (record.matchState === 'year_match' ||
record.matchState === 'age_match') return 'review'; // a person looks
return 'review'; // name only: never automatic
}
// An unanswered source means "not clear", never "clear".
const incomplete = response.sourceStatus.filter((s) => !s.ok || s.incomplete);curl https://api.offendersearch.app/v1/searches \
-H "X-API-Key: $OFFENDERSEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": { "firstName": "John", "lastName": "Doe", "dob": "1980-04-12" },
"webhookUrl": "https://yourapp.example/hooks/offendersearch"
}'
# -> 202 { "searchId": "srch_9f2a7c", ... }
# poll GET /v1/searches/srch_9f2a7c, or receive the finished result at webhookUrlcurl https://api.offendersearch.app/v1/batch \
-H "X-API-Key: $OFFENDERSEARCH_KEY" \
-H "Content-Type: text/csv" \
--data-binary $'firstName,lastName,dob,state\nMaria,Garcia,1980-04-12,TX\nJohn,Doe,,NJ'curl https://api.offendersearch.app/v1/monitors \
-H "X-API-Key: $OFFENDERSEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{ "product": "sex-offender", "type": "person",
"person": { "name": "Maria Garcia", "dob": "1980-04-12" },
"channels": { "email": ["alerts@yourapp.example"] } }'switch (res.status) {
case 401: throw new Error('Check the X-API-Key header');
case 402: throw new Error('Billing is not enabled on this account');
case 422: return { declined: (await res.json()).detail }; // fix the input, don't retry
case 429: return retryAfter(res.headers.get('Retry-After')); // back off, then retry
}Integration checklist
- The key lives on the server and is different per environment
- Every request sends a full date of birth when you have one
- Only
dob_matchrecords are acted on automatically - Unanswered sources are shown as “not clear”, never as “clear”
- Long searches use
POST /v1/searches, not a long-held request - 422 is surfaced to the user to fix; 429 backs off using
Retry-After - Record identifiers and citations are stored with each decision
- Hiring and tenant decisions go through FCRA workflows, not the standard search
Making a hiring or tenant decision? Use an FCRA workflow.
FCRA workflows are built primarily for tenant screening and hiring decisions. If a result will help decide whether to hire someone or rent to them, the check has to run as an FCRA-regulated consumer report, with a permissible purpose, consent, accuracy controls and a dispute path for the person. Our standard search and API are not a consumer report. FCRA workflows run through FCRA Partner Access, for background check companies and screening platforms under a written FCRA agreement.
FCRA pricing is quoted per partner, so contact us for pricing.
Background check API integration questions
How long does it take to integrate a background check API?
The first working call takes minutes. A production integration — matching rules, async handling, batch and error handling — is typically an afternoon to a couple of days, depending on how much of your review workflow already exists.
Do I need a sandbox?
You can build against the free trial: 25 real searches, no card. Keys carry no entitlements, so create a separate key per environment and revoke any one without affecting the others.
Is there an SDK?
The API is plain REST with JSON, so any HTTP client works, and the OpenAPI specification is published for generating a typed client in your language. The docs show curl, Node and Python for every endpoint.
Should I call it from the browser?
No. Call it from your server and keep the key secret. Show your users the outcome your workflow decides on, not the raw records.
Can I migrate from another sex offender search API without rewriting my parser?
Yes. POST /v1/compat/sexoffender accepts the parameters and returns the envelope of legacy sex offender search APIs, so a switch is a base URL and key change. The migration guide maps every field.
What about hiring and tenant decisions?
Those are FCRA-regulated, so they run as FCRA orders through FCRA Partner Access rather than on the standard search endpoints. The FCRA API has its own order workflow, webhooks and dispute endpoint — contact us for pricing.
Related: background check API · background check API pricing · criminal background check API · employment background check API · API documentation
Make the first call in the next five minutes
25 free searches on real data, no card.
The Offendersearch APIs
One account, one key, one bill — the sex offender registry and criminal records, side by side.
Sex offender registry
- Sex offender API — One call across 58 US sex offender registries, with scored matches and a citation on every record.
- Sex offender search API — Endpoints, request shapes, record fields, matching and batch, in detail.
- Sex offender database — The national registry data in one schema — photos, aliases, offenses, addresses.
- Registered offender database — What a registered offender record holds, and how its accuracy is measured.
- Bulk sex offender search — Screen a whole list of names in one upload or one API call.
Criminal records
- Criminal records API — County, state and federal records — jail, prison, court and warrant — through one API.
- Criminal background check API — One cited answer per person for onboarding and screening flows.
- Criminal search API — The search endpoint itself: parameters, record types and coverage, call by call.
- Background check API — The registry and criminal layers together, on one key and one bill.
- Employment background check API — The registry and criminal data layer for HR, ATS and screening platforms.
- Bulk criminal record search — Run a list of names against criminal records in one call.
Build with it
- API documentation — Quickstart, every endpoint, the record object and the OpenAPI spec.
- Background check API pricing — $0.15 a call, $0.11 past 2,000 a month, 25 free calls to start — worked out by volume.
- MCP server for offender search — Give Claude and other AI agents the same search as a tool.
- Offendersearch vs offenders.io — A side-by-side comparison of the two registry APIs.