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

PaidPOST https://www.spreadrun.com/api/v1/pbj-staffing-qa, API key required, $25.00 per completed report
DemoPOST https://www.spreadrun.com/api/demo/pbj-staffing-qa, no key, 1 MB, 10 runs per day
BodyThe 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 parameterDefaultMeaning
asOftoday (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.
censusnoneTotal resident days in the quarter (the sum of each day's census). Turns on the staffing estimate. Above 0.
weekendCensusestimatedResident days on Saturdays and Sundays. When missing, estimated from census assuming the same census every day.
caseMixRatio1.0The facility's nursing case-mix index divided by the national average, 0.2 to 5. Adjusted hours are reported hours divided by it.
rnTurnover, nurseTurnovernoneTwelve-month turnover percentages, 0 to 100. When missing, the star range covers every possible turnover score.
adminDeparturesnoneAdministrators 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

FieldMeaning
statusFAIL 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, fileSpecVersionThe CMS specification checked against (4.10.0), and the file's own version when it is a known one (otherwise other).
reportingQuarterfederalFiscalYear, quarter, and the quarter's start and end dates.
processTypemerge or replace.
countsemployees, staffHoursRecords, workDays, hourEntries, totalHours.
coveragedaysWithHours, daysWithRnHours, daysWithoutRnHours (days in the quarter up to asOf).
findingsUp 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, findingsTruncatedTotals, including findings beyond the 500 listed.
filesOnly 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, scopeWhat the report does not cover, the documents each rule comes from, and what the verdict means.
submissionDeadlinedate (the end of the 45th day after the quarter), time, daysRemaining and passed, as of asOf.
staffingEstimateOnly 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, asOfContainer (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.

RuleSeveritySourceMeaning
XSDerrorspecThe 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-4006errorspecA required header, employee or staffing hours item is missing.
CMS-1020warningspecA retired fileSpecVersion (2.00.0, 2.00.3 or 4.00.0) on a check dated before April 1, 2026.
CMS-1021errorspecA retired fileSpecVersion on or after April 1, 2026. Files must use 4.10.0.
CMS-3676errorspecA coded value that is not allowed: fileSpecVersion, stateCode, reportQuarter, processType, jobTitleCode (1 to 40) or payTypeCode (1 to 3).
CMS-3677errorspecA date that is empty or not a valid YYYY-MM-DD date.
CMS-3679errorspecA 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-4018errorspecCharacters CMS does not allow in a text item, the email address, or an employee ID.
CMS-3702errorspecfacilityId is blank.
CMS-3793errorspecText longer than the item allows.
CMS-1009, CMS-4019errorspecA year before 1895 or after 2050.
CMS-4002errorspecA work date after asOf (today by default). CMS rejects dates after the upload date.
CMS-4008errorspecprocessType is missing from staffingHours.
CMS-4025errorspecMore than 22.5 hours for one employee on one date, all job titles together.
CMS-1010warningspecA work date outside the quarter in the header. CMS does not process that record.
CMS-4016-PARTIALwarningspecHours 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-ASCIIwarningspecNon-ASCII characters. CMS requires standard ASCII and issues a warning for anything else.
RISK-HOURS-PER-MONTHwarningaudit2018More than 400 hours in one calendar month for one employee ID.
RISK-NO-RN-DAYSwarningfivestarFour or more days in the quarter, up to asOf, with no hours under job title codes 5, 6 or 7 (RN).
RISK-ID-PIIwarningmanualAn employee ID shaped like a Social Security Number.
RISK-EMPTY-REPLACEwarningspecprocessType="replace" with no staffHours records, which deletes all staffing hours already submitted for the quarter.
SR-OUTSIDE-EMPLOYMENTwarningSpreadRunHours before the employee's hireDate or after their terminationDate.
SR-DATE-ORDERwarningSpreadRunterminationDate before hireDate.
SR-DUPLICATE-EMPLOYEEwarningmanualThe same employee ID listed more than once in the employees section.

Source keys, as returned in every report:

specCMS PBJ Data Specifications v4.10.0 (January 16, 2026), edit IDs and XSD
manualCMS PBJ Policy Manual v2.8 (August 2026)
faqCMS PBJ Policy Manual FAQ (August 2026)
fivestarCMS Nursing Home Five-Star Quality Rating System Technical Users' Guide (September 2026)
audit2018CMS PBJ audit selection criteria as stated by CMS and reported by Skilled Nursing News (November 2018)

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