# Clearances

> Record once that a person a criminal search returned is not your subject; later searches for the subjectId hide them. One source per personRef, no extra charge.

- **HTML:** https://offendersearch.app/docs/criminal/clearances
- **Base URL:** https://api.offendersearch.app
- **Authentication:** `X-API-Key` request header
- **OpenAPI:** https://offendersearch.app/openapi.json · https://offendersearch.app/openapi.yaml
- **Criminal reference as markdown:** https://offendersearch.app/docs/criminal.md

## Clearances: dismiss a false-positive criminal match once, per subject

A criminal search for a common name returns people who are not the person you are screening. A clearance records, for one **subject** — a resident, a visitor, an applicant, an employee, identified by your own `subjectId` — that one returned person **is** or **is not** that subject. Every later `POST /v1/criminal/search` that sends the same `subjectId` honours it: a person marked `not_this_person` leaves `records[]` and is listed in `cleared[]`.

Clearances are keyed on `personRef`, the identifier that groups the records one source holds for the same person (see [the Criminal Record object](https://offendersearch.app/docs/criminal/record-object.md)). They are **included in your search price, no extra charge**, they share the `/v1/clearances` routes and the same `subjectId` with the [Sex Offender API](https://offendersearch.app/docs/clearances.md), and `product` says which dataset a verdict belongs to.

> **A clearance applies only to the exact person cleared, never to a name or a date of birth.** The person you cleared was returned precisely because they share a name — and often a birthday — with your subject. Matching a clearance by name would hide the subject’s own record if it ever appeared. So the match is `personRef` only, and a record whose `personRef` cannot be resolved is never suppressed.

> **A criminal personRef is scoped to one source.** A county jail, a state corrections department and a court each issue their own. Clearing a person from one source clears that source’s records for them — including a later booking or case there, which comes back once flagged `offenses_changed` for a fresh look. It does not clear a different source’s record for the same name: review each source’s person separately.

## Who uses criminal clearances

| Who | What a clearance does for them |
| --- | --- |
| **Visitor management systems** | A regular visitor who shares a name with someone in a county roster is shown to the desk once, reviewed once and cleared once. Every later sign-in for the same visitor id runs the full search and comes back clean. |
| **Skilled nursing and assisted living** | Residents are screened at referral and re-screened on a schedule; standing volunteers the same. A clearance recorded against the resident id is honoured at every re-screen. |
| **Home care and staffing** | Caregivers and applicants are screened at hire and again between credentialing cycles. The look-alike cleared at hire stays cleared at the re-check; a new booking or case still comes through. |
| **Schools, nonprofits and volunteer programs** | Coaches, chaperones and parent helpers who return every season are reviewed by a person once. |
| **Tenant screening** | An applicant’s file is one subject. A look-alike reviewed once stays cleared across the checks that file goes through, with who decided and why on record. |
| **Platforms that screen for many facilities** | Send a `clientId` per facility with every search and every clearance. One facility’s verdicts never reach another facility’s results. |

## The clearance flow: search, review, clear, search again

### 1. Search with a subjectId

Send your id for the person being screened as `subjectId` — and, if you screen for more than one facility or client, your id for that client as `clientId`. Nothing else about the request changes. The response gains `counts.clearedSuppressed` and `cleared[]`; on a first search both are empty.

```bash
curl -X POST https://api.offendersearch.app/v1/criminal/search \\
  -H "X-API-Key: $OFFENDERSEARCH_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
        "query": { "lastName": "Rivera", "firstName": "Jordan", "dob": "1988-04-12", "state": "TX" },
        "subjectId": "resident-48213",
        "clientId": "facility-07"
      }'
```

```json
{
  "status": "complete",
  "counts": { "records": 1, "recordsReturned": 1,
              "sourcesQueried": 0, "sourcesComplete": 0, "sourcesIncomplete": 0, "candidatesCapped": false,
              "sourcesOnFile": 44, "sourcesPending": 27, "clearedSuppressed": 0 },
  "warnings": [],
  "page": 1, "perPage": 50, "totalPages": 1,
  "sourceStatus": [],
  "cappedOmittedSources": [],
  "omittedFields": ["sourceData"],
  "cleared": [],
  "records": [
    { "recordType": "jail_booking",
      "externalId": "TX-BEXAR:booking:734115",
      "personRef": "prs_8b1d4e6f0a2c3c9e7f1a",
      "name": { "first": "JORDAN", "middle": "", "last": "RIVERA", "suffix": "" },
      "dob": { "date": "1988-04-12", "birthYear": 1988, "age": 38, "dobPrecision": "full" },
      "matchState": "dob_match", "matchConfidence": 0.99,
      "sources": [ { "code": "TX-BEXAR", "level": "county",
                     "recordUrl": "https://…/booking/734115", "live": false } ] }
  ],
  "proof": { "status": "none" },
  "searchId": "crs_7f2a1c9e0b4d6a8f1e23",
  "meterEvents": [ { "kind": "criminal_call", "quantity": 1, "chargeCeilingUsd": null } ],
  "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.)." }
}
```

### 2. A person reviews the match

The booking shares the resident’s name and date of birth, so `matchState` is `dob_match`. A reviewer compares the booking photograph where one is published, the charges and the source’s own page (`sources[].recordUrl`) with the resident and decides. Keep the `searchId` and the `personRef`: the verdict cites both.

### 3. Record the verdict

`POST /v1/clearances` with `product: "criminal"`. `searchId` must be a criminal search in your account’s 14-day history whose stored results contain the `personRef` — the proof that the person was reviewed from a real result. A criminal record has no `recordId`, so leave that field out; a second verdict for the same subject, client and person replaces the first.

```bash
curl -X POST https://api.offendersearch.app/v1/clearances \\
  -H "X-API-Key: $OFFENDERSEARCH_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
        "product": "criminal",
        "subjectId": "resident-48213",
        "clientId": "facility-07",
        "personRef": "prs_8b1d4e6f0a2c3c9e7f1a",
        "searchId": "crs_7f2a1c9e0b4d6a8f1e23",
        "verdict": "not_this_person",
        "reviewer": "admissions-desk",
        "note": "Booking photo does not match the resident."
      }'
```

```json
{
  "id": "clr_2a9c05e7d41b83f0",
  "product": "criminal",
  "verdict": "not_this_person",
  "personRef": "prs_8b1d4e6f0a2c3c9e7f1a",
  "recordId": null,
  "searchId": "crs_7f2a1c9e0b4d6a8f1e23",
  "subjectId": "resident-48213",
  "clientId": "facility-07",
  "reviewer": "admissions-desk",
  "note": "Booking photo does not match the resident.",
  "createdAt": "2026-10-18T14:02:11+00:00",
  "revokedAt": null,
  "supersedes": null
}
```

### 4. Search again — the cleared person is gone, and accounted for

The next search for the same `subjectId` and `clientId` runs in full, then removes the cleared person. `counts.records` counts what you received; `counts.clearedSuppressed` says how many were removed, and `cleared[]` names each one with the clearance that applied.

```json
{
  "status": "complete",
  "counts": { "records": 0, "recordsReturned": 0,
              "sourcesQueried": 0, "sourcesComplete": 0, "sourcesIncomplete": 0, "candidatesCapped": false,
              "sourcesOnFile": 44, "sourcesPending": 27, "clearedSuppressed": 1 },
  "warnings": [],
  "page": 1, "perPage": 50, "totalPages": 1,
  "cleared": [
    { "personRef": "prs_8b1d4e6f0a2c3c9e7f1a",
      "clearanceId": "clr_2a9c05e7d41b83f0",
      "verdict": "not_this_person",
      "clearedAt": "2026-10-18T14:02:11+00:00",
      "recordId": null }
  ],
  "records": [],
  "searchId": "crs_0b6e2d91a7c84f3e5d10",
  "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.)." }
}
```

Send `clearanceMode: "annotate"` to keep cleared people in `records[]` with a `clearance` object attached, or `"ignore"` to answer as if no clearances existed. A `this_person` verdict never removes a record; it is kept and annotated in every mode.

## What brings a cleared person back

A clearance is a verdict about the person as they were reviewed. When something about them changes in that source, or the match becomes stronger than the one that was cleared, the person returns to `records[]` with `clearance.stale: true` and a `staleReason` — in every mode, and it cannot be turned off. Review the record again and record a new verdict; until you do, the person stays in the results.

| staleReason | What changed since the clearance |
| --- | --- |
| `identity_changed` | The person’s name or date of birth. |
| `offenses_changed` | Their cases or charges — including a new booking or case in the same source. |
| `status_changed` | Their custody status, release date or facility. |
| `stronger_match` | This search matched them more strongly than the search that was cleared — for example the subject’s date of birth now matches where only the name did. |

```json
{
  "recordType": "jail_booking",
  "externalId": "TX-BEXAR:booking:801962",
  "personRef": "prs_8b1d4e6f0a2c3c9e7f1a",
  "name": { "first": "JORDAN", "middle": "", "last": "RIVERA", "suffix": "" },
  "matchState": "dob_match",
  "clearance": {
    "clearanceId": "clr_2a9c05e7d41b83f0",
    "verdict": "not_this_person",
    "clearedAt": "2026-10-18T14:02:11+00:00",
    "stale": true,
    "staleReason": "offenses_changed"
  }
}
```

## Clearance rules: personRef only, per source, per client, until revoked

- **personRef only.** A clearance names one `personRef` and suppresses only records that carry it. Never a name, never a date of birth. A record whose `personRef` cannot be resolved is never suppressed.
- **One source at a time.** A criminal `personRef` belongs to one source, so a clearance covers that source’s records for the person and no other source’s. The same name in another county or a state system is a different `personRef` and a separate review.
- **Per subject, per client.** A verdict is scoped to the `subjectId` it was recorded for, and to the `clientId` when one was sent. Nothing one client clears affects another client’s results.
- **Stored as hashes.** `subjectId` and `clientId` are kept only as per-account hashes, never as the ids you sent. They are echoed on the request that carried them and are `null` on `GET /v1/clearances/{clearanceId}`.
- **Proof of review.** The `searchId` must be in your 14-day search history and that search must have returned the `personRef` — otherwise `404 search_not_found` or `409 person_not_in_search`.
- **No expiry.** A clearance applies until you revoke it. Re-surfacing is how a changed person comes back; nothing comes back on a timer.
- **Revoke, don’t delete.** `DELETE` sets `revokedAt`; the next search for that subject shows the person again, and the clearance stays readable with `includeRevoked=true`.
- **Scoped to the account.** Clearances survive API key rotation and are shared by every key and dashboard user on the account.
- **Included in your search price, no extra charge.** Nothing on `/v1/clearances` is metered, and a search with a `subjectId` is billed exactly like one without.
- **Additive.** A request without `subjectId` returns exactly what it did before clearances existed — no `cleared` key, no `clearedSuppressed`, no `clearance` on any record.

## Clearance endpoints

The `/v1/clearances` routes are shared with the Sex Offender API and documented in full at [https://offendersearch.app/docs/clearances.md](https://offendersearch.app/docs/clearances.md); `product: "criminal"` is what makes a verdict a criminal one. Every route authenticates with the `X-API-Key` header or a dashboard session.

| Method | Path | What it does |
| --- | --- | --- |
| POST | `/v1/clearances` | Record a verdict for one subject and one `personRef`. `201` with the Clearance. |
| GET | `/v1/clearances` | List a subject’s clearances (`subjectId` required; `clientId`, `product`, `includeRevoked` optional). |
| GET | `/v1/clearances/{clearanceId}` | Retrieve one clearance by id. |
| DELETE | `/v1/clearances/{clearanceId}` | Revoke it. Returns `{ id, revokedAt }`. |

The search-side fields — `subjectId`, `clientId` and `clearanceMode` on the request; `cleared[]`, `counts.clearedSuppressed` and the record’s `clearance` on the response — are in the [Search](https://offendersearch.app/docs/criminal/search.md) reference, and the two objects they carry are defined below.

## The ClearedEntry object — one person a clearance hid from this response

One record a `not_this_person` clearance removed from `records[]` for the `subjectId` sent. `cleared[]` carries one of these per suppressed record, so an interface can say how many previously cleared people are hidden and link each to its clearance.

Returned or accepted by [`POST /v1/criminal/search`](https://offendersearch.app/docs/criminal/search#reference-post-v1-criminal-search), [`GET /v1/criminal/searches/{searchId}`](https://offendersearch.app/docs/criminal/async#reference-get-v1-criminal-searches-searchid).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `personRef` | `string` |  | The cleared person, as the search identified them. Example `"prs_3c9e1f0a7b2d4e6f8a1b"`. |
| `clearanceId` | `string` |  | The clearance that applied. `GET /v1/clearances/{clearanceId}` returns it. Example `"clr_7d2f41c0a9b3e8f6"`. |
| `verdict` | `string` — one of `"not_this_person"` |  | Always `not_this_person`; a `this_person` verdict never removes a record. |
| `clearedAt` | `string (date-time)` |  | When the clearance was recorded. |
| `recordId` | `string` or null |  | `null`: a criminal record is cited by `externalId` with its `sources[].code`, and the cleared person is identified by `personRef`. |

## The RecordClearance object — the clearance attached to a kept record

The clearance that names a record's person, attached as `clearance` when the request carried `subjectId` and the record was kept: in `clearanceMode: "annotate"`, on a `this_person` verdict, or because a cleared person has re-surfaced (`staleReason` set). A record no clearance names carries no `clearance` key.

Returned or accepted by [`POST /v1/criminal/search`](https://offendersearch.app/docs/criminal/search#reference-post-v1-criminal-search), [`GET /v1/criminal/searches/{searchId}`](https://offendersearch.app/docs/criminal/async#reference-get-v1-criminal-searches-searchid), [`POST /v1/criminal/batch`](https://offendersearch.app/docs/criminal/batch#reference-post-v1-criminal-batch), [`GET /v1/criminal/records/{recordId}`](https://offendersearch.app/docs/criminal/record-object#reference-get-v1-criminal-records-recordid).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `clearanceId` | `string` |  | The clearance. `GET /v1/clearances/{clearanceId}` returns it. Example `"clr_7d2f41c0a9b3e8f6"`. |
| `verdict` | `string` — one of `"not_this_person"`, `"this_person"` |  | The verdict recorded for this person and subject. |
| `clearedAt` | `string (date-time)` |  | When the verdict was recorded. |
| `stale` | `boolean` |  | `true` when this person was cleared as `not_this_person` and is shown anyway, because something about them changed since the clearance or this search matched them more strongly than the search that was cleared. Review the record again and record a new verdict; until you do, the person stays in `records[]`. |
| `staleReason` | `string` or null — one of `"identity_changed"`, `"offenses_changed"`, `"status_changed"`, `"stronger_match"` |  | Why the person re-surfaced. `identity_changed` — their name or date of birth changed. `offenses_changed` — their cases or charges changed, including a new booking or case in the same source. `status_changed` — their custody status, release date or facility changed. `stronger_match` — this search matched the person more strongly than the search that was cleared (the subject's date of birth now matches where only the name did). `null` when the person has not re-surfaced. |

---

## Related

- Previous: [Resolve a website to a code](https://offendersearch.app/docs/criminal/resolve.md)
- Next: [Async live jobs & polling](https://offendersearch.app/docs/criminal/async.md)
- Index: [Criminal Search API reference](https://offendersearch.app/docs/criminal.md)
