Home health and home care agencies
A caregiver works alone in someone's home. Here is how agencies screen before the first visit and keep screening afterwards, and which API each step belongs on.
How screening works in home care today
Home health agencies (skilled, Medicare-certified) and home care agencies (non-medical personal care, state-licensed) share one fact that shapes everything: the worker is alone with the client, in the client's home, with no supervisor in the next room. Screening is therefore front-loaded. A recruiter or HR coordinator runs the checks between offer and first visit, a scheduler will not assign a caregiver whose file is incomplete, and the agency's compliance officer owns the periodic re-checks. Agencies with many branches run this from a central applicant-tracking or caregiver-management system that already holds the identifiers the checks need — legal name, date of birth, the states the caregiver has lived and worked in.
What the rules require
The Medicare home health Conditions of Participation set personnel qualifications by discipline (42 CFR 484.115) and require staff to be licensed, certified or registered as state law requires (42 CFR 484.100(b)); they do not themselves require a criminal background check. The OIG said so directly in 2015: "there are no Federal laws or regulations that require HHAs to conduct background checks" (OEI-07-14-00130), while its companion report found that 41 states required home health agencies to check prospective employees as of January 2014, that every sampled agency ran a pre-hire check, and that about half also re-checked after hire (OEI-07-14-00131). Hospice is the exception with a federal rule: 42 CFR 418.114(d) requires a criminal background check on every hospice employee with direct patient contact or access to patient records, requires hospice contracts to impose the same on contracted staff, and — where the state sets no requirement — requires the check within three months of employment for every state the person lived or worked in during the prior three years.
State law carries the detail, and the detail is about timing and registries. California's Home Care Services Consumer Protection Act (Health & Safety Code § 1796.10 et seq.) requires an affiliated home care aide to be listed on the Home Care Aide Registry before providing services (§ 1796.14(b)), after electronic fingerprint submission to the Department of Justice (§ 1796.23) and a clearance or exemption issued before registration (§ 1796.24). Illinois' Health Care Worker Background Check Act (225 ILCS 46; 77 Ill. Adm. Code 955) covers home health care aides and personal care assistants, requires registry verification before employment, and bars hiring or retaining a person with a disqualifying conviction absent a waiver. Washington requires state and FBI fingerprint checks for long-term care workers, allowing unsupervised work while the FBI result is pending if the state check is clear (RCW 74.39A.056). New York's Criminal History Record Check program (10 NYCRR Part 402) covers Article 36 home care agencies, keeps a temporary employee under documented supervision until results arrive, and sends a subsequent-arrest notification the agency must risk-assess. Texas home and community support services agencies must check criminal history and the nurse aide and Employee Misconduct Registries before hiring, re-search the registries at least every twelve months, and check volunteers before a first face-to-face client contact (Tex. Health & Safety Code § 250.003; 26 TAC § 558.247).
Agencies billing Medicare or Medicaid also screen against the OIG's List of Excluded Individuals/Entities and their state Medicaid exclusion list. The OIG's 2013 Special Advisory Bulletin notes the LEIE is updated monthly, that monthly screening "best minimizes" liability, and that exposure attaches whether the person is an employee, a contractor or a volunteer (42 CFR 1001.1901). Sex offender registry checks are a common component of the pre-hire package agencies buy from screening vendors, alongside the criminal check and the registries above.
Cadence, and the client's household
The cadence that emerges is: everything before the first visit; a registry re-search annually where the state says so; a criminal re-check on a fixed cycle (annual or biennial is common) or on a trigger such as a subsequent-arrest notice; exclusion lists monthly. The household is the other half of the safety picture. OSHA's *Guidelines for Preventing Workplace Violence for Healthcare and Social Service Workers* (OSHA 3148, 2016) treat home visits as field work in private residences where engineering controls may be impossible, and its field-work checklist asks whether workers are told of past violent acts by particular clients, briefed about the area they will work in, able to refuse service in a hazardous situation, and always known to be somewhere by someone. OSHA says nothing about screening a client's household members; agencies address the household through the intake assessment and those field-safety practices.
Where the API fits
| Workflow step | Endpoint | Fields that matter |
|---|---|---|
| Register the agency (or each franchisee / branch entity) as the end user that holds the employment purpose | POST /v1/fcra/end-users | name, externalId, permissiblePurposes: ["employment"], certification (text, version, certifiedAt, certifiedBy) |
| Pre-hire check before the first visit | POST /v1/fcra/orders → 202, then webhook order.completed or GET /v1/fcra/orders/{order_id} | permissiblePurpose: "employment", consent (obtainedAt, method, documentRef), subject (firstName, lastName, dob, addresses[].state), useLocation.state, searches[] (sex_offender; criminal with exclusions: "all"), clientReference, Idempotency-Key |
| Read the result | FcraOrder.searches[] | status, result (clear, records_found, incomplete), recordCount, withheld{} (reasons a record was not furnished), records[] |
| Re-screen on the cadence or on a trigger | The same order call; POST /v1/fcra/searches/{search_id}/reverify to re-verify a furnished record | A new clientReference; the earlier order stays on file |
| Monthly exclusion-list run | The criminal search of an FCRA order with exclusions: "all" | dispositionStatus: "sanction" marks an exclusion-list record; conviction_only is the default mode |
| Know when something changes on the active roster | POST /v1/monitors, type: "person", one per dataset | person, minConfidence, label = caregiver id, channels.webhookUrl; an alert triggers the regulated re-check |
| Awareness around a client's home for visit planning | POST /v1/monitors, type: "location"; on demand, GET /v1/map/viewport?center=&radiusMiles= | location.lat/lng or address, radiusMiles; alerts in_radius |
| Separation or discharge | DELETE /v1/monitors/{monitorId} | Evaluation stops now |
The split is deliberate. A caregiver check decides employment, so it runs as an FCRA order; the self-service search and criminal endpoints carry a legal.notice that they are not consumer reports and must not be used for that decision. Monitoring is a signal, not a decision: an alert tells the compliance officer to run the regulated re-check now instead of waiting for the calendar.
Reference integration
Two halves. register_agency_end_user and caregiver_order are the regulated check — partner-only on the live host (403 fcra_not_enabled otherwise), but every os_test_ key is an enabled sandbox partner, so the module runs as written against the sandbox, where an order completes immediately and the outcome is chosen by the subject's last name (Clear, Records, Withheld, Unavailable, Excluded, Sanctioned). watch_caregiver and watch_client_home are Monitoring. The webhook receiver for alerts is in the next section.
"""Home health and home care — caregiver screening and roster monitoring. Python 3.11+, requests.
Two different APIs for two different decisions:
caregiver_order() the pre-hire and re-screen check — an FCRA order (partner-only on the live host;
every os_test_ key is an enabled sandbox partner, so this runs as written)
watch_caregiver() Monitoring: a standing person watch on each active caregiver
watch_client_home() Monitoring: a location watch around a client's home for the care team's awareness
OFFENDERSEARCH_API_KEY os_test_… (sandbox) or os_live_… (production)
OFFENDERSEARCH_BASE https://sandbox.offendersearch.app (default here)
"""
from __future__ import annotations
import os
import time
from datetime import datetime, timezone
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"}
{
"id": "fo_ee0b34c5b52fd35b",
"status": "complete",
"createdAt": "2026-10-25T14:10:02+00:00",
"updatedAt": "2026-10-25T14:10:02+00:00",
"completedAt": "2026-10-25T14:10:02+00:00",
"cancelledAt": null,
"clientReference": "hire-sanctioned-001",
"endUserId": "eu_8a2f1c3d",
"permissiblePurpose": "employment",
"useLocation": { "state": "OH" },
"controlVersion": "fcra-controls-2026-10-19.1",
"liveScope": "relevant",
"sandbox": true,
"searches": [
{ "id": "fs_452884eecde9a1f2", "type": "sex_offender", "status": "complete", "result": "clear",
"recordCount": 0, "withheld": {}, "incompleteReasons": [], "records": [] },
{ "id": "fs_452884eecde9a1f3", "type": "criminal", "status": "complete", "result": "records_found",
"recordCount": 1, "withheld": {}, "incompleteReasons": [],
"records": [ { "recordId": "sandbox:excl:a:5a17c0de00000002", "type": "criminal", "dispositionStatus": "sanction",
"retrievedAt": "2026-10-25T14:10:02+00:00", "corrections": [], "sandbox": true } ] }
]
}The outcome logic
| What the order says | Rule | What the recruiter sees |
|---|---|---|
| Clear | Every search status: "complete" with result: "clear" and withheld empty | The file is complete for this check; the orderId, completedAt and controlVersion are stored with it and the scheduler may assign. |
| Records found | A search with result: "records_found"; records[] carries each furnished record with matchBasis, and for criminal records dispositionStatus and cases[] | The report (GET /v1/fcra/orders/{order_id}/report) and the adverse-action steps your FCRA process already defines. The API furnishes; your process decides. |
| Clear, with withheld records | result: "clear" but withheld has counts (e.g. insufficient_identifiers, not_current_at_source) | Nothing is furnished because the controls would not allow it; the counts explain why the report is shorter than a self-service search would be. Not a defect. |
| Incomplete | A search ending status: "unavailable" with result: "incomplete" and incompleteReasons[] | The sources could not be reached; the order completes anyway. Re-order later; do not treat as clear. |
| Refused | 403 fcra_not_enabled / fcra_purpose_not_allowed, 404 unknown_end_user, 422 end_user_suspended | Account, agreement or end-user setup — nothing ran. |
conviction_only (default) furnishes exclusions whose basis is a conviction; all adds administrative exclusions such as a licence action; none furnishes no exclusion-list record. The sandbox Sanctioned subject is clear under the default and furnished under all. FCRA results.Ongoing monitoring
A roster of several hundred caregivers changes under you: someone is excluded in March, someone is added to a registry in July, and the annual re-check is in November. Monitoring puts a standing person watch on each active caregiver — one monitor per dataset — evaluated once a day. When an alert arrives, the agency runs the regulated re-check (caregiver_order again, or POST /v1/fcra/searches/{search_id}/reverify on the furnished record) and lets its FCRA process take it from there. The alert itself is not the decision, and Monitoring carries the same not-a-consumer-report notice as the rest of the self-service API; ask counsel how an alert may be used.
// Express: receive Monitoring alerts. Every delivery is signed with the monitor's webhookSecret
// (returned once on the 201) — verify over the RAW body before parsing. Answer 2xx fast; do the work after.
import express from "express";
const app = express();
import crypto from "node:crypto";
const SECRET = process.env.OFFENDERSEARCH_WEBHOOK_SECRET; // channels.webhookSecret from the 201
app.post("/hooks/offendersearch", express.raw({ type: "application/json" }), (req, res) => {
const parts = Object.fromEntries(String(req.get("X-Offendersearch-Signature") ?? "").split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", SECRET).update(`${parts.t}.`).update(req.body).digest("hex");
const ok = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300 &&
parts.v1?.length === expected.length && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
if (!ok) return res.sendStatus(401);
const { type, event, alertId, monitorId, monitorLabel, product, detail } = JSON.parse(req.body); // type: "monitor.alert"
if (type === "monitor.alert" && event !== "removed") {
// detail: { name, jurisdiction, locality, matchLabel, matchConfidence, personRef, recordId? (sex-offender),
// recordType? / externalId? / exclusion? (criminal) }
queueRescreen({ caregiverId: monitorLabel.split(" · ")[0], alertId, monitorId, product, detail });
}
res.sendStatus(204);
});
app.listen(8080);- Set
minConfidence: "year_match"when you have a date of birth and want fewer name-only alerts; leave it unset to get the default (year_matchwith a DOB,name_matchwithout). - The first evaluation reports every current match as
new; expect alerts immediately for anyone who already has a record, and treat them as the re-check trigger they are. - A location monitor around a client's home alerts when a registrant's published address enters the radius (
matchLabel: "in_radius"); the alert carries the registrant's name, jurisdiction and city, never a street address. It informs visit planning; it says nothing about the client or the caregiver. - Cancel at separation or discharge. The monitor and its alerts stay readable; it is not charged on any invoice prepared after the cancel.
Person monitoring, location monitoring, alerts, webhooks and lifecycle.
When this is FCRA
This is the industry where the core job is a consumer report. Deciding whether to hire a caregiver, keep them, or assign them to a client is an employment purpose under the Fair Credit Reporting Act, and a background report procured from a third party for that purpose is a consumer report. The self-service Sex Offender Search, Criminal Records and Monitoring APIs must not be the basis for that decision; every response says so in legal.notice. The path is the FCRA Partner API, and what changes is the shape of the work, not just the endpoint:
- An end user (the agency) registered with its permissible purposes and a certification you record; orders can state only a purpose the end user holds and your partner agreement allows (
403 fcra_purpose_not_allowedotherwise). Access. - A consent attestation on every order (
obtainedAt,method,documentRef) and the subject's addresses, which drive which jurisdictions are searched and which state rules apply. - Controls applied at furnish time — reporting-period limits, state registry withholding, the exclusion-list mode — with the
withheld{}counts telling you what was held back and why, and acontrolVersionon the order. Controls. - Disputes (
POST /v1/fcra/orders/{order_id}/disputes), a consumer portal the subject can use, and signed webhooks (X-Offendersearch-Signature: t=…,v1=…) fororder.completed,search.completed,dispute.*andrecord.correctedevents. Disputes, webhooks. - Partner-only. The live host answers
403 fcra_not_enabledwithout a signed partner agreement; the sandbox treats everyos_test_key as an enabled partner so you can build first.
Whether a particular check — an exclusion-list screen of current staff, a registry re-search a state requires annually — is a consumer-report use is a question for your counsel. Where it is, it runs as an FCRA order.
Evidence and audit
- The order is the record. Store
orderId,createdAt,completedAt,permissiblePurpose,controlVersion,clientReferenceand each search'sstatus,result,recordCountandwithheld{}with the caregiver file. A state surveyor asking "what did you check before the first visit, and when" is answered from that row. - The report.
GET /v1/fcra/orders/{order_id}/report?format=pdf(orjson) renders the regulated report with the required notices; file the PDF with the hire. Orders. - Receipts.
GET /v1/fcra/receipts/{order_id}returns an Ed25519-signed receipt over the order'scompletedAt,controlVersionand report hashes — proof of what was produced, without any record content. Evidence. - Evidence captures.
GET /v1/fcra/orders/{order_id}/evidencelists the source captures behind furnished records; each is downloadable bycapture_id. - Retention. No retention period is published for FCRA order data; keep your own copies of the report, receipt and order row under your records policy and your partner agreement. Monitoring alerts stay readable on the monitor (
GET /v1/monitors/{monitorId}/alerts, up to 200).
Rollout plan
- Confirm the regulated path. With counsel, map each check your agency runs (pre-hire, periodic, registry re-search, exclusions) to "FCRA order" or "not a consumer report". Apply for partner access for the first group; it is an agreement, not a toggle. Access.
- Build against the sandbox. Create an account, mint an
os_test_key in Dashboard → API keys, run the module above againsthttps://sandbox.offendersearch.app, and exercise every last-name outcome (Clear,Records,Withheld,Unavailable,Excluded,Sanctioned,Dispute). FCRA sandbox. - Wire the webhook endpoint. Set the FCRA webhook endpoint (
PUT /v1/fcra/webhook-endpoint), verifyX-Offendersearch-Signature, and handleorder.completedandrecord.corrected. Set the Monitoring receiver with a secret token in its URL. - Integrate the caregiver system. Trigger
caregiver_orderfrom the offer stage of your applicant tracking or caregiver-management system; block scheduling until the order iscompletewith the outcome your policy accepts; store the order row and the report with the file. - Pilot one branch live. Switch that branch to an
os_live_key under the partner agreement, run new hires through the order flow alongside the current vendor for a cycle, and compare outcomes and turnaround. - Roster monitoring and the re-screen cadence. Create person monitors for the active roster, route alerts to the compliance queue as re-check triggers, and schedule the periodic orders your states require. Cancel monitors at separation.