Machine-readable endpoint contract.Verification Report
See a sample and verify a PDF locally.History API
Explore the separate History JSON and PDF endpoints.
How the Verification Report API works
The Audit Report API records what our data and live checks found when you ran it. Every request gets a new report ID. The API returns immediately; your application polls for completion, then retrieves the structured report or branded PDF. The PDF includes a Report ID and a link to check the exact issued file.
A report is evidence for review. It is not an identity adjudication, background-check decision, or determination of eligibility. Historical database records remain visible even when no current official source confirms registration.
| Endpoint | Access | Purpose |
|---|---|---|
POST /sexoffender/report/live | API key | Create an audit-ready Verification Report. |
GET /sexoffender/report/live | API key | List your account's reports, newest first. |
GET /sexoffender/report/live/{reportId} | API key | Poll status and retrieve the completed snapshot. |
GET /sexoffender/report/live/{reportId}/pdf | API key | Download the exact PDF after completion. |
GET /sexoffender/report/live/verify/{reportId} | Public | Get a minimal signed verification receipt. |
Base URL: https://api.offenders.io. Authenticate private endpoints with X-API-Key or Authorization: Bearer. Keep API keys on your server. The public receipt grants no access to the private report.
Create a report
Send JSON with either a record uuid returned by Search, or firstName and lastName with optional dob, state, city, zipcode, and address. Do not mix UUID and name fields. The broad query checks indexed candidates and fresh registry sources; the UUID request checks that one indexed record against live sources where supported.
Broad search
Content-Type: application/json
X-API-Key: {YOUR_API_KEY}
{
"firstName": "Jane",
"lastName": "Example",
"state": "CA"
}
Exact record UUID
Content-Type: application/json
X-API-Key: {YOUR_API_KEY}
{
"uuid": "5893a310-37ce-58d8-b101-39e76a60e94a"
}
A successful create returns 202 Accepted. It does not wait for the report or include the final evidence.
Content-Type: application/json
{
"report_id": "lr_0123456789abcdef0123456789abcdef",
"status": "queued",
"resource_uri": "/sexoffender/report/live/lr_0123456789abcdef0123456789abcdef"
}
Poll status and list reports
Poll resource_uri with the same account's API key. A queued or running report returns 200 with report_id, status, created_at, and resource_uri. A completed report also returns completed_at, the complete snapshot, signed_manifest, SHA-256 hashes, and pdf_uri. The completed JSON may be large. Read it as the full result; there is no candidate pagination within one report.
X-API-Key: {YOUR_API_KEY}
{
"report_id": "lr_...",
"status": "completed",
"created_at": "2026-09-25T17:00:00.000Z",
"completed_at": "2026-09-25T17:00:18.000Z",
"snapshot_sha256": "...",
"pdf_sha256": "...",
"pdf_uri": "/sexoffender/report/live/lr_.../pdf",
"snapshot": { "candidates": [ ... ], "source_coverage": { ... } },
"signed_manifest": { ... }
}
GET /sexoffender/report/live?limit=10 lists only your account's report metadata. The optional limit is 1–20 (default 10). When next_cursor is present, send it as cursor for the next page. List rows contain status, timestamps, resource URI, and a PDF URI when complete; open one report to read its evidence.
Polling is the complete default integration. A configured webhook may notify you of completion, but the authenticated GET remains authoritative. A webhook event contains no report body.
Download the PDF
After the report is completed, call pdf_uri with your API key. Success is 200 with Content-Type: application/pdf. Save the returned bytes as provided so the file hash remains verifiable. Before completion the endpoint returns 409; poll the JSON resource and try again.
X-API-Key: {YOUR_API_KEY}
Accept: application/pdf
There is no public or permanent PDF download URL. The QR code on a report opens the public verification page; it does not expose the PDF.
Understand the evidence
The snapshot contains the submitted query, generated time, source coverage, and all returned candidates. Each candidate contains public record fields, candidate_origin, and separate sources.nsopw and sources.state execution states. attempted_verified indicates a live observation by that source; attempted_not_found, attempted_unavailable, not_attempted_budget, and not_attempted_unsupported describe other outcomes. An indexed record alone does not establish current registration.
The report preserves matching historical evidence, including records no longer observed by a live source. State checks have a server-managed safety budget; any candidates not checked because of that budget are marked not_attempted_budget. If the indexed search is too broad to generate a complete report, the report fails with indexed_scope_too_large rather than silently truncating candidates. Narrow the query and create a new report.
Public PDF verification
The public receipt endpoint returns only receipt, signature, and public_key_pem. The receipt includes Report ID, issuance time, PDF SHA-256, signing key ID, and algorithm. It does not return names, searches, accounts, candidates, or PDF bytes. Only completed reports have public receipts. The Report ID is a locator, not proof that a particular PDF is genuine.
To verify a file, open Verification Report verification. Your browser extracts the Report ID and computes the selected PDF's SHA-256 locally, then checks the signed receipt; it does not upload the PDF. A green Verified result requires the entire file hash to match. A QR scan without the file confirms only that Offenders.io issued the Report ID.
Errors, privacy, and usage
HTTP errors use {"code": number, "message": string, "action": string}, except the intentionally opaque 404 for an unknown or other-account report. Missing authentication returns 401; invalid or unsupported create inputs return 400; ineligible testing or internal credentials and durable-retention restrictions return 403; rate limits return 429; a temporary service or artifact problem returns 503 with retry guidance. A completed report cannot be modified; rerun the request to obtain a new Report ID.
A failed job remains a 200 status resource with status: "failed", failure_code, message, and action. Narrow a search for indexed_scope_too_large, check the UUID for uuid_not_found, and follow the returned action for other failures. Do not interpret a failed job as a clean registry result.
Verification Reports are a free pilot and are not billed as ordinary Search or Extensive calls. Use an eligible production API key; testing and internal keys cannot create or retrieve them. Accounts configured for no-log retention cannot create durable reports. A HIPAA-enabled entitlement alone does not block this ordinary endpoint; it is not the dedicated HIPAA endpoint for PHI/ePHI workflows. Approved regulated uses still require their separate agreement and workflow.