Developer docs · v1.0.0

Hospitals and visitor management

A name at the kiosk, a badge in seconds, a supervisor path for the one-in-four look-alike, and a clearance so the regular visitor is never stopped twice.

How visitor screening works in hospitals today

Hospitals are open buildings with locked rooms inside them. The Medicare hospital Conditions of Participation guarantee patients the right to receive the visitors they designate — "including, but not limited to, a spouse, a domestic partner (including a same-sex domestic partner), another family member, or a friend" — require written visitation policies, allow "clinically necessary or reasonable" restrictions, and forbid restricting visitation on the basis of race, color, national origin, religion, sex, gender identity, sexual orientation or disability (42 CFR 482.13(h)). The Joint Commission's Environment of Care standard EC.02.01.01 requires a hospital to identify individuals entering its facilities and to control access to and from areas it designates security-sensitive, leaving the hospital to decide who needs identification and how. Its 2022 workplace violence prevention requirements add a program led by a designated individual with an annual risk analysis (LD.03.01.01 EP 9), an annual worksite analysis (EC.02.01.01 EP 17), incident reporting and investigation (EC.04.01.01 EP 6) and staff training (HR.01.05.03 EP 29). The International Association for Healthcare Security and Safety publishes the profession's guidelines, including one on violent patient and visitor management.

The desk, the kiosk and the units

Operationally this becomes a visitor management system (VMS): a kiosk or a staffed desk at each public entrance that scans or types a government ID, captures the visitor's name and often date of birth, checks the name against the hospital's own lists (restricted visitors, protective orders, prior incidents) and, in many hospitals, against the public sex offender registries, then prints a photo badge that expires that day. Security staff run it; the chief security officer owns the policy; registration and nursing see the badge. The screen takes seconds because the line is long.

The registry check is concentrated where the patients are children or infants. The National Center for Missing & Exploited Children's *For Healthcare Professionals: Guidelines on Prevention of and Response to Infant Abductions* (10th edition, 2014) recommends limiting maternity visitors to those who can give the mother's full name, photographing maternity-unit visitors, positively identifying visitors to nursery, maternity, NICU and pediatric units with a photo ID, running background checks "including a search of sex offender registries" on everyone entrusted to care for or transport infants and pediatric patients, and searching the public registries for any adult patient placed on a unit with pediatric patients. Children's hospitals that publish their badging policies describe exactly that flow: ID compared against the public registries at badge issue, a 24-hour badge, and a registered visitor either refused entry or limited to the patient's room and public areas with security's approval. One published account of such a program put the confirmation rate at about a quarter: three of four registry name matches turned out, on review, to be a different person. The supervisor step exists because of that number.

Volunteers and clergy

Volunteers are screened as staff. Joint Commission standard HR.01.01.01 EP 4 requires the hospital to obtain and document criminal background checks on applicants "as required by law and regulation or hospital policy", and the Commission's guidance says volunteers who work in the same capacity as staff providing care, treatment and services are expected to have them when law or policy requires. Some states go further: Hawaii requires prospective direct patient access employees *and adult volunteers* of health care facilities, hospitals included, to consent to checks covering criminal history, the abuse registries, the sex offender registry and the nurse aide registry, with an annual name inquiry thereafter (Haw. Rev. Stat. § 321-15.2). The OIG's exclusion guidance applies to volunteers as to employees. No rule specific to clergy was found; hospitals generally run visiting chaplains and faith-community volunteers through the volunteer program, and credential employed chaplains through HR.

Named, not applied. The standards and statutes above are cited so you can read them; what they require of a given hospital, unit or visitor policy is for your security leadership, compliance office and counsel. A visitor policy that restricts a registrant must still satisfy 42 CFR 482.13(h) and your state's rules, and that judgment is yours. The API returns public records with provenance; it does not make a hospital compliant.

Where the API fits

Workflow stepEndpointFields that matter
Kiosk or desk: name (and DOB or age) → screen → badgePOST /v1/search across all 58 US registriesquery.firstName, lastName, dob or age; subjectId = your visitor id, clientId = campus; deadlineMs + onDeadline: "partial"; read status, records[].matchState, matchBasis, images[0].url, sources[0].recordUrl
Supervisor resolves a look-alike oncePOST /v1/clearancesproduct: "sex_offender", subjectId, clientId, personRef, recordId, searchId, verdict: "not_this_person", reviewer, note
Repeat visitorThe same search with the same subjectIdcleared[] and counts.clearedSuppressed show the look-alikes already resolved; clearance.stale on a record means the cleared person re-surfaced because something changed
Pediatric unit: an adult patient placed with children (NCMEC recommendation)POST /v1/searchSame fields; subjectId = patient id; a partial answer is "could not complete"
Volunteers and visiting clergyWhere your counsel treats it as an employment-purpose check: the FCRA Partner API; otherwise POST /v1/search and POST /v1/criminal/search with subjectId = volunteer idFcraOrderCreate with permissiblePurpose: "employment"; or the self-service fields above
Document a contested restrictionPOST /v1/report; live.evidence: "pdf" for the registry's own pagesearchId; evidence[].downloadUrl
Volunteer roster stays watchedPOST /v1/monitors, type: "person"person, label = volunteer id, channels

Pattern for VMS integration: the kiosk or VMS posts the visitor to your middleware (or your VMS vendor calls the API directly), the middleware calls POST /v1/search with the visitor's id as subjectId and the campus as clientId, derives the desk state below, and returns it to the VMS — which prints the badge, holds for a supervisor, or shows "could not complete". Keep the API key in the middleware, never in the kiosk.

Reference integration

screen_visitor is the kiosk call: one registry search with a 15-second target and onDeadline: "partial", so the desk never waits on a slow registry and never mistakes a partial answer for a clear one. supervisor_clears records that a look-alike is not this visitor; the demonstration runs the same visitor twice to show the second visit coming back clear with previously_cleared: 3. Run it against the sandbox with an os_test_ key.

"""Hospital visitor management — kiosk screening with clearances for repeat visitors.
Python 3.11+, requests. Runs against the sandbox with its fixed test names.

  OFFENDERSEARCH_API_KEY   os_test_… (sandbox) or os_live_… (production)
  OFFENDERSEARCH_BASE      https://sandbox.offendersearch.app (default here)

The desk flow: a visitor gives a name and (where your policy collects it) a date of birth or age;
the kiosk sends one search with subjectId = your visitor id and clientId = the campus; the screen
shows clear / review / match / could-not-complete; a supervisor resolves review states and records
a clearance so the same look-alike never stops this visitor again.
"""
from __future__ import annotations

import os
import time
from dataclasses import dataclass, field

import requests

API_KEY = os.environ["OFFENDERSEARCH_API_KEY"]
BASE = os.environ.get("OFFENDERSEARCH_BASE", "https://sandbox.offendersearch.app")
CAMPUS_ID = os.environ.get("CAMPUS_ID", "campus-main")
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
The second visit — records empty, three look-alikes in cleared[]
{
  "searchId": "srch_2e7d1a9c",
  "status": "complete",
  "counts": { "records": 0, "recordsReturned": 0, "sourcesQueried": 58, "sourcesComplete": 58, "sourcesIncomplete": 0, "clearedSuppressed": 3 },
  "warnings": [],
  "records": [],
  "cleared": [
    { "personRef": "prs_0a1b2c3d4e5f60718293", "clearanceId": "clr_7d41e2a9", "verdict": "not_this_person", "clearedAt": "2026-10-25T15:02:40+00:00", "recordId": "rec_6d066763131ebe8c77ea" },
    { "personRef": "prs_1b2c3d4e5f607182a3b4", "clearanceId": "clr_7d41e2aa", "verdict": "not_this_person", "clearedAt": "2026-10-25T15:02:41+00:00", "recordId": "rec_7e177874242fcf9d88fb" },
    { "personRef": "prs_2c3d4e5f607182a3b4c5", "clearanceId": "clr_7d41e2ab", "verdict": "not_this_person", "clearedAt": "2026-10-25T15:02:41+00:00", "recordId": "rec_8f288985353a0dae99ac" }
  ],
  "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.)." },
  "sandbox": true
}

The desk states

Desk stateRuleWhat the desk and the supervisor see
clearrecords empty and status: "complete""Print the badge." The searchId is stored on the visit record. previously_cleared may be non-zero for a regular visitor.
reviewCandidates exist, none with matchState: "dob_match" — typically a kiosk that collected only an age, or registries that publish no birth date (no_dob_age_year)The kiosk holds; the supervisor sees one card per candidate — name, aliases, dob/age, matchBasis, registeredBy, the registry photo and the registry's own page — and compares it with the person and their ID.
matchA candidate with matchState: "dob_match"The supervisor is called. Still a candidate until a person has compared photo and details; then the visitation policy applies — to the person, under 42 CFR 482.13(h).
could_not_completerecords empty but status: "partial"; sourceStatus[] rows with incomplete: true name the registriesNever shown as clear. Retry, or follow the manual procedure the policy defines for an outage.
refused / failed422 (read detail — a name too short to search, a malformed date), 429, 5xxAn operator message; the manual procedure. Nothing was billed.
Note. Collect a date of birth when you can. With one, a wrong-DOB look-alike is excluded before it reaches the desk (the sandbox's "Exact Match" with a different date returns nothing) and a true match is tiered dob_match. With only an age, common names produce review states; design for them rather than auto-denying. The front-desk guide walks the desk states with the sandbox scenarios.

Ongoing monitoring

Visitors come and go; monitoring is for the people who stay. The volunteer roster — hundreds of people at a large hospital, many of them in pediatric and maternity areas — is the natural set: one person monitor per volunteer per dataset (product: "sex-offender" and, where your policy includes it, "criminal"), label = volunteer id, alerts to the volunteer office or security by webhook or email. Inpatients on a long stay in a unit with children are a second set, created at placement and cancelled at discharge. A location monitor around the campus (type: "location", radiusMiles) is a third, for the security office's awareness.

Create a person monitor (volunteer or long-stay patient)
curl -X POST https://sandbox.offendersearch.app/v1/monitors \
  -H "X-API-Key: $OFFENDERSEARCH_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "product": "sex-offender",
    "type": "person",
    "person": { "firstName": "Exact", "lastName": "Match", "dob": "1980-01-01" },
    "minConfidence": "year_match",
    "label": "resident-48213 · unit 2B",
    "channels": { "webhookUrl": "https://your-app.example.com/hooks/offendersearch?token=REPLACE_WITH_A_SECRET" }
  }'
  • Evaluated once a day; the first evaluation reports every current match as new. Deliveries are signed with the monitor's webhookSecret — verify X-Offendersearch-Signature before acting.
  • An alert names the person, the registry and the city, the matchLabel, and (for Sex Offender monitors) a recordId you can open with GET /v1/records/{recordId} before anyone acts.
  • Cancel at the end of the volunteer term or at discharge; the monitor and its alerts remain readable.

Person monitoring, alerts, delivery.

When this is FCRA

Visitor screening is a facility-safety process under your visitation policy and 42 CFR 482.13(h); it is not a consumer report, and the self-service API's legal.notice applies. Screening a prospective employee is an employment purpose and belongs on the FCRA Partner API — an end user, a certified purpose, a consent attestation, controls, disputes and signed webhooks, available to approved partners (403 fcra_not_enabled otherwise). Volunteers and clergy sit between: the Joint Commission expects them to be screened like staff when law or policy requires, and whether that screen is a consumer-report use is a question for your counsel. Where counsel says it is, the volunteer check is an FCRA order with permissiblePurpose: "employment"; where it is not, the self-service search and criminal endpoints with subjectId = volunteer id are the fit. Never use the self-service API as the sole basis for a hiring, retention or volunteer-placement decision your counsel has placed under the FCRA.

Evidence and audit

A restricted visitor may complain; a surveyor may ask how the visitation policy was applied; a family may ask who was badged onto the unit. The visit record should carry the searchId, the desk state, the status and counts, and — when a supervisor was involved — the clearance or the decision with the reviewer's name and note.

Print the registry's own page for a contested restriction
curl -X POST https://sandbox.offendersearch.app/v1/search \
  -H "X-API-Key: $OFFENDERSEARCH_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "query": { "firstName": "Exact", "lastName": "Match", "dob": "1980-01-01" },
    "live": { "jurisdictions": ["OH"], "evidence": "pdf" }
  }'
# 202 { "searchId": "evs_…", "status": "pending", "mode": "async", "registries": ["OH"], "pollUrl": "/v1/searches/evs_…" }
# GET pollUrl until status is complete; evidence[] then carries one document per registry with a downloadUrl.
  • Verification report. POST /v1/report with the searchId (and viewerName = the supervisor) renders a timestamped PDF of every matching record with a source citation on each, +$0.02. Render it at decision time. Reports.
  • Registry page. live.evidence: "pdf" with live.jurisdictions prints the named registries' own pages; the 202 returns a pollUrl, the completed search carries evidence[].downloadUrl, readable for 30 days, 25¢ per document. Live evidence.
  • Clearances. Each not_this_person verdict cites the searchId that showed the person and keeps reviewer and note; GET /v1/clearances?subjectId=…&clientId=…&includeRevoked=true lists a visitor's history, revoked ones included. Clearances.
  • Retention. Searches stay in the account history for 14 days (GET /v1/searches/{searchId}/results); the visit record and badge log on your side hold what your policy requires beyond that. Keep subjectId as your visitor id, never an MRN or a patient identifier.

Rollout plan

  1. Decide the policy before the kiosk. With security leadership and counsel: which entrances and units screen, what is collected (ID scan, DOB, age), what each desk state means, who the supervisor is, and how a confirmed match is handled under 42 CFR 482.13(h) and state law. The screen implements the policy; it does not define it.
  2. Sandbox the desk states. Create an account, mint an os_test_ key in Dashboard → API keys, run the module above against https://sandbox.offendersearch.app, and watch "Name Only" go from review to clear after the clearances. Time the calls; set deadlineMs to what the line can bear.
  3. Integrate the VMS. Put the API call in middleware your VMS or kiosk calls; map the VMS visitor id to subjectId and the campus to clientId; return the desk state and the candidate cards; keep the key out of the kiosk.
  4. Build the supervisor view. Candidate cards with the registry photo and sources[].recordUrl; "this person" / "not this person", the second wired to POST /v1/clearances; a note field. Log who decided.
  5. Pilot one entrance. Switch to an os_live_ key at one pediatric or maternity entrance, run alongside the existing process, and measure review volume, confirmation rate and queue time. Expect most registry matches to resolve as different people; tune DOB capture, not the API.
  6. Extend to volunteers and other entrances. Add volunteer screening on the path counsel chose (FCRA order or self-service), create person monitors for the roster, then roll the kiosk flow to the remaining entrances, one clientId per campus.