Sex Offender Search API · v1.0.0

Verification reports

A timestamped PDF of a search you already ran, with a source citation on every record. This is the document that goes in the file.

When to use this

When a search decided something — a visitor was admitted, a volunteer was cleared, a candidate was escalated — the file needs more than a searchId in a database. POST /v1/report renders one consolidated PDF for a search on your account: who was viewing it, what was asked, each registrant that matched, with every field on file, a source citation on each record, and the legal notice. You will build the step that requests the PDF from the searchId you stored, saves it with its X-Report-Id, and does so inside the window that makes it possible.

Before you start

  • A test key, or a dashboard session — this route accepts either. The sandbox renders the production PDF for the sample people, without photographs, and bills nothing.
  • A searchId from a prior POST /v1/search or POST /v1/searches on the same account, created within the last 7 days. Batch rows have no searchId and cannot be reported on.
  • Price: one PDF charge ($0.02) on top of the search that was already billed. The legacy one-shot mode — an inline query instead of searchId — runs a new search and bills a call as well (pricing).
The one thing people get wrong. The window is 7 days, shorter than the 14-day retention of stored results. A report request for an older search answers 410. Request the PDF when the decision is made, not when the audit arrives.

Step by step

  1. Run the search and keep the `searchId`. Search Exact Match with dob 1980-01-01. Store searchId.
  2. Request the report. POST /v1/report with the searchId and the optional viewer, purpose and reference fields. The body of the 200 is the PDF.
  3. Save it with its id. Read X-Report-Id (rpt_ + 12 hex) and Content-Disposition from the headers; store the id next to the searchId.
  4. Handle the refusals. 404 for a searchId this account never ran; 410 past 7 days; 400 when neither searchId nor query was sent.

Step 2 — the request

curl -s -D headers.txt -o report.pdf https://sandbox.offendersearch.app/v1/report \
  -H "X-API-Key: $OFFENDERSEARCH_KEY" -H "Content-Type: application/json" \
  -d '{"searchId": "srch_7a89158926d834f43f66856f",
       "viewerName": "Admissions desk", "viewerEmail": "desk@example.com",
       "purpose": "Visitor screening", "reference": "visit-2026-10-25-0417"}'
grep -i "x-report-id\|content-disposition" headers.txt
200 — response headers
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="offendersearch-verification-rpt_97a079557016.pdf"
X-Report-Id: rpt_97a079557016

The body is the PDF, not JSON. viewerName, viewerEmail, purpose and reference are optional and are printed at the top of the document as a record of who ran it and why; they are not an access gate. requesterName is a legacy alias of viewerName.

What the PDF contains

  • The report id and the time it was generated; the viewer identity, purpose and reference you sent.
  • The query as it was run and the registries searched.
  • Every matching registrant with every field on file: names and aliases, date of birth or age and how it matched, addresses and jurisdiction, offenses and risk designation, photograph where available, and the extended per-state fields.
  • A source-attribution section with a citation on every record — the registry and the page it came from.
  • A legal notice: informational use only; not a consumer report; the use restrictions.

Step 4 — the refusals

{ "detail": "No search found for that searchId on this account." }

Reading the result

WhereFieldKeep it for
HeaderX-Report-Id (rpt_ + 12 hex)The document's identity; printed on the PDF. Store with the searchId.
HeaderContent-DispositionThe suggested filename, offendersearch-verification-{reportId}.pdf.
RequestsearchIdWhich search the report cites. It must be on this account and under 7 days old.
RequestviewerName, viewerEmail, purpose, referencePrinted on the first page: who, why, and your case id.
Request (legacy)query, jurisdictions, locationScopedOne-shot mode: runs and bills a new search. Prefer searchId.

Edge cases and pitfalls

  • The report re-runs a reduced form of the query at report time — firstName, lastName, dob, age, city, state, zipcode, jurisdictions, locationScoped — against the data at that moment. A search that used county, a radius, q, nameMatch/prefixMatch, a non-default match, a live block or a clearance scope can produce a PDF that differs from the envelope you read. Request the report promptly, and for a live decision also keep the evidence documents.
  • Batch rows cannot be reported. Re-run the person with POST /v1/search to obtain a searchId.
  • 7 days, not 14. /results keeps records for 14 days; /report accepts a searchId for 7.
  • It is one PDF per search, not per registrant; a search with three candidates yields one document listing all three.
  • Trial accounts can call /report; the route has no paid-entitlement gate and the PDF is metered at the PDF rate rather than as a trial unit, so expect it on the first invoice.
  • Proof documents are a different thing. POST /v1/searches/{searchId}/proof renders per-registry look-alike documents for named registries and requires billing; it is an internal add-on, not the verification report. See Verification reports for the distinction.
  • Not FCRA. The notice printed on the document says so: this report is not a consumer report and must not be the sole basis for an employment, housing, credit or insurance decision. That path is the FCRA Partner API.

Production checklist

  • The report is requested in the same workflow step that records the decision, inside 7 days.
  • X-Report-Id stored with searchId, recordIds and the reviewer's verdict.
  • viewerName/purpose/reference filled from your own case data so the first page answers the auditor's questions.
  • PDFs stored under your own retention policy; the platform keeps the search 14 days.

Product overview