Order statuses and retrieving results
A search ends in one of three results, and every record it did not furnish has a reason code. Read the status, then the result, then the withheld counts.
What you’ll build
The result reader: code that walks an order’s searches, classifies each as clear, records_found or incomplete, reads the furnished records from GET /v1/fcra/orders/{order_id}/searches/{search_id}, and explains every withheld record by its reason code. You will use the sandbox subjects Records, Withheld and Unavailable to see all three outcomes.
Furnished records are the product’s own record object plus FCRA fields; the controls that decide furnishing versus withholding are documented in full in Controls & reason codes — this guide shows you how to read their output.
Before you start
- Three completed sandbox orders (see Creating screening orders): Pat Records with both searches, Pat Withheld with a criminal search, Pat Unavailable with a sex-offender search.
- Records appear only on
GET /v1/fcra/orders/{order_id}/searches/{search_id}and in the report — never on the order object. - Order statuses:
received,in_progress,partial,complete,cancelled,error. Search statuses:queued,in_progress,complete,unavailable,error,cancelled,superseded. Search results:clear,records_found,incomplete(nulluntil finished and onerror).
result: "clear", recordCount: 0 and non-empty withheld counts. The counts explain; they are not records and are never shown to the consumer.Step by step
- Read the order.
GET /v1/fcra/orders/{order_id}. Stop whenstatusiscomplete,errororcancelled;partialmeans keep waiting. - Classify each search.
statusfirst:completeandunavailableare finished;errorhas no result. Thenresult:records_found→ read records;clear→ checkwithheld;incomplete→ readincompleteReasonsandcoverage. - Read the records.
GET /v1/fcra/orders/{order_id}/searches/{search_id}returnsrecords[]: each is the product record plusrecordId,type,matchBasis,retrievedAt,verifiedAt, and on criminal recordsdispositionStatus, per-chargefcraDispositionandfcraRedactions. - Read the coverage.
coverage[]has one row per source:mode(live/snapshot),status(answered/unavailable/not_searched),relevant,restricted,candidates,furnished,withheld,captureIds[].
curl https://sandbox.offendersearch.app/v1/fcra/orders/fo_ee0b34c5b52fd35b/searches/fs_9c03d7e1a4b6f258 \
-H "X-API-Key: $OFFENDERSEARCH_TEST_KEY"{
"id": "fs_9c03d7e1a4b6f258",
"type": "criminal",
"status": "complete",
"result": "records_found",
"recordCount": 1,
"withheld": {},
"createdAt": "2026-10-25T14:01:07.318402+00:00",
"startedAt": "2026-10-25T14:01:07.402118+00:00",
"completedAt": "2026-10-25T14:01:07.455930+00:00",
"supersededBy": null,
"coverage": [],
"incompleteReasons": [],
"records": [
{
"recordId": "sandbox:criminal:records-1980-01-01",
"type": "criminal",
"matchBasis": { "state": "dob_match", "identifiers": ["name", "dob"] },
"retrievedAt": "2026-10-25T14:01:07.455930+00:00",
"verifiedAt": "2026-10-25T14:01:07.455930+00:00",
"sandbox": true,
"name": { "first": "Pat", "last": "Records", "full": "Pat Records" },
"dob": "1980-01-01",
"sources": [{ "code": "ZZ-SANDBOX", "level": "county", "live": true }],
"state": "ZZ",
"dispositionStatus": "conviction",
"cases": [
{ "caseNumber": "SBX-0001", "court": "Sandbox County Court", "filedDate": "2021-03-04",
"charges": [
{ "description": "Sandbox charge (test data)", "level": "misdemeanor", "disposition": "Guilty",
"dispositionDate": "2021-09-10", "fcraDisposition": "conviction" }
] }
]
}
]
}{
"id": "fs_1e7b4c9a3d5f2086",
"type": "criminal",
"status": "complete",
"result": "clear",
"recordCount": 0,
"withheld": { "insufficient_identifiers": 2, "not_current_at_source": 1 },
"incompleteReasons": [],
"records": []
}{
"id": "fs_7a2d9e4c1b6f3058",
"type": "sex_offender",
"status": "unavailable",
"result": "incomplete",
"recordCount": 0,
"withheld": {},
"incompleteReasons": ["live_unavailable"],
"records": []
}Sandbox searches have empty coverage because they make no live calls; a production search lists every source consulted. The production coverage shape is in Results & records.
Reading the result
| Field | Values | What it decides |
|---|---|---|
result | records_found | At least one record passed every control and was re-verified. Read records[]. |
result | clear | Nothing was furnished. withheld may be non-empty — candidates existed but failed a control. |
result | incomplete | A relevant source could not be searched live or a record could not be re-verified; never clear. incompleteReasons ⊆ source_unanswered, live_unavailable, verification_unavailable. |
withheld | reason → count | insufficient_identifiers (no exact date-of-birth match), jurisdiction_restricted, disputed_suppressed, not_current_at_source, verification_unavailable; criminal adds obsolete_non_conviction, obsolescence_undeterminable, time_limited. |
records[].matchBasis.state | dob_match | Always: only exact-date-of-birth records are furnished. |
records[].dispositionStatus | conviction, non_conviction, sanction, mixed, unknown | Criminal only, across furnished charges. sanction is an administrative exclusion-list record, furnished only with exclusions: "all". |
records[].fcraRedactions | reason → count | Charges removed from a furnished record by the time rules. |
controlVersion (order) | fcra-controls-2026-10-19.1 | The rule set the order ran under; the evidence record pins a hash of the exact rules. |
Edge cases and pitfalls
- `partial` is not final. One search finished, another is running. Keep waiting for
order.completed. - `status: "unavailable"` is finished. Its
resultisincomplete; the order still completes. Decide what an incomplete check means for your workflow before go-live. - `error` has `result: null` and is reported by
search.completedwithstatus: "error"and noresult. Read it; do not inferclear. - Superseded searches (after a re-verify) stay on the order with
status: "superseded"andsupersededBy; skip them and read the new search. - Exclusion-list records are criminal records with
recordType: "healthcare_exclusion"; a conviction-based one readsdispositionStatus: "conviction", an administrative one"sanction"and appears only underexclusions: "all". A list entry with no date of birth is withheld asinsufficient_identifiers. - `corrections[]` appears on a record a resolved dispute modified; show it with the record.
- `restricted: true` in a coverage row means a registry whose records are withheld for the order’s purpose; it was not searched live and does not make the result incomplete.
Production checklist
- Branch on
statusbeforeresult; treatincompleteanderroras their own outcomes, never asclear. - Show reviewers the
withheldreasons andfcraRedactions; show the consumer only furnished records (the portal does this). - Store
controlVersionwith every order you adjudicate on. - Skip
supersededsearches; readsupersededBy. - Adjudication and any notices to the consumer stay with you; the API furnishes records and the reasons it did not.