HomeCareBilling API changelog
Changes to the HomeCareBilling REST API, newest first. Each heading is the
API version, as hcb-api-version and the OpenAPI document's info.version
state it. Additive changes within a version are listed under it; a breaking
change starts a new version under a new path. A deprecation is listed here
with its sunset date at least six months before the operation stops
answering.
1
Published September 24, 2026, at /api/v1. Deprecations: none.
Added October 24, 2026 (US-74.8, DCW Workforce Report):
GET /api/v1/reports/workforce(from,to, at most a year apart;limit,offset): each Direct Care Worker's hours, lowest wage, four-week average hours, members served and counties per primary service, for HCPF's Base Wage Attestation and Workforce Reporting. The MCP toolget_workforce_reportanswers the same function.
Changed October 24, 2026 (#2997, file answers that survive a cut):
- MCP file answers carry base64 beside the
download_urlonly up to 4 KB (was 16 KB). The answer holds the base64 twice, so a 12 KB 837 answered 33.9 KB, past a gateway that cuts near 20 KB, with the link after the cut point.delivery: "inline"is unchanged. - Company document and export files carry a charset only on text types (a
PDF went out as
application/pdf; charset=utf-8), and their file name in RFC 6266's encoded form (filename*=UTF-8''...).
Changed October 24, 2026 (#2997, print parameters by their names):
GET /api/v1/print/{form},GET /api/v1/print/{form}/{id}.pdfand theget_print_documenttool refuse a parameter the form does not read, naming the ones it does (400bad_request; a tool error over MCP). It used to be ignored, so a client that sentdate_fromfor a communication report'sfromgot the default range with no sign of it. The operations' descriptions and the tool'sparamslist what each form reads.- A print's PDF is served
inlinerather thanattachment, so a person who opens an assistant'sdownload_urlsees it in the browser, ready to print.
Changed October 24, 2026 (#2997, file answers any AI client can open):
- Every MCP file answer now carries a
download_urlthat opens WITHOUT the Authorization header for 10 minutes: a signed link for that one file, on that one AI connection, so an assistant whose model cannot attach the connection's token, or the person it hands the link to, can open or print it. Each fetch re-checks the connection, the agency's consent and the member, as a token would; revoking the connection closes its links. The answer isprivate, no-storeand sends no Referer. The token still works. The link is never the access token, which is still never read from a URL. - base64 now rides along only for a small file (4 KB since the entry above) (it encodes before the
link, so a gateway that cuts a long answer would cut the link off too).
delivery: "inline"sends base64 up to 1 MiB beside the link, for a client that must pass the bytes on.
Changed October 24, 2026 (#2997, an MCP client that cuts tool results short):
- Every MCP tool that answers a file (
get_print_document,print_client_work_orders,export_shift_plan,get_batch_837,get_person_document_file,get_company_document_file,get_data_export_file,get_client_note_attachment,get_caregiver_note_attachment) takes an optionaldelivery:auto, the default, answers as before (base64 up to 1 MiB, else adownload_url);urlanswers only the/mcp/filesdownload_url, whatever the size, without making the file. The fetch makes it, checks the record and writes the audit row, so a record that does not exist is reported there.
Changed October 23, 2026 (Epic 109, US-109.7, one status for many caregivers):
PATCH /api/v1/caregivers/status(caregiver_ids, at most 200, andstatus): sets each caregiver to the status, saving each one on its own so a refused save leaves the others saved. The answer listsupdatedandfailed, each failure with the caregiver's id, name (null for an id that is not this agency's caregiver) and the reason in words. An archived caregiver is a failure, not a change. A caregiver already at the status counts as updated and writes no audit row; each one that changed writes one. One caregiver sent twice, in either letter case, is set and counted once. An unknown status or one that is not a string, no ids, more than 200, or an id that is not a string is 422validation_failed, and nothing is written.- The MCP tool
update_caregiver_statusesanswers the same function. Its PHI access row names the agency's caregivers the call found, never an id it did not find.
Changed October 23, 2026 (Epic 109, US-109.3, the attention queue):
GET /api/v1/attention(kind,limit,offset): everything about a client or caregiver that needs doing, overdue first (oldest first, undated last among them), then soonest due. Each row carrieskind(due_today,overdue,compliance,oig,supervisory_visit,recertification,authorization_ending,follow_up),subject_type(client,caregiver, oragencyfor a reminder with no client),subject_id,subject_name("Last, First"),due_on,action_label("Renew by Nov 3") andpath, the app page that does it.limitdefaults to 20 and is at most 100;totalis the true count. An unknownkindis 422invalid_kind.- The MCP tool
needs_attentionanswers the same function.
Changed October 22, 2026 (Epic 108, US-108.9, the dollars unused on a PAR):
GET /api/v1/authorizationsandGET /api/v1/authorizations/{id}carryunused_value: roughly what the authorized units no claim has billed yet are worth, in whole US dollars as a string ("2496"), at HCPF's published rate on the authorization's end date for its code and modifiers (HX dropped, as a PAR never carries it). Null unless the authorization is active, or when no published rate prices it. The MCP toolsfind_authorizationsandget_authorizationcarry the same field.
Changed October 22, 2026 (Epic 108, US-108.3, underpaid claims):
GET /api/v1/underpayments(paid_from,paid_to,include_dismissed,limit,offset): paid claims HCPF paid less than its published rate for the dates of service, after the adjustments that lawfully explain short pay, the largest gap first. Each row carriesclaim_id,client_id, the service and paid dates,procedure_code,modifiers,units,published_rate,tenant_rate,expected,paid,gap,carcs(each with itsdescription), and thekindandfingerprintto dismiss it with. The page addstotal_gap,truncated(more than 5,000 paid claims in the period, so only the newest-paid were judged),paid_fromandpaid_to. Paid dates default to the last 90 days; a range over 366 days is 400. Dismissed rows are left out unlessinclude_dismissedis true. Dismissing isPOST /api/v1/revenue-warnings/dismissalswith kindunderpayment.- The MCP tool
list_underpaymentsanswers the same function.
Changed October 22, 2026 (Epic 108, US-108.5, resubmission deadlines):
GET /api/v1/resubmission-deadlines(within_days,include_dismissed,limit,offset): denied and unpaid claims, the soonest resubmit-by date first (idandclaim_id, both the claim's id,batch_id,client_id,service_date_from,service_date_to,procedure_code,status,icn,resubmit_by,basis,days_left,kind,fingerprint,dismissed). A dismissed line is left out unlessinclude_dismissed=true; dismiss one withPOST /api/v1/revenue-warnings/dismissals, kindresubmission_deadline.- The MCP tool
list_resubmission_deadlinesanswers the same function.
Changed October 22, 2026 (Epic 108, US-108.1, dismissible revenue warnings):
GET /api/v1/batches/{id}/revenue-warnings: every revenue warning on the batch's claims, in row order (claim_id,row_number,kind,fingerprint,message,dismissed), paged. A warning blocks nothing. Another agency's batch answers 404.POST /api/v1/revenue-warnings/dismissals(kind,subject_id,fingerprint) dismisses one until its figures change, 201 with the dismissal; dismissing one already dismissed answers the existing dismissal.DELETE /api/v1/revenue-warnings/dismissalswith the same body shows it again, 204. An id naming no claim of the agency answers 404 before the rest of the body is judged; a kind no warning has is 422unknown_kind.- The MCP tools
list_batch_revenue_warnings,dismiss_revenue_warningandrestore_revenue_warninganswer the same functions.
Changed October 22, 2026 (Epic 108, US-108.8, Medicaid revalidation dates):
GET /api/v1/provider-revalidations,POST /api/v1/provider-revalidations,PATCH /api/v1/provider-revalidations/{id}andDELETE /api/v1/provider-revalidations/{id}: the revalidation due date for each NPI the agency bills under (npi,location_name,revalidation_due_on,notes), nearest first. Writes need an admin credential (403 forbidden otherwise); a changed date clearslast_alerted_threshold, so it is reminded again at 90, 60 and 30 days.- The MCP tools
list_provider_revalidations,save_provider_revalidation(adds, or changes one givenprovider_revalidation_id) anddelete_provider_revalidationanswer the same functions.
Changed October 22, 2026 (Epic 107, US-107.11, a client's month printed as one document):
GET /api/v1/print/{form}takes the formclient_work_orderswithclient_idandmonth(YYYY-MM): every live Work Order of the client in force in that month, one sheet each, Personal Care before Homemaker, then by shift and WO #, footed "Page N of M" across the document;format=pdf, or/api/v1/print/client_work_orders/{client_id}.pdf, answers it as a PDF. Another agency's client, or a deleted one, answers 404.- The MCP tool
print_client_work_orders(client_id,month) answers that PDF as the other print tools do.
Changed October 21, 2026 (Epic 107, US-107.10, one way to make a client's Work Orders):
GET /api/v1/clients/{id}/shift-planandget_shift_plancarryother_work_orders, the client's live Work Orders made outside the Shift Plan that are in force this month or later (id, number, service, caregiver, effective_date, closing_date; at most 50), andhma, the client's HMA calculator week (plan_id,weekly_minutes) or null.POST /api/v1/plans-of-care/{id}/work-orders/distributeanddistribute_plan_work_orderscarryshift_plan_work_orders, the Work Orders the client's Shift Plan made that are in force in the month, each with itsshift_id; empty when the client has no Shift Plan. The Work Orders are made regardless.
Changed October 21, 2026 (Epic 107, US-107.14, the card's task columns):
GET /api/v1/clients/{id}/shift-planandget_shift_plan: each card row gainsmin_task(a decimal string, the row's week over its visits as the printed Work Order writes it: 40 + 35 is "37.5"),times(its marks on the shift) andweek(its day minutes added); all three null on a row with no marks on that shift.
Changed October 21, 2026 (Epic 107, US-107.6, one plan PDF):
GET /api/v1/print/{form}and the MCP toolget_print_documenttake the formshift_planwithclient_id: the client's Shift Plan as one document, a Letter portrait sheet per shift, Personal Care's then Homemaker's, footed "Page N of M" across the plan;format=pdfanswers it as a PDF. Another agency's client, or a deleted one, answers 404.
Changed October 21, 2026 (Epic 107, US-107.8, the Shift Plan in her words):
PUT /api/v1/clients/{id}/shift-plan/care-instructions/{shift_id}and the MCP toolset_shift_plan_care_instructions: one card's Care Instructions, as the card's box keeps them. They are that shift's Work Order notes: Generate writes them, and a change rewrites the notes of a Work Order already generated for the shift, audited as a relayed setting. Blank or null removes them; a text longer than a Work Order's notes hold answers 422too_long, a shift id no plan has 404.GET /api/v1/clients/{id}/shift-plan:settings.care_instructions; each card'safter,care_instructionsandcaregiver_week(the shift's caregiver's week across the agency's clients, null with no active caregiver); each day'sby_day, true when the shift starts at a time of its own that day (set throughshift_settingsby_day in PATCH); each service'soff_tasks; each task row'ssplit. A split task is no longer amongwarnings, and a caregiver who also works for another client at an overlapping or too-close time is named there, one line per day and visit.- A client's first Shift Plan takes the days, shifts a day, each shift's start and "after", the gap, the split and the marks of the agency's most recently changed one, instead of the fixed defaults; with no plan yet, the defaults.
Changed October 21, 2026 (Epic 107, US-107.3, a caregiver is optional and picks are saved):
PUT /api/v1/clients/{id}/shift-plan/caregivers/{shift_id}and the MCP toolset_shift_plan_caregiver: save the caregiver picked for a shift, or let go of it withcaregiver_id: null, before Generate or after. A caregiver the agency has none of on file (another agency's, a deleted one) answers 404 and nothing is saved; an inactive one is saved and comes back as a warning.GET /api/v1/clients/{id}/shift-planandget_shift_plancarrycaregivers, shift id => the caregiver picked for it.POST /api/v1/clients/{id}/shift-plan/generateandgenerate_shift_plan_work_orders: a shift left out ofcaregiverstakes its saved pick, no longer its Work Order's caregiver; each caregiver sent is saved as the shift's pick. A shift with no pick is skipped asno_caregiverand keeps the Work Order it has.
Changed October 21, 2026 (Epic 107, US-107.7, the task table as on her page):
POST /api/v1/clients/{id}/shift-plan/tasks/addand the MCP tooladd_shift_plan_task: the task table's Add task. A task of the state form goes into the table on the Shift Plan, never on the Plan of Care, at 15 min × 1 = 15 min a week, or with the calculator's figures when it was taken out earlier. A task already in the table changes nothing; a name the form does not list for the service answers 422unknown_task.DELETE /api/v1/clients/{id}/shift-plan/tasks/{service}/{task}and the MCP toolremove_shift_plan_task: the task table's ×. The task leaves the table, the layout and the changed cells of its row; a task the table does not hold answers 404.GET /api/v1/clients/{id}/shift-plan:task_tablelists each service's tasks in the state form's order, under the form's names ("Meal Prep/Menu Planning", "Bladder Care"); each row gainsnorm,maxandover_max(the state's weekly maximum, a warning only). Newtask_totals(each service's Min / week and CFC hours) andaddable(the form's tasks Add task offers).
Changed October 21, 2026 (US-107.9):
POST /api/v1/cfc-calculatorand the MCP toolcreate_client_from_cfc_calculator: a new client from a CFC calculator. The card read from it (last_nameandfirst_namerequired;medicaid_id,addressandphonewhen the calculator has them) makes the client, and the calculator's import job starts for it, asPOST /api/v1/clients/{id}/cfc-calculatorstarts one. The answer'soutcomeiscreated,existing(the Medicaid ID, or with none the name, is on file for the same person: no client is made and the import is for that client) orconflict(the Medicaid ID is on file under another name: 200,importnull, nothing written). A card the client form refuses answers 422validation_failed, and nothing is made.- A calculator row whose Min / week is not its Min / task times its Times / week is imported with its days spread over that Min / week, so they add up to the week the task keeps.
Changed October 21, 2026 (Epic 107, US-107.1, a Shift Plan keeps the office's own cells):
POST /api/v1/clients/{id}/shift-plan/cellsandset_shift_plan_celltake nolock_versionand never answer 409: a cell is kept on the Shift Plan as the office's own value, on any shift, generated or not, and every later change lays the week out again under it. The count the automatic layout gives that cell lets go of the change. A shift the plan does not have, or a row on no Work Order task of the plan, answers 404. Alock_versionstill sent is ignored.POST /api/v1/clients/{id}/shift-plan/undoandundo_shift_plan_editslet go of every cell change, then return each generated Work Order to the layout; they no longer answer 409.GET /api/v1/clients/{id}/shift-plan: every card's day cells are the layout with the office's cells over it, a generated card's too, never its Work Order's stored lines; a cell'seditedis true exactly where the office set it.
Changed October 21, 2026 (Epic 104, the Shift Plan):
GET /api/v1/clients/{id}/shift-planand the MCP toolget_shift_plan: the client's Shift Plan as the Shift Plan screen shows it (made with the agency's defaults on the first read): its settings, each service's week against its calculator, one card per shift with its generated Work Order, day columns and rows of day cells, the task table,warningsandprint_problems. Days are the plan's own, 0 Saturday to 6 Friday. Each read is audited against the plan and its client.PATCH /api/v1/clients/{id}/shift-planandupdate_shift_plan_settings: the settings sent, as the screen saves them; a malformed value answers 422 naming its field.POST /api/v1/clients/{id}/shift-plan/cellsandset_shift_plan_cell: one day cell, against the card'slock_version; a Work Order written since answers 409stale_recordand nothing is saved.POST /api/v1/clients/{id}/shift-plan/undoandundo_shift_plan_edits: the screen's Undo my changes, answeringundone_shifts.POST /api/v1/clients/{id}/shift-plan/tasksandupdate_shift_plan_task: one task-table figure (times,min_taskormin_week); a value not above 0 answers 422invalid_figure, one past a week 422too_large.POST /api/v1/clients/{id}/shift-plan/generateandgenerate_shift_plan_work_orders: the screen's Generate, with optionalcaregiversper shift, answeringgenerated(the Work Orders written, replaced, archived and skipped, and the warnings). Nothing is refused for the layout.GET /api/v1/clients/{id}/shift-plan/exportandexport_shift_plan: the screen's Download Excel, audited as an export before it is sent.- Every write answers the Shift Plan as the screen shows it next, in
data. Another agency's client answers 404.
Changed October 18, 2026 (#2567):
POST /api/v1/broadcastsand the MCP toolsend_broadcasttakerecipient_scopepick, implied by either new field:caregiver_ids, the agency's caregivers to send to whatever their status (former ones included, at most 1000), andtag, every caregiver carrying it (any case), active ones only unlessinclude_formeris true. An id that is not one of the agency's caregivers answers 422validation_failed. A caregiver opted out of SMS is never texted, onbothtoo.Broadcastgainsreply_countandyes_count.GET /api/v1/broadcastsand the MCP toollist_broadcasts: the agency's broadcasts, newest first, paged, each withmessage,reply_countandyes_count.GET /api/v1/broadcasts/{id}/repliesand the MCP toollist_broadcast_replies: the caregivers who texted back to a broadcast, latest first, each with the reply,yesandreplied_at; another agency's broadcast answers 404. Each read is audited against the caregivers it returned.
Changed October 17, 2026 (US-102.37):
GET /api/v1/payroll-summaryand the MCP toolget_payroll_summary: the Payroll Summary of a month (year,month, both required) or one of its pay periods (period, an index intopay_periods), computed as the Payroll Summary page computes it. Each caregiver's row carries the regular, overtime, daily overtime, travel and attendant hours, the rates applied,total_pay, the cash advance this payroll deducts and the timesheets the hours came from; rows are sorted by name and paged withlimitandoffset, andtotalsare over every row. A cash advance another payroll file holds is listed incash_advance_held, worded as the page words it ("$50.00 on the Oct 01 - Oct 15, 2026 file"), and is in neithercash_advancenor the totals. Each read is audited against the caregivers it returned.GET /api/v1/cash-advancesand the MCP toollist_cash_advances: the agency's cash advances, newest first, filtered bystatus,searchanddeduct_in_month(YYYY-MM), paged, withtotalsofamountandremaining_balanceover every advance the filters match.CashAdvancegainsreason, in every answer, andcaregiver_name, in the list.GET /api/v1/payroll/w4-changesand the MCP toollist_w4_changes: the caregivers whose W-4 changed since payroll was last sent it, longest waiting first, with the ADP file number, filing status, dependents and when it changed, as the Payroll Summary's W-4 panel lists them. Paginated withlimitandoffset; each read is audited against the caregivers it returned.GET /api/v1/supervisory-visits/dueandsupervisory_visits_duetakeplanned_for(YYYY-MM): only the clients whose planned supervisory visit falls in that month, by planned day, as the roster's month list shows them. Each row carriesplanned_day, the day capped to the month's last, null when no day is set. Any other form ofplanned_foris400.
Changed October 17, 2026 (US-102.34):
GET /api/v1/clients/{id}/other-services,POST /api/v1/clients/{id}/other-services,PATCH /api/v1/client-other-services/{id}andDELETE /api/v1/client-other-services/{id}, and the MCP toolslist_client_other_services,add_client_other_service,update_client_other_serviceanddelete_client_other_service: a client's other services, the outside providers serving it (kindadult_day, cna, rn, pt or other;company,phone,address,description;days, any of su mo tu we th fr sa, kept in week order; andtimes, an optional time per chosen day). Each write is audited against the credential, as the client page's are. No kind, an unknown day or a field past its length answers422naming the field. Over MCP the typed fields, each time among them, answer as{"untrusted_text": ...}.- A client carries
agency_services_only(the client has no outside providers, Access's MHS ONLY), onGET /api/v1/clients/{id}, the list and the MCP toolget_client.POST /api/v1/clients/{id}/agency-services-onlyand the MCP toolset_agency_services_onlyset it, withvalueand thelock_versionthe client was read with; a client changed since answers409 stale_record.PATCH /api/v1/clients/{id}does not take it. - The agency profile carries
work_order_print_certification: whether a printed Work Order carries the notice, certification and signature lines, true unless the agency turns it off (GET/PATCH /api/v1/agency, and the MCP toolsget_agency_profileandupdate_agency_profile, admins only on write).
Changed October 16, 2026 (US-102.35):
POST /api/v1/clients/{id}/supervisory-planand the MCP toolset_supervisory_plan: a client's planned supervisory visit slot, the month of each quarter (planned_supervisory_offset, 1 to 3) and the day of it (planned_supervisory_day, 1 to 31), as the client page sets them. Both null clears it, a day without a month is422 validation_failed, and alock_versionread before another write is409 stale_record. The client read (GET /api/v1/clients/{id},get_client) carries both fields; the client PATCH does not write them.POST /api/v1/work-orders/{id}/duplicateandduplicate_work_ordertake an optionalmode(keep_both,close_previous,temporary) witheffective_date,closing_date,temporary_from,temporary_to,client_id,caregiver_idandlock_version: a new standing Work Order with the next WO #, as the page's Duplicate makes it, answered as its first month withwarnings. An admin or office manager only (403 duplicate_not_permitted).close_previousneeds thelock_versionthe Work Order was read with (409 stale_recordwhen it changed since); a choice the page refuses, a missing Effective Date included, is422 duplicate_refusedin its words, a close of an archived Work Order422 work_order_archived. A field another mode takes, or these fields mixed withmonthandyear, is400. A body withoutmodecopies one month, as before.POST /api/v1/caregivers/{id}/w4-sent-to-payrolland the MCP toolmark_w4_sent_to_payroll: records that the payroll processor was sent a caregiver's W-4 change and clears it, as the Payroll Summary does. An optionalw4_changed_atclears only the change read at that time (409 stale_recordotherwise); a caregiver with none waiting is422 no_w4_change. The W-4 values are never returned.
Changed October 11, 2026:
POST /api/v1/settings/sandata/certification/cases/{case}and the MCP toolsend_sandata_certification_case: sends one Sandata certification test case, admin only and in the certification tenant only. The certification page read carriescases, each with itsid, round,applied(null in round 1), why it isblocked, andstate, how many of its records areaccepted,waiting,refused(they go again on a send),parked(refused too often to go again until they change),held_back(they cannot be sent as they are) andto_send.404 not_foundfor an unknown case,409 not_readywhile Sandata has not accepted what the case needs (the message names the cases to send first, and says which of them send a record refused too often),422 no_recordswith no sample records,409 nothing_to_sendwhen every record of it is accepted, waiting, parked or held back,500 case_incompletewhen its change failed and changed nothing.PATCH /api/v1/settings/sandata/certification/dry-runand the MCP toolset_sandata_dry_run: the certification tenant's dry-run switch. On, a test case writes the records it would send to the server log, keeps nothing and sends nothing, also while Sandata is paused. The certification page read carriesdry_run, which is on until someone turns it off.POST /api/v1/settings/sandata/certification/sendand the MCP toolsend_sandata_sample_recordssend the Employees and then the Clients test case, each on its own, and answerdry_runand each case's result besidequeued, which is false in a dry run. A case refused while the other went carriesrefused, thecodeandmessagethe case's own send would answer.POST /api/v1/settings/sandata/certification/send-visitsand the MCP toolsend_sandata_sample_visitssend the next visit test case whose visits Sandata does not hold yet, one per call, and answer itscasebesidequeued_visits;409 not_readyis now about that case's clients and employees alone.- The certification page creates 8 sample clients and 8 employees (it created 5 of each), still with 20 visits.
Changed October 10, 2026:
-
A caregiver carries
position: the job title the agency gives them, free text up to 200 characters (code points) (GET/PATCH /api/v1/caregivers/{id}, the list,POST /api/v1/caregivers, and the MCP toolsupdate_caregiverandcreate_caregiver). Null until set. Over MCP it answers as{"untrusted_text": ...}, as text someone typed. -
The MCP tools
update_caregiverandupdate_clientanswer a card's address and city (a client's second address line and ACP address too) as{"untrusted_text": ...}, and a date of birth that is not an ISO date the same way, asget_caregiverandget_clientalready did.update_clientanswers the language preference that way too. -
A client's or caregiver's date of birth that can no longer be read answers null, on
/api/v1and over MCP, rather than the texterror; a caregiver's SSN that can no longer be read answersssn_maskednull rather than failing the request. -
Over MCP, a date of birth an import stored as
MMDDYYYYorM/D/YYYYanswers as theYYYY-MM-DDdate it is, as the rest of the app reads it; other text still answers as{"untrusted_text": ...}. -
A PUT to a company-document upload slot that another PUT is still storing answers 409
upload_slot_in_progress; read it again shortly. A used slot's 409upload_slot_usedalways names the document, and a slot whose store died before saving one may be used again after ten minutes. -
A Work Order read (
GET /api/v1/work-orders/{id}, the list, and the MCP toolget_work_order) answersseen_by_date: each date of its month to an opaque value (US-95.99). Send a date's value asseentoPUT /api/v1/work-orders/{id}/days/{date}orset_work_order_day, and a date changed since that read is refused (409stale_record) with nothing written. The value is a hash; its format is not a contract. -
A file an MCP tool answers with a
download_url(one too large to carry inline: a note attachment, a company or person document, an export, an 837, a printed form) is fetched under/mcp/files/, with the AI connection's own token (US-95.98). Its/api/v1twin refused that token, which is valid for/mcponly, so such a URL could not be fetched at all. The/api/v1file routes are unchanged and still take an agency key. -
Every error status an operation's description names is now in its
responses, in the sharedErrorenvelope, with the codes the description gives (US-95.54). The resources' list, get, create and update operations declare 400bad_request, 404not_found, 409stale_recordand 422validation_failedwhere each applies. Nothing about the answers themselves changed; a client generated from the document now handles them. -
A save that lost a race with another write while the request ran answers 409
stale_recordon every operation, and an MCP tool says the record changed since it was read. Nothing is saved, so read it again and retry. Before, only the supervisory visit lifecycle answered this way; a calendar event's restore, a visit exception's resolve or assignment, and any other write whose record moved answered 422validation_failed. -
The null rule of October 8 (US-95.62) now runs on every write with a body (US-95.89), among them the timesheet, Work Order content, generation and lifecycle, assignment lifecycle, visit exception, settings list, payroll, claim, report template, PAR lifecycle and caregiver app writes. A null or a blank on a field the body's schema does not declare
nullableis 422null_not_allowednaming it, and a body of one value (a direction, a status, a reason) refuses its null or blank by name. A nullable field's null empties it on a change, and on an action means the same as leaving it out (a sign date is today, a status change has no reason). The MCP tool for each write takes the same body, the integration settings writes, a person document's upload and metadata update and a restore'slock_versionamong them (US-95.100): a null or blank Sandata Account or provider id is refused by name, a null or blank username, password, Account SID or Auth Token keeps the saved one, and a JSON upload declares its body beside the multipart one. -
A company document up to the page's limit through JSON (US-95.56):
POST /api/v1/company-documents/uploadschecks the document's details and answers a single-useupload_url, bound to the credential and the agency, andPUT /api/v1/company-documents/uploads/{token}takes the file's bytes as the body, with the same credential, and answers the stored document. The MCP toolupload_company_documentanswers such a slot, under/mcp, when it is called withoutfile_base64or with a file larger than it carries. -
A record id is a UUID's 36-character text form, in either case, wherever one is sent (US-95.69): a path id, a body field, a query filter. Sixteen arbitrary characters were read as a raw UUID at some operations; they now name no record, so a path id answers 404 and an id among the
/api/v1/visits/bulk-verifyand/api/v1/visit-exceptions/resolveids answers 422validation_failedat both. -
The rest of the Settings page is on the API (US-95.47), admin credentials only:
GET /api/v1/settings/securityandPUT /api/v1/settings/security(the two-factor requirement and the session timeout, saved together),POST /api/v1/users/{id}/two-factor/reset,GET /api/v1/settings/notifications,PATCH /api/v1/settings/notifications,GET /api/v1/settings/adp,PATCH /api/v1/settings/adp,GET /api/v1/settings/csv-mapping,PUT /api/v1/settings/csv-mapping,GET /api/v1/settings/tpid-authorized,PUT /api/v1/settings/tpid-authorized, andGET /api/v1/consents/{purpose},POST /api/v1/consents/{purpose}andDELETE /api/v1/consents/{purpose}forexternal_ai_clientsandapi_access.GET /api/v1/me/reminder-preferencesandPUT /api/v1/me/reminder-preferencesread and set the caller's own reminder preferences, for any member. Each change writes an audit row naming the key. -
Added
POST /api/v1/work-orders/{id}/verify-for-billingand the MCP toolverify_work_order_for_billing, the timesheet page's Verify hours (US-95.44): the hours a Work Order's days carry become its verified hours, and one in progress is completed, writing or finding its caregiver report. It takes thelock_versionthe Work Order was read with and answers the Work Order,timesheet(what happened to the report) andcompletion(completed_noworalready_complete). AddedPOST /api/v1/work-orders/{id}/timesheet/overwriteand the MCP tooloverwrite_timesheet, the Work Order page's Overwrite: a completed Work Order's report is written again from its days and tasks, answering 201 with the new report. A report with a claim on a live batch answers 409has_claims, itsdetailsgivingtotal,by_statusandtimesheet_ids, and nothing changes; one with entries typed from the card answers 409entries_typed.
Changed October 9, 2026:
- Every printed form the web has is readable over the API (US-95.40):
GET /api/v1/print/{form}answers the print page's own HTML, with its print layout, for the route's path and query parameters sent as query parameters by their names on the route, andformat=pdfanswers that page as a PDF;GET /api/v1/print/{form}/{id},{id}being the record id then.pdf, is the PDF of one record's form. The forms, and the ids each takes, are listed in the operation's description. A record of another agency answers 404. Each print writes the audit row the web print writes, naming the credential. The MCP toolget_print_documentanswers the PDF. - The agency profile update refuses a null or blank
nameasnull_not_allowed, naming it, before the save is tried (US-95.73); it was refused asvalidation_failedfrom the save. The service authorization, agency profile, certification, satisfaction survey, supervisory visit, monthly report and PAR check MCP tools now declare their parameters from these bodies, so a field the API lets you empty takes null over MCP too. - A supervisory visit or monthly report write now treats a field sent as a
change: null or blank
visit_date,supervisor_nameorcommentsempties it, and a field left out is kept (US-95.87). Null used to be dropped as if the field had not been sent. Text is trimmed on both surfaces, and thenothing_to_changeandinvalid_answersrefusals read the same over /api/v1 and MCP. - A request whose data store was busy or did not answer (a lost connection,
a lock or statement timeout, a deadlock) before it saved anything now
answers 503
temporarily_unavailablewithRetry-After, and frees its Idempotency-Key, so a retry under the same key runs again (US-95.94). It used to answer an unmarked 500 that a retry under the key replayed. A request that had already saved part of its work still answers 500. POST /api/v1/batches/from-timesheetsanswers 409stale_recordwhen the client, assignment, work order or service authorization a claim took its billing values from changed between the read and the export, as it already did for the timesheet itself (US-95.74). The batch it makes bills the claims it validated, from one pricing pass (US-95.68).- A write whose path names a record the agency does not have answers 404
not_foundwhatever its body holds (US-95.86). Some writes used to judge the body first and answer 400 or 422 for an id that named nothing. The order is now the same on every write with a path id: the id, then the body, then thelock_version(400 for a missing or malformed one, 409 for a stale one). The MCP write tools answer in the same order. - A plan of care's
authorization_idtakes null to unlink its PAR. An id that is not a PAR of the plan's own client, not deleted, now answers 422 namingauthorization_idon a create or update, over REST and MCP alike; it used to save the plan unlinked, or ignore the id on an update. The link a plan already carries is kept when sent back, even once its PAR is deleted (US-95.85).
Added October 9, 2026:
GET /api/v1/settings/sandata,PATCH /api/v1/settings/sandata,POST /api/v1/settings/sandata/test,GET /api/v1/settings/telephony,PATCH /api/v1/settings/telephony,DELETE /api/v1/settings/telephony,POST /api/v1/settings/telephony/testandGET /api/v1/settings/{tab}/secrets/{key}(US-95.46): the Sandata and Telephony settings tabs, admin only. A read says whether each credential is saved; the secrets operation returns one with the tab's audit row. A telephony PATCH that changes credentials tests them with Twilio first.GET /api/v1/settings/sandata/certification,PATCH /api/v1/settings/sandata/certification/steps/{key},POST /api/v1/settings/sandata/certification/sample-records,DELETE /api/v1/settings/sandata/certification/sample-records,POST /api/v1/settings/sandata/certification/validate,POST /api/v1/settings/sandata/certification/sendandPOST /api/v1/settings/sandata/certification/send-visits(US-95.46): the Sandata certification page, admin only; the sample records are created, sent and removed only in the certification tenant.POST /api/v1/claims/{id}/prepare-resubmissionandPOST /api/v1/batches/{id}/prepare-resubmissions(US-95.49): an admin releases a refused claim's timesheet, or a whole batch's, to be billed again, as the batch page's Release does.POST /api/v1/claims/{id}/evv-overrideandPOST /api/v1/claims/{id}/follow-up(US-95.49): override a claim's EVV warning with a reason, and open a denial follow-up.GET /api/v1/clients/{id}/documents,POST /api/v1/clients/{id}/documents,GET /api/v1/caregivers/{id}/documents,POST /api/v1/caregivers/{id}/documents,GET /api/v1/documents/{id},PATCH /api/v1/documents/{id},DELETE /api/v1/documents/{id}andGET /api/v1/documents/{id}/file(US-95.48): the documents on a client's or caregiver's file, as the Documents tab keeps them. A file downloads only once its virus scan is clean (404not_scanned_cleanbefore).GET /api/v1/meeting-minutes,POST /api/v1/meeting-minutes,GET /api/v1/meeting-minutes/{id},PATCH /api/v1/meeting-minutes/{id},DELETE /api/v1/meeting-minutes/{id}andPOST /api/v1/meeting-minutes/{id}/finalize(US-95.43): the Compliance meeting minutes pages, from draft to finalized. Finalized minutes refuse any change (422not_draft).GET /api/v1/oig-attestations,POST /api/v1/oig-attestationsandGET /api/v1/oig-attestations/{id}(US-95.43): the monthly OIG exclusion attestation; its report is named by a company document of the agency.GET /api/v1/denials(US-95.50): the claims the remittance did not pay, newest payment first, filtered bypayment_date_from/payment_date_toandmember, each CARC and RARC with its plain-Englishmeaning.POST /api/v1/query(US-95.41): the aggregate counts the AI assistant answers (a count, a per-status breakdown, a date-range count, or the records missing data). Stores nothing, so it takes no Idempotency-Key and a read-only account may ask it.POST /api/v1/timesheets/{id}/exportandPOST /api/v1/timesheet-entries/{id}/pull-evv(US-95.45): the returned timesheet bar's Export and the entries page's Pull EVV. A timesheet entry now also carriesevv_clock_in,evv_clock_outandvisit_id.
Added October 9, 2026 (US-95.42): what the client, caregiver and batch pages show of SSN, medical information and the 837 file.
- Clients and caregivers carry
ssn_masked(***-**-and the last four digits), and their POST and PATCH take a fullssn, which is never returned. Anssnin a body used to be ignored. GET /api/v1/clients/{id}/medicalandPATCH /api/v1/clients/{id}/medicalread and write the client page's Medical tab.GET /api/v1/batches/{id}/837downloads a batch's 837 file as Batch Detail does.
Changed October 8, 2026 (US-95.62): one null rule for the record writes, read
from the request body's schema. It runs on the POST and PATCH of assignments,
authorizations, caregivers and their trainings, evaluations and vaccinations,
clients, client certifications, satisfaction surveys, client and caregiver
notes, complaints, critical incidents, plans of care, prospects, service
rates, supervisory visits, support tickets, task set templates, visits and
work orders, and now also on PATCH /api/v1/agency,
POST /api/v1/satisfaction-surveys/{id}/complete and the monthly report save
(POST /api/v1/work-orders/{id}/monthly-report), which did not refuse a null
before. Every other write reads its body as it did.
On those writes a field left out is unchanged, and no value the server accepts is changed on the way in:
- A null or a blank (
""or whitespace) on a field the schema does NOT declarenullableis 422null_not_allowednaming the field. A null there was already refused; a blank used to reset the field to its default (status: ""on a client,visit_type: ""on a visit) or was refused with another code (validation_failedfor a blankfirst_nameor claim default,field_requiredfor a blank support ticketsubject). - These fields are now declared not nullable, since the record requires them:
a service rate's
procedure_code,rate_per_unitandeffective_date; an assignment'sbilling_codeandeffective_date; a plan of care'seffective_date; a prospect'sfirst_name,last_nameandphone; a task set template'sname; a note'snote_dateandnote_text; a training'scompleted. A null on one wasvalidation_failed, and on a plan'seffective_datea 200 that changed nothing; it is nownull_not_allowed. - A null or a blank on a field the schema declares
nullablereaches the write as before. On a PATCH it empties the field, or, on a field the record still requires (an authorization'sauthorized_units, a complaint'scomplaint_date), is 422 naming it. Three writes do otherwise, and keep doing so: a supervisory visit write and a monthly report save keep the field on a null (a blank empties it), and a completed training'sexpiry_dateis set to a year after its completion. - A list holding a null element is refused naming the list, where it could
store the null (a plan's
tasksholding a null was a 400 and is now this 422).
MCP's create and update tools for visits, assignments, Work Orders, plans of
care, service rates, prospects and task set templates take the same schemas
and answer the same calls alike. MCP's other write tools still refuse a null
on a property they do not declare nullable, even where this API takes it.
Changed October 8, 2026 (US-95.79): a failure that is not the caller's is
answered by what a retry can achieve, the same on every operation that stores
or reads a file (the ten that document it). A file store that did not answer,
or an upload whose temporary file could not be read for a reason that clears
by itself, is 503 (storage_unavailable for the file store,
temporarily_unavailable for the upload) with Retry-After: 30. A file store
that refused the request, a virus scan that could not be queued or an upload
that could not be read for any other reason is 500 internal_error. A record
whose file is gone is 410 file_missing, its message saying to generate or
upload the file again; only the five operations that read a stored file
document or answer it. The answers that changed:
GET /api/v1/payroll-exports/{id}/file:file_missingwhere it saidno_file.GET /api/v1/company-documents/{id}/file: 410 or 500 where it said 503retrieve_failed.GET /api/v1/note-attachments/{id}: 503, 500 or 410 where it said 404.GET /api/v1/exports/{id}/file: 503 or 500 where an unreadable file said 410, and 409export_failed, its message the export's own reason, where a failed export said 409not_ready.POST /api/v1/provider-care-plans/{id}/reconciliation/preview: 503, 500 or 410 where a PCSP the store could not read said 422unreadable_document.POST /api/v1/company-documentsandPOST /api/v1/clients/{id}/pcsp-documents: 503 or 500 where a store, scan-queue or upload failure said 422validation_failed.POST /api/v1/client-notes/{id}/attachmentsandPOST /api/v1/caregiver-notes/{id}/attachments: 503 or 500 where a virus scan that could not be queued, or an upload that could not be read, said 422not_savedorfile_required, and 500internal_errorwhere a refused audit record said 422not_saved.POST /api/v1/payroll-exports/{id}/generate: 503 or 500 where a store failure said a 500 that kept the Idempotency-Key, and 500internal_errorthat frees it where a refused audit record failed the request. A refused generation leaves the export and its earlier file as they were.GET /api/v1/exports/{id}: an export whose file the store did not answer for staysprocessing, itserror_messagesaying it is retried automatically, until the last attempt marks itfailed, saying to start a new export; one whose file the store refused isfailedat once, where both used to readfailedbetween attempts. A completed export'serror_messageis null.
A store answer is transient when it is an HTTP 408, 429, 500, 502, 503 or 504,
S3's 400 RequestTimeout, or a transport or protocol error, and permanent
otherwise (a 501 or 505 included). None of these changed anything. An answer
that persisted nothing now leaves the Idempotency-Key free whatever its status
(these, and a 500 for an audit record that could not be written), so a retry
under the same key runs again instead of replaying the failure; a retry while
the first request still runs is 409 idempotency_in_progress, as before. A
slow file store answers within about 67 seconds. MCP tools say the same
sentence.
Changed October 8, 2026 (US-95.82): request body limits are stated in the
pages' MB, 2^20 bytes, and KB, 2^10 bytes, so each rises slightly: any body
takes 1 MB (1,048,576 bytes, was 1,000,000), a JSON-RPC body to /mcp
3,248,128 bytes (was 3,100,000), the CFC calculator tools a file of 1 MB (was
1,000,000 bytes), validate_claims_csv a sheet of 1 MB (1,048,576 bytes, was
1,000,000), and a signature image (POST /api/v1/work-orders/{id}/signatures,
sign_work_order, the caregiver app's signatures) 50 KB (51,200 bytes, was
50,000). A voice recording to the in-app assistant takes the upload routes' 10
MB (10,485,760 bytes, was 8,000,000).
A file sent base64 to an MCP tool fits the /mcp body up to 1.7 MB (1,887,435
bytes; the CFC calculator tools take 1 MB), and every tool that takes one says
so, refuses a larger file, and names the REST route that takes it:
create_batch and store_pcsp, which said 10 MB, refuse naming
POST /api/v1/batches or POST /api/v1/clients/{id}/pcsp-documents, and
add_client_note_attachment, add_caregiver_note_attachment and
upload_company_document refuse naming their multipart routes.
validate_claims_csv and POST /api/v1/clients/{id}/pcsp-documents state
their limits, and POST /api/v1/company-documents states that a JSON body
takes at most 1 MB. Every 413 for a body too large names the limit that
refused it, by the route and the body's content type: a multipart body on a
route that takes files names the file it may carry (a CFC calculator's, 5 MB),
any other body the most its parser reads (1 MB, and 3 MB for JSON to /mcp,
whose 413 points to the tool's description for where a larger file goes).
Added October 7, 2026 (US-95.30): the files on notes.
GET /api/v1/client-notes/{id}/attachments and
GET /api/v1/caregiver-notes/{id}/attachments list a note's attachments with
their virus-scan status; POST /api/v1/client-notes/{id}/attachments and
POST /api/v1/caregiver-notes/{id}/attachments attach a file (multipart field
file, up to 10 MB; a file breaking the note page's rules is 422 naming the
rule); GET /api/v1/note-attachments/{id} downloads one once its scan is clean
(404 before); DELETE /api/v1/note-attachments/{id} removes one, for its
uploader or an agency admin (404 for anyone else). MCP gains the matching
tools, one per kind of note.
Added October 7, 2026 (US-95.32): OIG checks, PINs and the bulk compliance
updates. GET /api/v1/caregivers/{id}/oig-checks and
POST /api/v1/caregivers/{id}/oig-checks list and record a caregiver's OIG
exclusion checks, and POST /api/v1/oig-checks/bulk records a clear check for
every active caregiver (admin credentials only). POST /api/v1/caregivers/{id}/telephony-pin
and POST /api/v1/telephony-pins/bulk generate telephony PINs,
PUT /api/v1/caregivers/{id}/app-pin sets and DELETE /api/v1/caregivers/{id}/app-pin
resets an app PIN; none of them returns a PIN (PRD 5.8).
POST /api/v1/trainings/bulk-annual-completion (admin credentials only) and
POST /api/v1/vaccinations/bulk make the compliance dashboard's bulk updates.
MCP gains the matching tools.
Added October 7, 2026 (US-95.32): a caregiver's compliance record, pay rates
and Employee File checklist. GET /api/v1/caregivers/{id}/compliance-items,
POST /api/v1/caregivers/{id}/compliance-items (one per caregiver: 422
already_recorded naming it) and PATCH /api/v1/caregivers/{id}/compliance-items
(409 stale_record) keep the compliance record and its custom items.
GET /api/v1/caregivers/{id}/pay-rates and POST /api/v1/caregivers/{id}/pay-rates
list and add pay rates, a new one ending the current rate of its type.
GET /api/v1/caregivers/{id}/file-checklist,
PATCH /api/v1/caregivers/{id}/file-checklist (several items, all or none; 422
hidden_item or unknown_item) and
POST /api/v1/caregivers/{id}/file-checklist/review read, set and review the
Employee File checklist. MCP gains the matching tools.
Added October 7, 2026 (US-95.36): the agency's own records.
GET /api/v1/company-documents, GET /api/v1/company-documents/{id},
POST /api/v1/company-documents (multipart file, or file_base64 with
file_name), PATCH /api/v1/company-documents/{id} and
DELETE /api/v1/company-documents/{id} (each with the lock_version read: 400
without it, 409 stale_record when it changed since; 422 retained for an OIG
attestation's report) and GET /api/v1/company-documents/{id}/file (once
scanned clean; 409 scan_pending, 410 scan_infected). POST /api/v1/exports
starts a report page's CSV export, GET /api/v1/exports/{id} reads its status
and GET /api/v1/exports/{id}/file its file. GET /api/v1/import-configurations,
GET /api/v1/import-configurations/{id}, POST /api/v1/import-configurations,
PATCH /api/v1/import-configurations/{id} and
DELETE /api/v1/import-configurations/{id} (each with the lock_version
read: 400 without it, 409 stale_record when it changed since). GET /api/v1/saved-reports,
POST /api/v1/saved-reports, PATCH /api/v1/saved-reports/{id} and
DELETE /api/v1/saved-reports/{id}, by kind (client or caregiver); a saved
report's filters are accepted and never returned. Eighteen MCP tools do the same.
Added October 7, 2026 (US-95.35): payroll writes.
DELETE /api/v1/service-rates/{id}, POST /api/v1/service-rates/{id}/transition
(close a rate and open its successor from effective_date) and
POST /api/v1/service-rates/import (a CSV as csv or csv_base64, with
preview to check it and write nothing) manage the agency's own rates, and
PUT /api/v1/service-rates/schedule-source sets use_system_fee_schedule.
POST /api/v1/cash-advances, POST /api/v1/cash-advances/{id}/repayments and
POST /api/v1/cash-advances/{id}/write-off are Cash advances.
POST /api/v1/payroll-exports starts an export for a pay period,
POST /api/v1/payroll-exports/{id}/generate builds its ADP file (format
adp or adp_run, with warnings), GET /api/v1/payroll-exports/{id}/file returns the
CSV, and POST /api/v1/payroll-exports/{id}/mark-exported marks it sent.
MCP's delete_service_rate, transition_service_rate,
import_service_rates, set_fee_schedule_source, create_cash_advance,
record_cash_advance_repayment, write_off_cash_advance,
create_payroll_export, generate_payroll_csv, get_payroll_export_file and
mark_payroll_export_exported do the same.
Added October 7, 2026 (US-95.33): provider care plans.
GET /api/v1/provider-care-plans (client_id), POST /api/v1/provider-care-plans,
GET /api/v1/provider-care-plans/{id} and PATCH /api/v1/provider-care-plans/{id}
save and read a plan and its revisions, the certification period decided as the
form decides it (422 certification_disagreement naming both periods unless
certification_choice is sent). POST /api/v1/provider-care-plans/{id}/mark-current,
POST /api/v1/provider-care-plans/{id}/reconciliation and
POST /api/v1/clients/{id}/pcsp-documents (multipart file) mark a plan current,
record a reconciliation and store a PCSP.
POST /api/v1/provider-care-plans/{id}/reconciliation/preview proposes a PCSP's
authorisations and answers a single-use token good for an hour, and
POST /api/v1/provider-care-plans/{id}/reconciliation/apply applies exactly
that preview with the caller's decisions (409 already_applied, expired).
MCP gains the matching tools.
Added October 7, 2026 (US-95.31): the client page's actions.
POST /api/v1/clients/{id}/calendar-events adds a custom event to a client's
calendar and POST /api/v1/calendar-events/{id}/restore undoes a change to one
(upcoming or overdue only). POST /api/v1/clients/{id}/next-action-snoozes and
DELETE /api/v1/clients/{id}/next-action-snoozes snooze and bring back a Next
Actions suggestion for the caller. GET /api/v1/clients/{id}/health-summary,
POST /api/v1/clients/{id}/health-summary (422 no_conditions, 503
ai_unavailable), PATCH /api/v1/clients/{id}/health-summary (409
stale_record) and DELETE /api/v1/clients/{id}/health-summary read, write,
edit and delete the AI health summary. GET /api/v1/clients/{id}/par-check and
PATCH /api/v1/clients/{id}/par-check read and save the PAR unit check, all
services or none (422 not_on_par for a service the PAR has no plan for). MCP
gains the matching tools.
Added October 7, 2026 (US-95.31): client records.
GET /api/v1/clients/{id}/certifications, POST /api/v1/clients/{id}/certifications,
PATCH /api/v1/client-certifications/{id} and
DELETE /api/v1/client-certifications/{id} keep a client's certification
periods (an overlap answers 422). GET /api/v1/clients/{id}/satisfaction-surveys,
POST /api/v1/clients/{id}/satisfaction-surveys,
PATCH /api/v1/satisfaction-surveys/{id} (409 stale_record) and
POST /api/v1/satisfaction-surveys/{id}/complete (every required question
answered) keep its surveys. GET /api/v1/clients/{id}/emergency-info,
POST /api/v1/clients/{id}/emergency-info and DELETE /api/v1/emergency-info/{id}
keep its emergency information revisions, and
PATCH /api/v1/clients/{id}/information-sheet writes the information sheet's
fields (a blank SSN keeps it; the SSN is never returned). MCP gains the
matching tools.
Added October 7, 2026 (US-95.33): a supervisory visit's lifecycle.
POST /api/v1/supervisory-visits/{id}/complete completes it and schedules the
next one (admin credentials only, 403 forbidden otherwise),
POST /api/v1/supervisory-visits/{id}/reopen clears its signatures for
correction (422 already_draft), POST /api/v1/supervisory-visits/{id}/date
sets or clears its date, and POST /api/v1/supervisory-visits/{id}/signatures
signs one line (supervisor, client, caregiver or pcp; 422 already_signed).
A visit another request changed while one of these ran answers 409
stale_record (send it again), and a later completion step that failed (the
next visit, the completing user's reminder cadence) 500 internal_error,
nothing saved. MCP's complete_supervisory_visit, reopen_supervisory_visit,
set_supervisory_visit_date and sign_supervisory_visit call the same
functions.
Changed October 7, 2026 (US-95.52): an agency whose account is read-only may
now make, over /api/v1, every write its MCP twin allows at that level (notes,
incidents, complaints, trainings, support tickets, reminders and the like),
as MCP and the web already let it; the level an operation allows is read from
the MCP tool naming it. Batch writes and every write whose twin excludes the
read-only level are still refused with 403 read_only, and a credential
without hcb.write with 403 insufficient_scope.
Added October 7, 2026 (US-95.51): POST /api/v1/batches/from-timesheets bills
the approved timesheets among timesheet_ids as one batch, as Billing >
Generate batch does (201 with the batch, left_out naming every timesheet not
in it and why, and warnings; 422 critical_issues when the selection breaks
a rule that blocks a batch, 422 nothing_billable, 409
timesheets_already_exported or stale_record). MCP's
create_batch_from_timesheets does the same.
Added October 7, 2026 (US-95.38): the Settings list tabs, admin credentials
only (403 forbidden otherwise). Checklists: GET /api/v1/checklists/{checklist}/items,
POST /api/v1/checklists/{checklist}/items, PATCH /api/v1/checklist-items/{id},
POST /api/v1/checklist-items/{id}/deactivate (422 last_active),
POST /api/v1/checklist-items/{id}/reactivate and
POST /api/v1/checklist-items/{id}/move. CFC programs:
GET /api/v1/cfc-programs, PATCH /api/v1/cfc-programs/{category} (422
last_active_category), POST /api/v1/cfc-programs/{category}/tasks,
PATCH /api/v1/cfc-tasks/{id}, POST /api/v1/cfc-tasks/{id}/deactivate (422
last_active_task), POST /api/v1/cfc-tasks/{id}/reactivate and
POST /api/v1/cfc-tasks/{id}/move. Report templates:
GET /api/v1/report-templates/{report_type},
POST /api/v1/report-templates/{report_type}/questions,
PATCH /api/v1/report-questions/{id},
POST /api/v1/report-questions/{id}/deactivate,
POST /api/v1/report-questions/{id}/reactivate,
POST /api/v1/report-questions/{id}/move,
POST /api/v1/report-questions/{id}/flag (sets a flag to the value sent),
POST /api/v1/report-templates/{report_type}/apply-preset (422
unknown_preset) and PATCH /api/v1/report-templates/{report_type}/form; a
change the page confirms first answers 409 confirmation_required unless
confirm is true. A question's add and edit bodies are typed: options is an
array of codes, option_labels an object of captions keyed by code (a code
it names must be in the options, or be one the same write removes, whose
caption goes with it), multiline a boolean and
print_region top_list or table, which the supervisory sheet's own band
questions do not take. A setting a question does not take is refused by name
(422), and a null inside options or option_labels is refused. EVV rules: GET /api/v1/evv-rules,
PATCH /api/v1/evv-rules/{id}, POST /api/v1/evv-rules/{id}/toggle and
POST /api/v1/evv-rules/reset. Every audit row written during an /api/v1 or
MCP request now names the API key or AI connection. MCP gains the matching
tools.
Added October 7, 2026 (US-95.37): agency administration, admin credentials
only (403 forbidden otherwise) except connected apps. GET /api/v1/users,
PATCH /api/v1/users/{id} (name, role; 422 cannot_change_own_role,
last_admin), DELETE /api/v1/users/{id} (deactivates and revokes the
member's keys, connections and webhook endpoints; 422 cannot_deactivate_self)
and POST /api/v1/users/{id}/reactivate. GET /api/v1/invitations,
POST /api/v1/invitations (201; 422 already_member, pending_invitation)
and DELETE /api/v1/invitations/{id} (422 not_pending).
GET /api/v1/api-keys and GET /api/v1/webhook-endpoints list without
secrets; GET /api/v1/webhook-endpoints/{id}/deliveries reads the delivery
log and POST /api/v1/webhook-deliveries/{id}/resend sends one again (409
in_flight). POST /api/v1/api-keys, DELETE /api/v1/api-keys/{id},
POST /api/v1/webhook-endpoints, PATCH /api/v1/webhook-endpoints/{id} and
DELETE /api/v1/webhook-endpoints/{id} answer 403 web_only: a credential is
created or changed by an admin signed in to Settings.
GET /api/v1/connected-apps and DELETE /api/v1/connected-apps/{id} list and
revoke AI app connections as Connected apps does: an admin credential the
agency's, a staff one its own member's. Another agency's record is 404. MCP's
find_users, update_user, deactivate_user, reactivate_user,
find_invitations, invite_user, revoke_invitation, find_api_keys,
create_api_key, revoke_api_key, find_webhook_endpoints,
create_webhook_endpoint, update_webhook_endpoint,
delete_webhook_endpoint, find_webhook_deliveries,
resend_webhook_delivery, find_connected_apps and revoke_connected_app
call the same functions.
Added October 7, 2026 (US-95.39): the pipeline, caregiver broadcasts and
notifications, open to every credential. GET /api/v1/prospects,
POST /api/v1/prospects, GET /api/v1/prospects/{id},
PATCH /api/v1/prospects/{id} (409 stale_record) and
DELETE /api/v1/prospects/{id} (422 cannot_delete_converted) keep the
pipeline, and POST /api/v1/prospects/{id}/convert makes the client or
caregiver (422 invalid_status_for_conversion unless at onboarding).
POST /api/v1/broadcasts sends a message to active caregivers by email, SMS or
both, to all or a compliance group, skipping and counting those without the
contact method or opted out of SMS (422 no_recipients, 409 duplicate, 429
rate_limited). GET /api/v1/notifications lists the credential's member's
notifications (read=read|unread); POST /api/v1/notifications/{id}/read,
POST /api/v1/notifications/read-all and
POST /api/v1/notifications/{id}/resolve act on them. Another agency's
record, or another member's notification, is 404. MCP's find_prospects,
get_prospect, create_prospect, update_prospect, delete_prospect,
convert_prospect, send_broadcast, list_notifications,
mark_notification_read, mark_all_notifications_read and
resolve_notification call the same functions.
Added October 7, 2026 (US-95.34): batch and claim writes.
POST /api/v1/batches now takes column_mapping and save_mapping (keep the
mapping the file was read with as the agency's saved one).
DELETE /api/v1/batches/{id} deletes a batch not yet sent (422
already_submitted, submission_in_progress, not_eligible), returning its
timesheets to approved. PATCH /api/v1/claims/{id} corrects an uploaded claim
and POST /api/v1/claims/{id}/replacement creates a replacement claim in its
own batch, each with a reason and for admin credentials only (403
forbidden). POST /api/v1/claims/{id}/reconcile,
POST /api/v1/claims/{id}/unreconcile and
POST /api/v1/checks/{number}/reconcile are the payment report's
reconciliation, and PATCH /api/v1/claims/{id}/investigation sets a denial's
investigation_status and resolution_notes. A Claim now carries
reconciled_at, investigation_status and resolution_notes. MCP's
create_batch, delete_batch, update_claim, create_replacement_claim,
reconcile_claim, unreconcile_claim, reconcile_check and
update_claim_investigation do the same.
Added October 7, 2026 (US-95.28): timesheet writes.
POST /api/v1/assignments/{id}/timesheets creates a month's timesheet from an
assignment (201; 409 work_order_timesheet_exists, 422
period_outside_assignment). POST /api/v1/timesheets/{id}/entries,
PATCH /api/v1/timesheet-entries/{id}, POST /api/v1/timesheets/{id}/tasks
and PATCH /api/v1/timesheet-tasks/{id} edit a draft's entries and tasks (422
not_editable once it is not a draft). POST /api/v1/timesheets/{id}/submit
(422 signatures_required unless acknowledge_missing_signatures),
POST /api/v1/timesheets/{id}/approve (with warnings for stored hours that
differ from the entries), POST /api/v1/timesheets/{id}/reject (a reason),
POST /api/v1/timesheets/{id}/reopen (422 no_release unless a denied claim
sent it back) and POST /api/v1/timesheets/{id}/signatures run the returned
timesheet's workflow. DELETE /api/v1/timesheets/{id} deletes a draft (422
not_draft otherwise), and GET /api/v1/timesheets/{id}/billing-data returns
the claim lines an approved timesheet bills, writing nothing (422
billing_refusal). A timesheet changed since it was read is 409
stale_record. MCP's create_timesheet, add_timesheet_entry,
update_timesheet_entry, add_timesheet_task, update_timesheet_task,
submit_timesheet, approve_timesheet, reject_timesheet,
reopen_timesheet, sign_timesheet, delete_timesheet and
generate_billing_data do the same.
Added October 7, 2026 (US-95.29): DELETE /api/v1/clients/{id} and
DELETE /api/v1/caregivers/{id} (the lock_version read, in the query)
soft-delete as the web's lists do; POST /api/v1/clients/{id}/restore and
POST /api/v1/caregivers/{id}/restore (the lock_version read, in the body)
restore them; a DELETE's answer carries the lock_version the record was left at,
the one its restore takes, and a second restore of the same read is 409
stale_record. A deleted client or caregiver leaves the default list and is
listed with include_deleted=true. A restored caregiver's response carries
meta.pin_resolution and, when a new telephony PIN was issued, meta.new_pin,
in that response only. DELETE /api/v1/client-notes/{id} and
DELETE /api/v1/caregiver-notes/{id} soft-delete a note and its attachments.
DELETE /api/v1/supervisory-visits/{id} deletes a draft for any key and a
finalized visit for an admin key only (422 not_draft otherwise), and
DELETE /api/v1/satisfaction-surveys/{id} deletes a survey, answering its id
and deleted_at. DELETE /api/v1/trainings/{id} and
DELETE /api/v1/evaluations/{id} delete a caregiver's training record or
evaluation, as the caregiver's tabs do. Refusals are 422 already_deleted, not_deleted,
has_active_references and has_active_assignments. MCP gains the matching
delete and restore tools.
Added October 7, 2026 (US-94.24): POST /api/v1/visits/bulk-verify and
POST /api/v1/visits/bulk-cancel move up to 100 of the agency's visits, each on
its own, as the visit list's bulk actions do; the answer lists succeeded_ids
and each visit failed with its reason (not_found, invalid_transition,
exception_not_dismissed, error). POST /api/v1/visit-exceptions/{id}/assignment
assigns an exception to a user of the agency, or unassigns it with
assigned_to_id null (422 assignee_not_found for anyone else). A visit
exception gains assigned_to_id. MCP gains create_visit,
bulk_verify_visits, bulk_cancel_visits, bulk_resolve_visit_exceptions and
assign_visit_exception on the same operations.
Added October 6, 2026 (US-95.26): a Work Order's content.
GET /api/v1/work-orders/{id}/plan reads the weekly plan in force today (each
weekday's visits, each task line with its minutes and per-weekday counts, and
its lock_version), and PATCH /api/v1/work-orders/{id}/plan writes weekdays,
lines and drop_lines into it as the Work Order page saves its grid (409
stale_record for a plan changed since, unless it already holds what is sent;
422 unknown_task_definition). PUT /api/v1/work-orders/{id}/days/{date} marks
a date worked or not (422 recorded_work without confirm, 422 frozen).
PUT /api/v1/work-orders/{id}/tasks/{task_definition_id}/days/{date} marks a
task done, not done or untouched, and
POST /api/v1/work-orders/{id}/unplanned-tasks records a task the plan did not
hold. PATCH /api/v1/provider-type-templates/{id}/certification saves a
provider type's certification with the certification_version read (admin
only; 409 stale_record; 422 not_agency_template).
GET /api/v1/provider-type-modifiers now also returns each provider type's
id, agency_owned and certification. MCP's get_work_order_plan,
update_work_order_plan, set_work_order_day, toggle_work_order_task,
add_unplanned_task and update_provider_type_certification do the same.
Added October 6, 2026 (US-95.14): supervisory visits and monthly client
reports. GET /api/v1/supervisory-visits lists the agency's visits (filtered by
status, client_id, caregiver_id and visit_date_from / visit_date_to)
and GET /api/v1/supervisory-visits/{id} returns one, each with its checklist
questions and answers and never a signature or print-form field;
POST /api/v1/supervisory-visits records a draft conducted by the API key's
user (a telehealth visit needs an agency admin and the agency's
acknowledgment, else 422 visit_type_not_allowed);
PATCH /api/v1/supervisory-visits/{id} edits a draft with its lock_version
(422 not_editable for a completed or signed visit, or a draft already
carrying a signature); GET /api/v1/supervisory-visits/due lists the clients
a visit is due for. GET /api/v1/monthly-client-reports lists a client's
reports (client_id required) and POST /api/v1/work-orders/{id}/monthly-report
saves the one report a Work Order month holds: 201 when it creates it, 200 when
it updates it, 422 client_signed once the client has signed. Another agency's
visit, client or Work Order is 404.
Added October 6, 2026 (US-95.17): compliance reads and the OIG roster screen,
each returning what its MCP tool returns. GET /api/v1/caregivers/{id}/compliance
returns a caregiver's training, vaccinations, evaluation and credential dates;
GET /api/v1/clients/{id}/file-completeness and
GET /api/v1/caregivers/{id}/file-completeness return a person's file items;
GET /api/v1/audit-readiness returns the summary's counts and a page of the
people with a gap; GET /api/v1/compliance-alerts lists the active caregivers
with one kind of problem (alert_type required, 400 otherwise);
GET /api/v1/oig-screens lists the agency's OIG screens with their still-open
review counts (include_single adds new-hire and single-caregiver screens);
POST /api/v1/oig-screens queues a roster screen and answers 202 with
status queued or already_queued (422 demo_agency for a demo agency);
GET /api/v1/oig-screening-status lists each caregiver's latest OIG check.
Another agency's client or caregiver is 404.
Added October 6, 2026 (US-95.18): support tickets, today's agenda and its
reminders. POST /api/v1/support-tickets opens a support ticket (subject,
description of at least 20 characters, category and priority, all required);
a screenshot or any other field in the body is ignored, never stored. A
missing, over-long or unknown value is 422 naming the field
(field_required, field_not_text, field_too_long, invalid_choice,
description_too_short), and past the in-app assistant's shared ceiling the
answer is 429 support_ticket_limit. GET /api/v1/support-tickets lists, in
the page envelope and newest first, the tickets the API key's user raised,
filtered by status and priority, and GET /api/v1/support-tickets/{id}
returns one of them, each with its reference, status, priority, category,
SLA status and resolution notes, never its description; a ticket another
member raised, or another agency's, is 404. GET /api/v1/agenda/today
returns the reminders due today and those overdue (each capped, with total,
truncated, limit and its own offset, due_today_offset and
overdue_offset), today's client birthdays and the billing work waiting, for
Mountain time's day unless date names another.
POST /api/v1/reminders/{id}/complete and
POST /api/v1/reminders/{id}/dismiss close one reminder as the Today page's
Done and Dismiss buttons do (completing a recurring one schedules its next,
dismissing ends the series); one already closed as asked answers 200 with
changed: false, one closed the other way is 422 already_closed, and
another agency's reminder is 404 and nothing changes. MCP's
create_support_ticket, list_support_tickets, check_ticket_status,
whats_due_today and complete_reminder do the same.
Added October 6, 2026 (US-95.20): POST /api/v1/service-rates creates one of
the agency's own service rates (procedure_code, modifiers, rate_per_unit,
effective_date, description), and PATCH /api/v1/service-rates/{id} changes
its rate_per_unit, effective_date or description. A service rate carries no
lock_version, so a PATCH takes none. A platform-wide rate is never written: its
id answers 404. A duplicate code, modifiers and effective date, or a
rate_per_unit not greater than 0, answers 422 naming the field. MCP's
create_service_rate and update_service_rate do the same.
Added October 6, 2026 (US-95.16): a caregiver's training, vaccinations and
evaluations. GET /api/v1/caregivers/{id}/trainings,
GET /api/v1/caregivers/{id}/vaccinations and
GET /api/v1/caregivers/{id}/evaluations list the caregiver's records in the
shape MCP's caregiver-record tools return (notes are written, never returned).
POST /api/v1/caregivers/{id}/trainings and
POST /api/v1/caregivers/{id}/evaluations record one (422 already_recorded
with the existing record's id in details.training_id or
details.evaluation_id), and PATCH /api/v1/trainings/{id} and
PATCH /api/v1/evaluations/{id} change one (422 nothing_to_change for an
empty body; these records carry no lock_version).
POST /api/v1/caregivers/{id}/vaccinations records the vaccination for a year
and type, 201 when none was recorded (422 status_required without a status)
and 200 when it updates the one recorded; a vaccination has no PATCH. Another
agency's caregiver or record is 404 and nothing is written.
Added October 6, 2026 (US-95.15): critical incidents and complaints.
GET /api/v1/critical-incidents lists the agency's incidents (filtered by
status, incident_type, client_id and date_from / date_to) and
GET /api/v1/critical-incidents/{id} returns one, its reports,
notifications and referrals in the nested shape MCP's incident tools use;
POST /api/v1/critical-incidents reports a draft (reported by the API key's
user) and PATCH /api/v1/critical-incidents/{id} changes the fields sent with
its lock_version, reports and notifications merged over the stored legs
(422 invalid_field for a malformed leg). GET /api/v1/complaints lists the
agency's complaints (filtered by status, client_id, caregiver_id and
date_from / date_to), GET /api/v1/complaints/{id} returns one with its
answers by question key, POST /api/v1/complaints logs one at intake (422
unknown_answer_keys or invalid_answers for answers its questions cannot
take) and PATCH /api/v1/complaints/{id} changes it with its lock_version.
On either resource a status move the record's transitions refuse is 422
invalid_transition, an empty change is 422 nothing_to_change, and another
agency's record, client or caregiver is 404. Neither resource has a delete.
Added October 6, 2026 (US-95.13): the communication log.
GET /api/v1/clients/{id}/notes and GET /api/v1/caregivers/{id}/notes list a
client's or caregiver's notes in the page envelope, newest first, filtered by
contact_type and synced with updated_since;
POST /api/v1/clients/{id}/notes and POST /api/v1/caregivers/{id}/notes
file a note (manager_initials defaults to the API key's user's initials);
PATCH /api/v1/client-notes/{id} and PATCH /api/v1/caregiver-notes/{id}
change the fields sent (a body that changes nothing is 422
nothing_to_change; notes carry no lock_version). A person of another
agency, or a deleted one, is 404. Attachments are neither returned nor
accepted; attachment_count says how many there are. Over-long initials or
employee names are 422 (initials_too_long, employee_names_too_long,
employee_name_too_long), never cut.
Added October 6, 2026 (US-95.27): Work Order generation and the templates
behind it. POST /api/v1/assignments/{id}/work-orders/generate lays out a
month's Work Order from the client's Plan of Care (201 with the Work Order and
warnings; 409 work_order_exists unless overwrite is true; 422
no_schedule). POST /api/v1/plans-of-care/{id}/work-orders/distribute
splits a plan across caregivers with per-caregiver frequencies (201 with the
Work Orders and coded warnings; 409 plan_changed for a plan task id the
plan no longer carries). POST /api/v1/plans-of-care/{id}/resolve-over-authorization
trims the month's Work Orders back to the authorization (200 with each change;
422 residual_over_authorization when a chosen target cannot absorb it).
POST /api/v1/work-orders/{id}/timesheet writes a completed Work Order's
caregiver report (201; 422 work_order_not_ready or hours_not_verified; 409
timesheet_exists). GET /api/v1/task-set-templates,
POST /api/v1/task-set-templates, GET /api/v1/task-set-templates/{id},
PATCH /api/v1/task-set-templates/{id} (with lock_version) and
DELETE /api/v1/task-set-templates/{id} list, get, create, change and delete
task set templates, and GET /api/v1/provider-type-modifiers and
PUT /api/v1/provider-type-modifiers/{code} read and set a provider type's
modifiers against the set read (expected_modifiers; 409 stale_modifiers).
Template and modifier writes are an admin's (403 forbidden). MCP's
generate_work_orders, distribute_plan_work_orders,
resolve_over_authorization, generate_timesheet, find_task_set_templates,
get_task_set_template, create_task_set_template,
update_task_set_template, delete_task_set_template,
find_provider_type_modifiers and set_provider_type_modifiers do the same.
Added October 6, 2026 (US-95.22): a client's CFC calculator, as a job.
POST /api/v1/clients/{id}/cfc-calculator starts an import of a CFC Direct
Care Services Calculator (.xlsx, .pdf, .png, .jpg or .jpeg, multipart field
file, at most 5 MB, optional task_names) into the client's Plans of Care,
one per service on the sheet;
POST /api/v1/clients/{id}/cfc-calculator/preview starts a preview of the
per-day minutes an import would write. Each answers 202 with the job at once,
since reading a scan can take minutes; GET /api/v1/cfc-imports/{id} reads it
until it has ended, succeeded with its rows or plans and warnings, or failed
with its error (unreadable_calculator, import_refused,
extraction_unavailable once the extraction service has not answered through
every retry). A file over 5 MB answers 422 file_too_large, and a body over the
upload cap 413, both naming max_file_size; any task_names but a list of
names 422 invalid_task_names.
Added October 5, 2026 (#2216): a visit exception's sandata_ack_status gains
sending, an acknowledgement claimed for a send that has not been answered
yet. It is not withdrawable, as submitted is not; a send that never
finished is retried after 15 minutes.
Added October 5, 2026 (US-98.29): DELETE /api/v1/visits/{id}/sandata-exceptions
withdraws a wrong code recorded as raised by Sandata while its
acknowledgement has not been sent (200 with the exception, now status
withdrawn; 422 already_sent once it has gone; 404 when the visit has no
code recorded), after which the right code can be recorded. A visit
exception's status gains withdrawn. MCP's withdraw_sandata_exception
does the same.
Changed October 5, 2026 (US-98.37): a visit time written without its UTC
offset (scheduled_start_time, scheduled_end_time, adjusted_start_time,
adjusted_end_time on POST or PATCH /api/v1/visits) is refused with 422
time_offset_required instead of being read as UTC; a value that is not a
time answers 422 invalid_time. MCP gains update_visit, with PATCH's
rules: a null clears a nullable field and is refused (null_not_allowed) on
any other, for every MCP update tool, and the answer carries the same
warnings.
Added October 5, 2026 (US-98.33): POST /api/v1/visits/{id}/reassign hands
a visit to another caregiver (caregiver_id, lock_version), answering the
visit and its warnings (calls_superseded, caregiver_not_active,
overlapping_visit, months_unfrozen); MCP's reassign_visit does the
same. A deleted caregiver is 422 caregiver_not_found, and a visit deleted
meanwhile is 404. A visit's calls
carry superseded_at, set on the earlier caregiver's calls by a reassignment:
they stay as history and no longer count as the visit's clock.
Added October 5, 2026 (US-98.36): PATCH /api/v1/me/pin changes the
caregiver's PIN (current_pin, new_pin). A wrong current_pin is 422
invalid_current_pin and counts as a failed sign-in (429 rate_limited once
the limit is reached); a new PIN that is not six digits, or is repeated or
sequential, is 422 validation_failed naming new_pin. On success (204) the
asking device stays signed in and every other device and web app session of
the caregiver is signed out.
Added October 5, 2026 (US-98.40): POST /api/v1/work-orders/{id}/fill-from-evv
fills an in-progress Work Order's days from the caregiver's EVV visits for its
client, as the page's Fill times from EVV does, and answers the days filled,
updated, unchanged, differing (typed by hand, kept) and flagged; a split shift
fills one entry per visit, a visit fills only the one live Work Order of its
month that serves it (one several could take is flagged), and a fill that
writes moves the Work Order's lock_version. MCP's
fill_work_order_from_evv does the same.
Added October 5, 2026 (US-98.32): DELETE /api/v1/visits/{id} answers
meta.links, what rested on the visit and stays, read under the delete's
lock: timesheet_entries whose EVV times were pulled from it, each with the
work_order_number its timesheet names (the first 50, with
timesheet_entries_total), and unfrozen_months, the Work Order months
its signature alone froze, each with its work_order_number. MCP's delete_visit answers the same as links.
Added October 5, 2026 (US-98.17): an unmatched call carries chosen_visit_id,
the visit the caregiver chose in the phone menu when that visit refused the
call, and reason gains visit_closed, visit_reassigned,
visit_already_clocked, no_clock_in and not_recorded for those calls.
Added October 5, 2026 (US-98.6): POST /api/v1/me/push-tokens registers the
caregiver app's APNs (platform ios) or FCM (platform android) token for
the signed-in device (201 the first time, 200 when it registers again or
replaces the token), and DELETE /api/v1/me/push-tokens/current stops push to
it; signing out does too. Reminders and alerts are queued to the app's
devices beside the caregiver web app's Web Push; delivery through APNs and FCM
starts once those are configured.
Added October 5, 2026 (US-98.12): the caregiver app's profile and inbox.
GET /api/v1/me also returns the caregiver's phone, email and
unread_notifications (as does sign-in's caregiver).
GET /api/v1/me/devices lists the devices the caregiver is signed in on
(current marks the one asking) and DELETE /api/v1/me/devices/{id} signs one
out. GET /api/v1/me/notifications (filter by type, dismissed=true to
include dismissed ones), POST /api/v1/me/notifications/{id}/read,
POST /api/v1/me/notifications/{id}/dismiss and
POST /api/v1/me/notifications/read-all (answering data.marked) work the
caregiver's notifications; a dismissal keeps its first time when repeated.
Another caregiver's device or notification is 404.
Added October 4, 2026 (US-98.8): POST /api/v1/visits schedules a visit
(source api), PATCH /api/v1/visits/{id} corrects its scheduled and
adjusted times and EVV attributes with the lock_version it was read with,
and POST /api/v1/visits/{id}/transitions moves its status (verify, cancel,
reopen and the rest), answering 422 invalid_transition with the statuses it
can move to. An adjusted-time change records Colorado's reason_code and
reason_memo; without a reason it is saved as OTHER. Create and update answer
{data, warnings}: reason_code_missing and overlapping_visit are warnings,
never refusals, as are group_identifier_dropped, assignment_not_open
(an assignment the office ended), long_window (over 24 hours) and
service_date_moved. A client, caregiver or assignment from another agency
(or an assignment for another pair) is 422 naming the field, as is a scheduled
window over 31 days. A visit's service date is its
scheduled start's day in Mountain time, set from the times rather than sent,
and it moves with the start; visit_type changes only
while the visit is not queued for or sent to Sandata, and only a group visit
keeps a group_identifier.
Added October 4, 2026 (US-98.20): DELETE /api/v1/visits/{id}, with the
lock_version the visit was read with, deletes a visit as the web does: its open exceptions are dismissed and their
Sandata acknowledgements queued, and a visit Sandata holds is queued to go to
Sandata as cancelled. A visit changed since it was read answers 409
stale_record; a deleted or unknown one answers 404.
Changed October 4, 2026 (US-98.20): a deleted visit's exceptions are
dismissed with it. GET /api/v1/visit-exceptions still lists them, now with
status dismissed, resolution code other and the note "The visit was
deleted."; the response shape is unchanged.
Added October 3, 2026 (US-74.1): POST /api/v1/clients/{id}/acp-protection
marks a client in Colorado's Address Confidentiality Program, whose address
and call locations are then withheld from Sandata, or removes the mark with a
reason; a client carries acp_protected.
Added October 4, 2026 (US-98.5): POST /api/v1/me/visits/{id}/signatures
keeps the client's or the caregiver's signature on one of the caregiver's
visits (one per signer; replace: true replaces it), and
GET /api/v1/me/visits/{id}/signatures/{signature_id}/image reads it back as
an uncached PNG.
Added October 4, 2026 (US-98.10): GET /api/v1/unmatched-calls lists the
telephony clock calls that matched no visit (filters status and
call_date_from / call_date_to; the calling number masked to its last four),
and POST /api/v1/unmatched-calls/{id}/match,
POST /api/v1/unmatched-calls/{id}/dismiss and
POST /api/v1/unmatched-calls/{id}/undo-dismiss resolve them as the
unmatched-calls screen does.
Added October 4, 2026 (US-98.4): POST /api/v1/me/clock-events takes up to
100 clocks the caregiver app recorded offline, each recorded at its
captured_at and judged on its own; it answers which synced and which failed.
Added October 4, 2026 (US-98.34): GET /api/v1/refused-clocks lists the
clocks a closed visit refused and the server kept for the office, and
POST /api/v1/refused-clocks/{id}/review marks one reviewed;
GET /api/v1/me/refused-clocks gives the caregiver app the signed-in
caregiver's own of the last 30 days.
Added October 2, 2026 (US-98.22): POST /api/v1/visits/{id}/sandata-exceptions
records the ACK exception Sandata raised on a visit it took (15 Unmatched
Client ID / Phone or 21 No Show Exception) as a sandata_raised visit
exception and queues its acknowledgement to Sandata; one per visit.
Added October 2, 2026 (US-95.25): the Work Order lifecycle.
POST /api/v1/work-orders/{id}/archive,
POST /api/v1/work-orders/{id}/unarchive,
POST /api/v1/work-orders/{id}/reopen,
POST /api/v1/work-orders/{id}/signatures,
POST /api/v1/work-orders/{id}/paper-signatures,
POST /api/v1/work-orders/{id}/transition and
POST /api/v1/work-orders/{id}/dismiss-warnings change a Work Order read at the
lock_version sent (409 for one changed since);
POST /api/v1/work-orders/{id}/duplicate copies it into the next month or the
month sent; POST /api/v1/work-orders/{id}/close-document snapshots a
completed one, close notes left out; and
POST /api/v1/work-orders/{id}/dismiss-guidance clears the page's Getting
Started notice. A status change to completed answers the caregiver report it
wrote or found in timesheet; an unarchive, reopen or duplicate whose slot a
live Work Order holds answers 409 slot_taken with its WO #. A Work Order now
reads with its four signature dates, paper_signatures_collected and
paper_signatures_collected_at.
Added October 2, 2026 (US-95.24): an assignment's status and weekly schedule.
POST /api/v1/assignments/{id}/transition changes an assignment's status,
with an optional reason the status history keeps and the lock_version it
was read with. GET /api/v1/assignments/{id}/schedule reads its shifts and
their days, and PUT /api/v1/assignments/{id}/schedule replaces one shift's
days, the shift named by shift_number in the body or ?shift=, with the
lock_version the assignment was read with; a save moves it and answers the
new one beside the shifts. A refused day answers 422 invalid_schedule
naming it. A transition's reason is at most 1000 characters.
Added October 2, 2026 (US-95.23): the PAR lifecycle.
POST /api/v1/authorizations/{id}/transition changes a PAR's status and
DELETE /api/v1/authorizations/{id} deletes one that is not active; both take
the lock_version the PAR was read with (in the body, and in the query
string for the delete) and answer 409 for a PAR changed since.
POST /api/v1/authorizations/{id}/recertifications starts its renewal,
POST /api/v1/recertifications/{id}/in-progress and
POST /api/v1/recertifications/{id}/complete move it on, and
GET /api/v1/recertifications lists the open ones of PARs still on file.
A PAR has one open recertification at a time, and completing one creates the
renewing PAR from the fields sent, as the web's renewal form does.
POST /api/v1/eligibility-checks records a client's eligibility for a month
and POST /api/v1/clients/{id}/eligibility-verified marks it verified;
clients now carry eligibility_verified_at.
Added October 2, 2026 (US-95.21): Plans of Care. GET /api/v1/plans-of-care
and GET /api/v1/plans-of-care/{id} return a client's plans with their
tasks; POST /api/v1/plans-of-care creates one with its tasks (the client's
current plan for that service becomes past) and
PATCH /api/v1/plans-of-care/{id} changes one, replacing its tasks when a
list is sent. A lowered task is saved with an over_authorized warning in
warnings. Plans have no lock_version (the last save wins, as on the web)
and no delete.
Added October 2, 2026 (US-95.19): the agency profile. GET /api/v1/agency
returns the agency's name, address, phone and fax, NPI, Tax ID and claim
defaults (rendering provider id, diagnosis code, place of service, week start
day). PATCH /api/v1/agency sets the fields it sends; admin credentials only.
The claim defaults and the week start can be changed but not cleared.
Added October 2, 2026 (US-94.20, US-94.23): GET /api/v1/claims takes
member (a Medicaid ID or patient name, at most 64 characters);
GET /api/v1/authorizations takes service_code, in any letter case;
POST /api/v1/batches/validate takes an optional column_mapping, as a JSON
part or column_mapping[field] form fields, applied over the saved mapping
for that check only.
Added October 1, 2026 (Epic 98): the caregiver app. A caregiver signs in with
POST /api/v1/caregiver-sessions (agency code, employee id, PIN) and gets a
device token, sent as a bearer token on /api/v1/me routes only:
GET /api/v1/me, and DELETE /api/v1/caregiver-sessions/current to sign
out. An agency API key is refused there, and a device token everywhere else.
Added October 1, 2026 (Epic 98): EVV visits. GET /api/v1/visits and
GET /api/v1/visits/{id}; one visit also carries the newest 200 of its clock
calls, its changes with reason codes and who signed (never the image).
Added October 1, 2026 (US-98.2): the caregiver's own schedule.
GET /api/v1/me/visits lists the signed-in caregiver's visits from
date_from to date_to (today by default, at most 31 days, starting no
more than 90 days back), not cancelled, with each client's name, address
and geofence and never a Medicaid id. GET /api/v1/me/visits/{id} is one of
them with its clock-in and clock-out; another caregiver's visit is 404, and
a cancelled or deleted one is returned with its status and deleted_at.
Added October 1, 2026 (US-98.3): clocking in and out from the caregiver app.
POST /api/v1/me/visits/{id}/clock-in and
POST /api/v1/me/visits/{id}/clock-out record the call with
the device's location and the device token's device id, and answer with the
warnings it was recorded with; whatever the device sends is recorded, never
refused, and a captured_at that is not a time, is ahead of now, or is
before the visit existed is recorded at the server's time; one sent more than
5 minutes after the time it carries is recorded at that time with late_sync.
A repeat answers 200 with the first call. A visit that is not scheduled or in
progress takes no clock: 422 visit_not_clockable, nothing recorded.
Added October 1, 2026 (US-98.9): visit exceptions. GET /api/v1/visit-exceptions
(filterable by status, exception_type, severity, visit, client, caregiver and
detected date, and syncable) and GET /api/v1/visit-exceptions/{id}, each
with the Colorado reason code its Sandata acknowledgement carries;
POST /api/v1/visit-exceptions/{id}/resolve to acknowledge, correct or
dismiss one, POST /api/v1/visit-exceptions/resolve for up to 100 at once,
and GET /api/v1/visit-exceptions/reason-codes.
Authentication is an agency API key, sent as a bearer token. Every list is
paginated and every error uses one envelope. A POST made with an API key takes an
Idempotency-Key header (except POST /api/v1/batches/validate, which stores
nothing). A PATCH takes no Idempotency-Key; it sets only the fields it sends.
The API is described by an OpenAPI 3 document, which needs no credential.
Operations, by resource:
- Clients:
GET /api/v1/clients,POST /api/v1/clients,GET /api/v1/clients/{id},PATCH /api/v1/clients/{id} - Caregivers:
GET /api/v1/caregivers,POST /api/v1/caregivers,GET /api/v1/caregivers/{id},PATCH /api/v1/caregivers/{id} - Assignments:
GET /api/v1/assignments,POST /api/v1/assignments,GET /api/v1/assignments/{id},PATCH /api/v1/assignments/{id} - Service authorizations:
GET /api/v1/authorizations,POST /api/v1/authorizations,GET /api/v1/authorizations/{id},PATCH /api/v1/authorizations/{id} - Batches:
GET /api/v1/batches,POST /api/v1/batches(upload a claims file),GET /api/v1/batches/{id},POST /api/v1/batches/validate(check a file without storing it), andPOST /api/v1/batches/{id}/submit(send a batch to HCPF) - Claims:
GET /api/v1/claims,GET /api/v1/claims/{id} - Work orders:
GET /api/v1/work-orders,POST /api/v1/work-orders,GET /api/v1/work-orders/{id},PATCH /api/v1/work-orders/{id} - Timesheets:
GET /api/v1/timesheets,GET /api/v1/timesheets/{id} - Service rates:
GET /api/v1/service-rates,GET /api/v1/service-rates/{id} - Billing codes:
GET /api/v1/billing-codes - Responses from the payer:
GET /api/v1/responses,GET /api/v1/responses/{id} - Remittances:
GET /api/v1/remittances,GET /api/v1/remittances/{id} - The OpenAPI document:
GET /api/v1/openapi.json
Webhook event types, registered by an agency admin in Settings:
batch.acceptedbatch.rejectedremittance.postedclaim.denied