Developer docs · v1.0.0

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.

Named, not applied. These rules are cited so you can read them. Which apply to a given agency, role and worker, what they require before a first visit, how a result may be used, and whether a given check is a consumer report are decisions for your compliance officer and counsel. The API supplies records with provenance; it does not make an agency compliant.

Where the API fits

Workflow stepEndpointFields that matter
Register the agency (or each franchisee / branch entity) as the end user that holds the employment purposePOST /v1/fcra/end-usersname, externalId, permissiblePurposes: ["employment"], certification (text, version, certifiedAt, certifiedBy)
Pre-hire check before the first visitPOST /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 resultFcraOrder.searches[]status, result (clear, records_found, incomplete), recordCount, withheld{} (reasons a record was not furnished), records[]
Re-screen on the cadence or on a triggerThe same order call; POST /v1/fcra/searches/{search_id}/reverify to re-verify a furnished recordA new clientReference; the earlier order stays on file
Monthly exclusion-list runThe 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 rosterPOST /v1/monitors, type: "person", one per datasetperson, minConfidence, label = caregiver id, channels.webhookUrl; an alert triggers the regulated re-check
Awareness around a client's home for visit planningPOST /v1/monitors, type: "location"; on demand, GET /v1/map/viewport?center=&radiusMiles=location.lat/lng or address, radiusMiles; alerts in_radius
Separation or dischargeDELETE /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"}

GET /v1/fcra/orders/{order_id} — the Sanctioned subject, trimmed
{
  "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 saysRuleWhat the recruiter sees
ClearEvery search status: "complete" with result: "clear" and withheld emptyThe file is complete for this check; the orderId, completedAt and controlVersion are stored with it and the scheduler may assign.
Records foundA 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 recordsresult: "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.
IncompleteA 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.
Refused403 fcra_not_enabled / fcra_purpose_not_allowed, 404 unknown_end_user, 422 end_user_suspendedAccount, agreement or end-user setup — nothing ran.
Note. The exclusion-list tier is a choice on the criminal search: 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.

Receive monitor alerts and queue the re-check
// 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_match with a DOB, name_match without).
  • 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_allowed otherwise). 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 a controlVersion on 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=…) for order.completed, search.completed, dispute.* and record.corrected events. Disputes, webhooks.
  • Partner-only. The live host answers 403 fcra_not_enabled without a signed partner agreement; the sandbox treats every os_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, clientReference and each search's status, result, recordCount and withheld{} 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 (or json) 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's completedAt, controlVersion and report hashes — proof of what was produced, without any record content. Evidence.
  • Evidence captures. GET /v1/fcra/orders/{order_id}/evidence lists the source captures behind furnished records; each is downloadable by capture_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

  1. 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.
  2. Build against the sandbox. Create an account, mint an os_test_ key in Dashboard → API keys, run the module above against https://sandbox.offendersearch.app, and exercise every last-name outcome (Clear, Records, Withheld, Unavailable, Excluded, Sanctioned, Dispute). FCRA sandbox.
  3. Wire the webhook endpoint. Set the FCRA webhook endpoint (PUT /v1/fcra/webhook-endpoint), verify X-Offendersearch-Signature, and handle order.completed and record.corrected. Set the Monitoring receiver with a secret token in its URL.
  4. Integrate the caregiver system. Trigger caregiver_order from the offer stage of your applicant tracking or caregiver-management system; block scheduling until the order is complete with the outcome your policy accepts; store the order row and the report with the file.
  5. 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.
  6. 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.