PBJ Staffing Data Pre-Submission QA API Reference
Beta. Structural checks of a nursing home's quarterly PBJ staffing XML file against the CMS PBJ data specifications v4.10.0, internal consistency checks, and flags for documented audit and rating risks. Product page and free test form.
Endpoint
| Paid | POST https://www.spreadrun.com/api/v1/pbj-staffing-qa, API key required, $25.00 per completed report |
|---|---|
| Demo | POST https://www.spreadrun.com/api/demo/pbj-staffing-qa, no key, 1 MB, 10 runs per day |
| Body | The PBJ staffing XML file, a gzip of it, or the ZIP you upload to CMS. Any Content-Type; gzip and ZIP are detected from the content. |
Request
Send the file itself as the request body, up to 4.4 MB (HTTP 413 above that). Staffing XML compresses very well, so send the ZIP or a gzip for a large facility. Each XML file in a ZIP may be up to 50 MB uncompressed, the CMS limit, and a ZIP may hold up to 20 XML files; they are checked together and billed as one report.
| Query parameter | Default | Meaning |
|---|---|---|
asOf | today (UTC) | A date, YYYY-MM-DD: the day you plan to upload. CMS edit -4002 rejects work dates after it, the count of days without RN hours stops at it, and the deadline countdown starts from it. |
census | none | Total resident days in the quarter (the sum of each day's census). Turns on the staffing estimate. Above 0. |
weekendCensus | estimated | Resident days on Saturdays and Sundays. When missing, estimated from census assuming the same census every day. |
caseMixRatio | 1.0 | The facility's nursing case-mix index divided by the national average, 0.2 to 5. Adjusted hours are reported hours divided by it. |
rnTurnover, nurseTurnover | none | Twelve-month turnover percentages, 0 to 100. When missing, the star range covers every possible turnover score. |
adminDepartures | none | Administrators who left in the last twelve months, a whole number. |
Rejected with HTTP 400 and not charged: an empty body, a PDF, a file that is not well-formed XML, DOCTYPE or entity declarations, a root that is not nursingHomeData, an Employee Link (administration) file, a ZIP with no XML file or more than 20, a corrupt or encrypted ZIP, an invalid asOf. A PBJ file with problems is not an input error: it gets a completed FAIL report, and that run is charged.
Report
| Field | Meaning |
|---|---|
status | FAIL if any error, WARN if only warnings, otherwise PASS. A PASS is not CMS acceptance and does not mean the file would survive an audit. |
specVersion, fileSpecVersion | The CMS specification checked against (4.10.0), and the file's own version when it is a known one (otherwise other). |
reportingQuarter | federalFiscalYear, quarter, and the quarter's start and end dates. |
processType | merge or replace. |
counts | employees, staffHoursRecords, workDays, hourEntries, totalHours. |
coverage | daysWithHours, daysWithRnHours, daysWithoutRnHours (days in the quarter up to asOf). |
findings | Up to 500, errors first. Each has severity (error or warning), ruleId, path (XPath-style, with [n] where an element repeats), message and source (a key into sources). Findings never repeat a value from the file. |
findingCount, findingCounts, ruleCounts, findingsTruncated | Totals, including findings beyond the 500 listed. |
files | Only for a ZIP with several XML files: one summary per file, numbered by position in the ZIP, and each finding gets a file number. |
notChecked, sources, scope | What the report does not cover, the documents each rule comes from, and what the verdict means. |
submissionDeadline | date (the end of the 45th day after the quarter), time, daysRemaining and passed, as of asOf. |
staffingEstimate | Only when census is sent. An estimate, not the CMS rating: reportedHprd and adjustedHprd (total nurse, RN and weekend total nurse hours per resident day; job title codes 5 to 12, RN 5 to 7), points per CMS Table A2, scoreRange out of 380, starRange and stars per Table 3, oneStarException (four or more days without RN hours), excluded (a CMS exclusion rule applies), assumptions and label. The inputs themselves are never repeated. |
input, inputSha256, asOf | Container (xml, gzip or zip), number and total size of XML files, the SHA-256 of the request body, and the date used. |
Rule IDs
CMS edits keep their CMS number, so a finding can be matched to the edit the CMS system would report. Fatal CMS edits are errors; CMS warnings, risk flags and consistency checks are warnings.
| Rule | Severity | Source | Meaning |
|---|---|---|---|
XSD | error | spec | The XML does not follow the CMS v4.10.0 XSD: an unknown or misplaced element, an element repeated more than allowed, or an empty optional header item. |
CMS-4003, CMS-4004, CMS-4006 | error | spec | A required header, employee or staffing hours item is missing. |
CMS-1020 | warning | spec | A retired fileSpecVersion (2.00.0, 2.00.3 or 4.00.0) on a check dated before April 1, 2026. |
CMS-1021 | error | spec | A retired fileSpecVersion on or after April 1, 2026. Files must use 4.10.0. |
CMS-3676 | error | spec | A coded value that is not allowed: fileSpecVersion, stateCode, reportQuarter, processType, jobTitleCode (1 to 40) or payTypeCode (1 to 3). |
CMS-3677 | error | spec | A date that is empty or not a valid YYYY-MM-DD date. |
CMS-3679 | error | spec | A number out of range: federalFiscalYear before 2016, or hours outside 0 to 22.5 or with more than two decimals. |
CMS-3690, CMS-3692, CMS-3802, CMS-4018 | error | spec | Characters CMS does not allow in a text item, the email address, or an employee ID. |
CMS-3702 | error | spec | facilityId is blank. |
CMS-3793 | error | spec | Text longer than the item allows. |
CMS-1009, CMS-4019 | error | spec | A year before 1895 or after 2050. |
CMS-4002 | error | spec | A work date after asOf (today by default). CMS rejects dates after the upload date. |
CMS-4008 | error | spec | processType is missing from staffingHours. |
CMS-4025 | error | spec | More than 22.5 hours for one employee on one date, all job titles together. |
CMS-1010 | warning | spec | A work date outside the quarter in the header. CMS does not process that record. |
CMS-4016-PARTIAL | warning | spec | Hours for an employee ID that is not in this file's employees section. CMS rejects the file unless the ID is already in its system, which only CMS can check. |
CMS-ASCII | warning | spec | Non-ASCII characters. CMS requires standard ASCII and issues a warning for anything else. |
RISK-HOURS-PER-MONTH | warning | audit2018 | More than 400 hours in one calendar month for one employee ID. |
RISK-NO-RN-DAYS | warning | fivestar | Four or more days in the quarter, up to asOf, with no hours under job title codes 5, 6 or 7 (RN). |
RISK-ID-PII | warning | manual | An employee ID shaped like a Social Security Number. |
RISK-EMPTY-REPLACE | warning | spec | processType="replace" with no staffHours records, which deletes all staffing hours already submitted for the quarter. |
SR-OUTSIDE-EMPLOYMENT | warning | SpreadRun | Hours before the employee's hireDate or after their terminationDate. |
SR-DATE-ORDER | warning | SpreadRun | terminationDate before hireDate. |
SR-DUPLICATE-EMPLOYEE | warning | manual | The same employee ID listed more than once in the employees section. |
Source keys, as returned in every report:
spec | CMS PBJ Data Specifications v4.10.0 (January 16, 2026), edit IDs and XSD |
manual | CMS PBJ Policy Manual v2.8 (August 2026) |
faq | CMS PBJ Policy Manual FAQ (August 2026) |
fivestar | CMS Nursing Home Five-Star Quality Rating System Technical Users' Guide (September 2026) |
audit2018 | CMS PBJ audit selection criteria as stated by CMS and reported by Skilled Nursing News (November 2018) |
- CMS Staffing Data Submission (PBJ) page: data specifications v4.10.0, Policy Manual v2.8 and FAQ
- CMS PBJ audit selection criteria, as reported by Skilled Nursing News (November 2018)
- CMS Nursing Home Five-Star Quality Rating System: Technical Users' Guide (September 2026) and cut point tables
- HHS OIG report A-09-24-02005 on RN hours reported in PBJ (June 2026)
Not checked
- Whether facilityId and employee IDs match what CMS has on file (CMS edits -3693 and -4016 need the PBJ system).
- Whether hours match payroll, invoices or contracts, which is what PBJ audits verify.
- Whether hours were worked onsite, and whether meal breaks were actually deducted (the file has no shift times).
- The CMS staffing rating itself. With a census you send, the report estimates hours per resident day and a star range; CMS uses its own MDS census, case mix and six quarters of turnover data.
- PBJ Administration Submission files (Employee Link).
- ZIP and XML file naming rules, and the 5 MB limit CMS applies to the upload ZIP.
Example responses
A paid check of the synthetic PBJ sample with asOf=2026-10-03 (report shortened to its summary fields), and the findings from a demo check of the sample with planted problems. Both generated by running the real endpoint code.
{
"requestId": "7f3c2a1e-5b8d-4c6f-9e0a-1d2b3c4d5e6f",
"api": "pbj-staffing-qa",
"mode": "paid",
"charged": true,
"priceCents": 2500,
"balanceCents": 7500,
"report": {
"schemaVersion": 1,
"status": "PASS",
"specVersion": "4.10.0",
"fileSpecVersion": "4.10.0",
"reportingQuarter": {
"federalFiscalYear": 2026,
"quarter": 4,
"start": "2026-07-01",
"end": "2026-09-30"
},
"processType": "merge",
"counts": {
"employees": 14,
"staffHoursRecords": 14,
"workDays": 789,
"hourEntries": 789,
"totalHours": 6917.5
},
"coverage": {
"daysWithHours": 92,
"daysWithRnHours": 92,
"daysWithoutRnHours": 0
},
"findingCount": 0,
"findingCounts": {
"error": 0,
"warning": 0
},
"ruleCounts": {},
"findingsTruncated": false,
"scope": "Structural checks against the CMS PBJ data specifications and documented risk patterns. A PASS does not mean CMS will accept the file or that it will survive a CMS audit, and this is not legal or compliance advice.",
"submissionDeadline": {
"date": "2026-11-14",
"time": "11:59 PM Eastern Time",
"asOf": "2026-10-03",
"daysRemaining": 42,
"passed": false,
"note": "CMS accepts no submissions after the deadline."
},
"input": {
"container": "xml",
"xmlFiles": 1,
"xmlBytes": 233073
},
"inputSha256": "a1da2506994af98f782f9ecc409b18a4dbdca9f7d7e3ba1e33b9668bab76873a",
"asOf": "2026-10-03"
}
}[
{
"severity": "error",
"ruleId": "CMS-1021",
"path": "/nursingHomeData/header/@fileSpecVersion",
"message": "This fileSpecVersion was retired on April 1, 2026. Files must use 4.10.0.",
"source": "spec"
},
{
"severity": "error",
"ruleId": "CMS-3676",
"path": "/nursingHomeData/staffingHours/staffHours[8]/workDays/workDay[67]/hourEntries/hourEntry/jobTitleCode",
"message": "jobTitleCode must be one of the CMS job title codes 1 to 40.",
"source": "spec"
},
{
"severity": "error",
"ruleId": "CMS-3676",
"path": "/nursingHomeData/staffingHours/staffHours[9]/workDays/workDay[66]/hourEntries/hourEntry/payTypeCode",
"message": "payTypeCode must be 1 (exempt), 2 (non-exempt) or 3 (contract).",
"source": "spec"
},
{
"severity": "error",
"ruleId": "CMS-3677",
"path": "/nursingHomeData/employees/employee[14]/hireDate",
"message": "hireDate is empty. Remove the tag when there is no date.",
"source": "spec"
}
]Errors
See the shared error table. Example input error (HTTP 400, not charged):
{
"error": {
"code": "input_error",
"message": "The file is not well-formed XML (no element found: line 1, column 71).",
"requestId": "7f3c2a1e-5b8d-4c6f-9e0a-1d2b3c4d5e6f",
"charged": false
}
}Code samples
# The ZIP you upload to CMS (or the XML file), checked as of the planned upload date
curl -X POST "https://www.spreadrun.com/api/v1/pbj-staffing-qa?asOf=2026-11-10" \
-H "Authorization: Bearer $SPREADRUN_API_KEY" \
-H "Content-Type: application/zip" \
--data-binary @pbj_2026_q4.zip