OffenderSearch
API Reference · v1.0.0

Clearances

Dismiss a false-positive match once per subject; later searches hide the person, and a changed record brings them back.

Base URL https://api.offendersearch.app

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

A search for a common name returns people who are not the person you are screening. A clearance records, for one subject you screen — 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 search that sends the same subjectId honours it: a person marked not_this_person leaves records[] and is listed in cleared[], so the same reviewer is never asked the same question twice.

Clearances are keyed on personRef — the durable identifier every record and every sources[] entry carries (see Record identity). They are included in your search price, no extra charge, and the flow is the same on the Criminal Search API.

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.

Who uses clearances

WhoWhat a clearance does for them
Visitor management systemsA regular visitor who shares a name with a registrant 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, instead of asking the desk the same question each week.
Skilled nursing and assisted livingResidents 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, so the admissions team reviews a look-alike one time.
Home care and staffingCaregivers and applicants are screened at hire and again between credentialing cycles. The look-alike cleared at hire stays cleared at the re-check, and a new or changed record still comes through.
Schools, nonprofits and volunteer programsCoaches, chaperones and parent helpers who return every season. The person who reviewed the match the first time does not have to be found again the next time.
Tenant screeningAn applicant’s file is one subject. A look-alike reviewed once stays cleared across the checks that file goes through, and the verdict is recorded with who decided and why.
Platforms that screen for many facilitiesSend a clientId per facility with every search and every clearance. One facility’s verdicts never reach another facility’s results, even for the same registrant and the same subject id.

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.

POST /v1/search
curl -X POST https://api.offendersearch.app/v1/search \
  -H "X-API-Key: $OFFENDERSEARCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "query": { "firstName": "Jordan", "lastName": "Rivera", "dob": "1988-04-12" },
        "subjectId": "resident-48213",
        "clientId": "facility-07"
      }'
200 OK (abridged)
{
  "searchId": "srch_9f2c1a7b",
  "status": "complete",
  "counts": { "records": 1, "recordsReturned": 1, "sourcesQueried": 58,
              "sourcesComplete": 58, "sourcesIncomplete": 0, "sourcesSkippedByScope": 0,
              "clearedSuppressed": 0 },
  "cleared": [],
  "records": [
    { "recordId": "rec_6d066763131ebe8c77ea",
      "personRef": "prs_3c9e1f0a7b2d4e6f8a1b",
      "name": { "first": "Jordan", "last": "Rivera", "full": "Jordan Rivera" },
      "dob": "1988-04-12", "matchState": "dob_match", "matchConfidence": 1.0,
      "source": { "jurisdiction": "TX", "personRef": "prs_3c9e1f0a7b2d4e6f8a1b",
                  "recordUrl": "https://…" } }
  ]
}

2. A person reviews the match

The registrant shares the resident’s name and date of birth, so matchState is dob_match. A reviewer compares the photograph, the registry’s address and the registry’s own page (source.recordUrl) with the resident in front of them and decides. Keep the searchId, the personRef and the recordId: the verdict cites all three.

3. Record the verdict

POST /v1/clearances with the verdict. searchId must be a 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 second verdict for the same subject, client and person replaces the first.

POST /v1/clearances
curl -X POST https://api.offendersearch.app/v1/clearances \
  -H "X-API-Key: $OFFENDERSEARCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "product": "sex_offender",
        "subjectId": "resident-48213",
        "clientId": "facility-07",
        "personRef": "prs_3c9e1f0a7b2d4e6f8a1b",
        "recordId": "rec_6d066763131ebe8c77ea",
        "searchId": "srch_9f2c1a7b",
        "verdict": "not_this_person",
        "reviewer": "admissions-desk",
        "note": "Photo and registry address do not match the resident."
      }'
201 Created
{
  "id": "clr_7d2f41c0a9b3e8f6",
  "product": "sex_offender",
  "verdict": "not_this_person",
  "personRef": "prs_3c9e1f0a7b2d4e6f8a1b",
  "recordId": "rec_6d066763131ebe8c77ea",
  "searchId": "srch_9f2c1a7b",
  "subjectId": "resident-48213",
  "clientId": "facility-07",
  "reviewer": "admissions-desk",
  "note": "Photo and registry address do 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, so an interface can say “1 previously cleared person hidden” and link to the decision.

200 OK — the same search, after the clearance
{
  "searchId": "srch_c41e8d20",
  "status": "complete",
  "counts": { "records": 0, "recordsReturned": 0, "sourcesQueried": 58,
              "sourcesComplete": 58, "sourcesIncomplete": 0, "sourcesSkippedByScope": 0,
              "clearedSuppressed": 1 },
  "cleared": [
    { "personRef": "prs_3c9e1f0a7b2d4e6f8a1b",
      "clearanceId": "clr_7d2f41c0a9b3e8f6",
      "verdict": "not_this_person",
      "clearedAt": "2026-10-18T14:02:11+00:00",
      "recordId": "rec_6d066763131ebe8c77ea" }
  ],
  "records": []
}

Send clearanceMode: "annotate" to keep cleared people in records[] with a clearance object attached (for an interface that greys them out), 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. The same three fields work per row on POST /v1/batch.

What brings a cleared person back

A clearance is a verdict about the person as they were reviewed. When something about them changes, 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.

staleReasonWhat changed since the clearance
identity_changedThe person’s name or date of birth.
offenses_changedTheir offenses.
status_changedTheir registration status, tier or absconder / predator flag.
stronger_matchThis 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.
A cleared person who re-surfaced
{
  "recordId": "rec_6d066763131ebe8c77ea",
  "personRef": "prs_3c9e1f0a7b2d4e6f8a1b",
  "name": { "first": "Jordan", "last": "Rivera", "full": "Jordan Rivera" },
  "dob": "1988-04-12", "matchState": "dob_match",
  "clearance": {
    "clearanceId": "clr_7d2f41c0a9b3e8f6",
    "verdict": "not_this_person",
    "clearedAt": "2026-10-18T14:02:11+00:00",
    "stale": true,
    "staleReason": "offenses_changed"
  }
}

Clearance rules: personRef only, 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.
  • 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, even for the same person.
  • 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.
Revoke a clearance
curl -X DELETE https://api.offendersearch.app/v1/clearances/clr_7d2f41c0a9b3e8f6 \
  -H "X-API-Key: $OFFENDERSEARCH_KEY"

{ "id": "clr_7d2f41c0a9b3e8f6", "revokedAt": "2026-11-02T09:15:40+00:00" }

Clearance endpoints

Every route authenticates with the X-API-Key header or a dashboard session. Each is documented in full below.

MethodPathWhat it does
POST/v1/clearancesRecord a verdict for one subject and one personRef. 201 with the Clearance.
GET/v1/clearancesList 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 }.

Search-side fields — subjectId, clientId and clearanceMode on the request; cleared[], counts.clearedSuppressed and the record’s clearance on the response — are documented on Search and Batch, and the objects they carry are defined below.

POST/v1/clearancesAuth: X-API-Key

POST /v1/clearances — record a verdict: request and response fields

Record that the person behind a personRef is (this_person) or is not (not_this_person) the subject identified by your subjectId. The verdict must cite the search that showed the person. A second verdict for the same subject, client and person replaces the first. Included in the search price; nothing here is metered.

Request

Body · application/json
FieldTypeDescription
product
optional · default "sex_offender"
string
one of "sex_offender", "criminal"
The dataset the verdict belongs to: sex_offender for a person returned by POST /v1/search or POST /v1/batch, criminal for one returned by POST /v1/criminal/search. A criminal personRef is scoped to one source, so a criminal clearance clears that source's records for the person — see criminal clearances.
subjectId
required
stringYour id for the person being screened, 1–128 characters — the same value you will send on later searches for them. Stored only as a per-account hash.
Example "resident-48213"
clientId
optional
stringYour facility, tenant or client id, 1–128 characters, when you screen for more than one. A clearance recorded with a clientId applies only to searches that send the same one. Stored only as a per-account hash.
Example "facility-07"
personRef
required
stringThe person the verdict is about — the personRef the search returned (prs_ and 20 hex characters). The verdict applies to this person and no one else, never to a name or a date of birth.
Example "prs_3c9e1f0a7b2d4e6f8a1b"
recordId
optional
stringThe recordId of the result the reviewer looked at, for the audit trail. At most 64 characters.
Example "rec_6d066763131ebe8c77ea"
searchId
required
stringThe search that showed this person. It must be in this account's 14-day history and its stored results must contain personRef — otherwise 404 search_not_found or 409 person_not_in_search.
Example "srch_9f2c1a7b"
verdict
required
string
one of "not_this_person", "this_person"
not_this_person — the returned person is someone else; later searches for the subject suppress (or annotate) them. this_person — the returned person is the subject; later searches keep them and annotate the record so your interface can show the confirmed match.
reviewer
optional
stringWho decided, in your own terms — a user id, a desk, a role. At most 120 characters.
Example "admissions-desk"
note
optional
stringWhy, in the reviewer's words. At most 500 characters.
Example "Photo and registry address do not match the resident."

Response

201 · application/json

The verdict was recorded and applies to the next search for this subject.

The body is the Clearance object. One verdict: the person behind a personRef is, or is not, the subject being screened. Returned by every /v1/clearances route. subjectId and clientId are echoed only on the request that carried them (create and list); on GET /v1/clearances/{clearanceId} they are null, because only a per-account hash of them is stored.

Errors
StatusCodeWhen
401—The X-API-Key header is missing or the key is not valid, and no valid dashboard session was sent.
404search_not_foundsearchId is not one of this account's searches, or it is older than the 14-day history window and its results are gone. Run the search again and clear from the new result. detail is {code, message}.
409person_not_in_searchThe search named by searchId did not return this personRef. A clearance must cite a search that showed the person being cleared. detail is {code, message}.
422—A field failed validation — an unknown product or verdict, a subjectId or clientId outside 1–128 characters, a personRef that is not the prs_ value a search returned, a reviewer over 120 or a note over 500 characters, or an unknown key. detail says which.
GET/v1/clearancesAuth: X-API-Key

GET /v1/clearances — list clearances: request and response fields

Every clearance recorded for one subjectId (and clientId, when you send one), newest first. Active clearances only unless includeRevoked=true. The ids you send are hashed before the lookup, so a listing needs the same subjectId and clientId the verdicts were recorded under.

Request

Query parameters
FieldTypeDescription
subjectId
required
stringYour id for the subject, as sent when the clearances were recorded.
Example "resident-48213"
clientId
optional
stringYour facility, tenant or client id, when the clearances were recorded with one.
Example "facility-07"
product
optional
string
one of "sex_offender", "criminal"
Restrict to one dataset. Omit for both.
includeRevoked
optional · default false
booleantrue also returns revoked clearances. Default false: active ones only.

Response

200 · application/json

The subject's clearances, newest first; [] when none are recorded.

FieldTypeDescription
clearances
array of ClearanceOne Clearance per verdict, with subjectId and clientId echoed from the query.
Errors
StatusCodeWhen
401—The X-API-Key header is missing or the key is not valid, and no valid dashboard session was sent.
422—subjectId is missing or outside 1–128 characters, clientId is outside 1–128 characters, or product is not sex_offender or criminal.
GET/v1/clearances/{clearanceId}Auth: X-API-Key

GET /v1/clearances/{clearanceId} — one clearance: request and response fields

One clearance by id — the clearanceId a search response's cleared[] or clearance carries. subjectId and clientId are null on this route: only a per-account hash of them is stored.

Request

Path parameters
FieldTypeDescription
clearanceId
required
stringThe clearance id (clr_…).
Example "clr_7d2f41c0a9b3e8f6"

Response

200 · application/json

The clearance, revoked or not.

The body is the Clearance object. One verdict: the person behind a personRef is, or is not, the subject being screened. Returned by every /v1/clearances route. subjectId and clientId are echoed only on the request that carried them (create and list); on GET /v1/clearances/{clearanceId} they are null, because only a per-account hash of them is stored.

Errors
StatusCodeWhen
401—The X-API-Key header is missing or the key is not valid, and no valid dashboard session was sent.
404—No clearance with that id on your account — including another account's clearance id.
DELETE/v1/clearances/{clearanceId}Auth: X-API-Key

DELETE /v1/clearances/{clearanceId} — revoke a clearance: request and response fields

Sets revokedAt. The verdict stops applying at once: the next search for that subject shows the person again. The clearance stays readable with includeRevoked=true, so the audit trail is not lost.

Request

Path parameters
FieldTypeDescription
clearanceId
required
stringThe clearance id (clr_…).
Example "clr_7d2f41c0a9b3e8f6"

Response

200 · application/json

The clearance was revoked.

FieldTypeDescription
id
stringThe revoked clearance's id.
Example "clr_7d2f41c0a9b3e8f6"
revokedAt
string (date-time)When it was revoked — now.
Errors
StatusCodeWhen
401—The X-API-Key header is missing or the key is not valid, and no valid dashboard session was sent.
404—No clearance with that id on your account — including another account's clearance id.

The Clearance object — every field on a recorded verdict

One verdict: the person behind a personRef is, or is not, the subject being screened. Returned by every /v1/clearances route. subjectId and clientId are echoed only on the request that carried them (create and list); on GET /v1/clearances/{clearanceId} they are null, because only a per-account hash of them is stored.

Returned or accepted by POST /v1/clearances, GET /v1/clearances, GET /v1/clearances/{clearanceId}.

FieldTypeDescription
id
stringclr_ followed by an opaque id. What GET and DELETE /v1/clearances/{clearanceId} take.
Example "clr_7d2f41c0a9b3e8f6"
product
string
one of "sex_offender", "criminal"
The dataset the verdict belongs to.
verdict
string
one of "not_this_person", "this_person"
not_this_person suppresses (or annotates) the person on later searches for the subject; this_person keeps and annotates them.
personRef
stringThe person the verdict is about.
Example "prs_3c9e1f0a7b2d4e6f8a1b"
recordId
string or nullThe result the reviewer looked at, when one was cited; null otherwise.
Example "rec_6d066763131ebe8c77ea"
searchId
stringThe search that showed the person.
Example "srch_9f2c1a7b"
subjectId
string or nullEchoed from the request that carried it; null on GET /v1/clearances/{clearanceId}, because only a hash is stored.
Example "resident-48213"
clientId
string or nullEchoed from the request that carried it; null when none was sent, and on GET /v1/clearances/{clearanceId}.
Example "facility-07"
reviewer
string or nullWho decided, as sent; null when not sent.
note
string or nullThe reviewer's note, as sent; null when not sent.
createdAt
string (date-time)When the verdict was recorded. This is the clearedAt a search response reports.
revokedAt
string (date-time) or nullnull while the clearance applies; set by DELETE /v1/clearances/{clearanceId}. A revoked clearance is listed only with includeRevoked=true.
supersedes
string or nullThe id of the clearance this one replaced — a second verdict for the same subject, client and personRef supersedes the first. null for a first verdict.

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/search, GET /v1/searches/{searchId}, POST /v1/batch.

FieldTypeDescription
personRef
stringThe cleared person, as the search identified them.
Example "prs_3c9e1f0a7b2d4e6f8a1b"
clearanceId
stringThe 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
stringThe recordId the suppressed record carries in this response's scope, so you can cite or fetch it.
Example "rec_6d066763131ebe8c77ea"

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/search, GET /v1/searches/{searchId}, GET /v1/searches/{searchId}/results, POST /v1/batch, GET /v1/records/{recordId}, GET /v1/map/records/{markerId}.

FieldTypeDescription
clearanceId
stringThe 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
booleantrue 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 offenses changed. status_changed — their registration status, tier or absconder/predator flag 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.

Product overview