Assisted living and memory care
Fifty state licensing regimes, one integration: move-in screening, workforce and contractor checks, family-visitor practice and per-community policy in code.
How screening works in assisted living today
Assisted living is licensed and regulated by the states, not certified by CMS. The National Center for Assisted Living's annual *Assisted Living State Regulatory Review* describes a system in which each state sets its own licensing, staffing, training, move-in and disclosure requirements, and the result is real variation: the same operator can run communities under five different rulebooks. Memory care — a secured unit or a dedicated dementia-care licence — adds its own staffing and training rules and, in practice, a more controlled door. Screening is run by the community's executive director, its move-in or sales coordinator, and a regional or corporate HR and compliance function that holds the policy.
Move-in
A move-in begins with a nurse assessment, a negotiated service plan and an admission agreement. Whether it also includes a registry or criminal check of the applicant is a matter of state rule and community policy, and most states say nothing about it. Where a state speaks, it tends to speak about disclosure rather than a check: Virginia requires an assisted living facility to inform each resident, with written acknowledgment, that they may wish to consult the sex offender registry and to assist on request (Va. Code § 63.2-1808(A)(19)), and lets the facility ask the State Police for automatic notice when an offender registers nearby (Va. Code § 9.1-914). Minnesota's registrant-notification statute (Minn. Stat. § 243.166 subd. 4b) puts the disclosure duty on the offender and the notice on law enforcement for the health care facilities it covers; whether a given community falls within it is a licensing question. Illinois' Identified Offenders Program, by contrast, reaches nursing homes and hospitals but not communities licensed under the Assisted Living and Shared Housing Act. Operators that screen applicants anyway do so under their own admission policy, usually at the point the deposit is taken, and usually for both the registry and criminal records in the states the applicant has lived.
Staff and contractors
Here the states are specific, and the specifics differ. Florida requires Level 2 screening — fingerprints through the Care Provider Background Screening Clearinghouse, rescreened every five years — for assisted living personnel who provide personal care or have access to residents' funds, property or living areas (Fla. Stat. §§ 429.174, 408.809(1)(e), 435.04). Washington requires a name-and-date-of-birth check plus a national fingerprint check for the administrator and every caregiver "employed directly or by contract", and the name-and-date-of-birth check for volunteers, students and contractors with unsupervised access (WAC 388-78A-2462); WAC 388-78A-2470 bars employing a registered sex offender or anyone on an abuse, neglect or exploitation registry, and RCW 74.39A.056 requires state and federal checks for all long-term care workers. Oregon makes the licensee responsible for background checks on all "subject individuals", repeated every two years (OAR 411-054-0025). Texas assisted living facilities are "facilities" under Health & Safety Code chapter 250, so the Employee Misconduct Registry and nurse aide registry must be checked before employment, with no direct consumer contact while a criminal history check is pending (§ 250.003). Illinois lists establishments licensed under the Assisted Living and Shared Housing Act as "health care employers" under its Health Care Worker Background Check Act (225 ILCS 46/15), which bars hiring or retaining anyone with a registry finding of abuse, neglect or theft in a direct-care role (225 ILCS 46/25). Communities that bill Medicaid waiver programs also screen staff and contractors against the OIG's LEIE and the state exclusion list on the monthly cadence the OIG recommends (Special Advisory Bulletin, May 2013; 42 CFR 1001.1901).
Family visitors and the memory care door
Assisted living is a residence, and visiting is informal: a sign-in book or tablet at the front, a code or badge at the memory care door, and staff who know the regular visitors by face. Screening of visitors, where it exists, is targeted — a new visitor to a resident with a guardian, a person a family has asked the community to watch for, a state notice — and sits in the community's written visitation policy rather than in a statute. The memory care unit's real controls are elopement prevention and a staffed door, and the visitor log is as much about knowing who was in the building as about screening.
Where the API fits
| Workflow step | Endpoint | Fields that matter |
|---|---|---|
| Move-in — registry check on the applicant (where policy calls for it) | POST /v1/search, all 58 US registries | query.firstName, lastName, dob; subjectId = resident id, clientId = community; records[].matchState, matchedName.type, registrationState, addressStates, sources[].recordUrl |
| Move-in — criminal records in the states lived in | POST /v1/criminal/search, cached, one call per state | query.state; records[].recordCategory, cases[].charges[], currentStatus, normalized |
| Workforce and contractor exclusion check (Medicaid waiver communities) | POST /v1/criminal/search with include: ["exclusions"] | recordType: "healthcare_exclusion", exclusion.program, authority, convictionBased, excludedOn, reinstatedOn, profession |
| Per-community policy | Your configuration, keyed by clientId | Which checks run, which states, which roles — set with counsel from the state's rules; the code only reads it |
| Family visitor at the memory care door | POST /v1/search with age; see hospitals and visitor management for the kiosk flow | query.age; subjectId = visitor id; status: "partial" → "could not complete" |
| Look-alike resolved by the executive director | POST /v1/clearances | product, subjectId, clientId, personRef, searchId, verdict: "not_this_person", reviewer, note |
| Residents and staff stay watched | POST /v1/monitors, type: "person", one per dataset | person, minConfidence, label (community · person id), channels |
| The neighbourhood around a community (the API's version of a state's ZIP-code notice) | POST /v1/monitors, type: "location" | location.address or lat/lng, radiusMiles (0–100, default 3) |
Reference integration
The module is written for an operator with several communities. One API key serves all of them; clientId is the community, so a clearance recorded in Austin never hides a record in Tampa; subjectId is your resident or worker id. COMMUNITY_POLICY holds what each community has decided to run — the code reads it and never decides it. move_in_packet returns one Check per policy item for the move-in coordinator to attach to the admission agreement; worker_exclusion_check runs the exclusion tier for staff and contractors with direct access. Run it against the sandbox with an os_test_ key.
"""Assisted living and memory care — move-in and workforce screening for a multi-community operator.
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)
One API key serves every community; clientId (the community id) keeps each community's
clearances to itself, and subjectId (your resident or worker id) ties every search to one person.
"""
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")
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# Per-community policy is YOUR configuration, set with counsel from the state's rules — not a statement
# of what any state requires. The code only reads it.
COMMUNITY_POLICY = {The outcome logic and the reviewer card
| Outcome | Rule | The card the coordinator sees |
|---|---|---|
clear | records empty and status: "complete"; for criminal, counts.sourcesPending also 0 | The check line reads "clear" with its searchId; the packet proceeds. |
review | Candidates exist, none with the birth date confirmed (matchState is year_match, age_match or no_dob_age_year) | Registry: name, aliases, dob/age, matchState, matchBasis, matchedName, registeredBy, livesIn, offense, photo, registryPages. Criminal: recordType, recordCategory, currentStatus, where, one line per charge (description · severity · disposition), the exclusion block when it is a list record, sourcePages. |
match | A candidate with matchState: "dob_match" | The same card, flagged as the strongest tier. A person compares photo, aliases and addresses against the applicant before anything is decided. |
incomplete | status: "partial", or counts.sourcesPending > 0 on a criminal search | "A source did not finish" with the names; the check is rerun, not recorded as clear. |
skipped | The community's policy does not include this check | Shown as skipped, with the policy as the reason, so the packet says what was and was not run. |
refused / failed | 422 (detail on the registry search; error.code and error.message on criminal), 402, other errors | An operator message; nothing was billed on 429 or 5xx. |
matchedName.type: "alias", matchBasis carrying alias:exact); run a second search only for a prior legal name the applicant gives you, and merge by personRef. See matching and date of birth.Ongoing monitoring
Residents stay for years and staff turn over quickly, so a move-in or hire-date snapshot ages fast. A person monitor per resident and per worker — one for each dataset you watch — is evaluated once a day and alerts on new, changed and removed events. For a multi-community operator the label is the routing key: put the community id and the person id in it, and the alert reaches the right executive director.
curl -X POST https://sandbox.offendersearch.app/v1/monitors \
-H "X-API-Key: $OFFENDERSEARCH_API_KEY" -H "Content-Type: application/json" \
-d '{
"product": "criminal",
"type": "person",
"person": { "firstName": "Felony", "lastName": "Record", "dob": "1975-06-15" },
"label": "community-austin-01 · resident-3101",
"channels": { "emails": ["moveins@your-operator.example.com"] }
}'{
"type": "monitor.alert",
"event": "new",
"alertId": "hit_2b7e151628ae",
"monitorId": "mon_7f2a1c9e0b4d",
"monitorLabel": "community-austin-01 · resident-3101",
"product": "criminal",
"detail": {
"name": "Felony Sample Record",
"jurisdiction": "OH",
"locality": "Sampleville",
"matchLabel": "dob_match",
"matchConfidence": 0.95,
"personRef": "prs_1f3a9c0e7b2d4e6f8a1b",
"recordType": "court_case",
"externalId": "SBX-CR-2015-000123"
},
"occurredAt": "2026-10-25T08:00:00+00:00",
"sentAt": "2026-10-25T08:04:12+00:00"
}- A criminal person monitor alerts on exclusion-list records too (
detail.recordType: "healthcare_exclusion"with adetail.exclusionblock), which is how a Medicaid waiver community learns about a mid-year exclusion between monthly runs. - A location monitor around each community (
type: "location",radiusMiles) alerts when a registrant's published address enters or leaves the radius — useful where a state offers a ZIP-code notice and where it does not. - Deliveries are signed with the monitor's
webhookSecret; verify the header before acting. Cancel monitors at move-out and separation; cancelled monitors and their alerts stay readable.
See person monitoring, location monitoring and delivery.
When this is FCRA
Screening an applicant for move-in is a residential admission under your state's assisted living rules and your policy — not a tenant-screening or credit decision in the FCRA's sense for most communities, though counsel should confirm that for a community whose agreement is structured as a lease. Screening workers is different: deciding whether to hire, retain or assign an employee, agency caregiver or contractor is an employment purpose, and a report procured for it is a consumer report. The self-service API's legal.notice says it may not be used for any FCRA purpose. That workflow belongs on the FCRA Partner API — end users with certified purposes, consent attestations, a criminal search whose exclusions mode furnishes the same exclusion-list records, disputes and signed webhooks — available to approved partners; others receive 403 fcra_not_enabled. worker_exclusion_check above shows the records and fields; where your counsel treats a given workforce screen as a consumer-report use, run it as an FCRA order instead.
Evidence and audit
- The move-in packet. File each
Checkwith itssearchId,outcome, thestatus/counts/sourceStatus[]of the response and the coordinator's decision. A state surveyor reviewing a resident file then sees what was checked and what it showed. - Verification report.
POST /v1/report(registry) orPOST /v1/criminal/report(criminal) with thesearchIdrenders a timestamped PDF with every record, every field and a source citation per record, +$0.02; render it when the decision is made. Reports, criminal reports. - Registry page as evidence.
live: { "jurisdictions": [...], "evidence": "pdf" }prints the named registries' own pages; the202carries apollUrl, the finished search carriesevidence[].downloadUrl, readable for 30 days. Live evidence. - Clearances. Every
not_this_personverdict names thesearchId,reviewerandnote, and survives revocation for the audit trail.GET /v1/clearances?subjectId=…&clientId=…lists a resident's. Clearances. - Retention. Searches are kept in the account history for 14 days; store what you need to keep on your side, under your records-retention policy. Resident data is protected health information — backend calls over TLS, minimum fields, a BAA from Dashboard → BAA where counsel requires one.
Rollout plan
- Write the policy table first. For each community, decide with counsel which checks run at move-in, for which worker roles, in which states — and record it as the
COMMUNITY_POLICYconfiguration. The code must be able to say "skipped by policy" as clearly as it says "clear". - Run the sandbox module. Create an account, mint an
os_test_key in Dashboard → API keys, run the module againsthttps://sandbox.offendersearch.appand check each test name against the expected outcome, especially the alias andreviewcases. - Build the card and the two buttons. The reviewer card from the table above, the registry's own page via
registryPages, and "this person" / "not this person" wired toPOST /v1/clearanceswith the community asclientId. - Pilot one community. Swap to an
os_live_key for one community, run move-ins and the workforce check alongside the current process, and review everyreviewoutcome with the executive director to calibrate what the policy says about each tier. - Add monitoring and the other communities. Create monitors for current residents and staff with
label= community · person id, verify the webhook, then add communities oneclientIdat a time. Confirm with counsel which worker screens move to the FCRA Partner API before a hiring decision depends on one.