Certified payroll in XML: what a contractor files and when
Contractors on most California public works submit certified payroll to the Labor Commissioner at least every 30 days, through DIR's online form or an XML upload validated against schema CPR.xsd version 1.3. The file carries contractor, project and weekly payroll blocks, and uploading it is not filing it until someone signs.
A certified payroll record on a California public works job is a filing of its own, made to its own agency, on its own clock. The payroll run that paid the crew on Friday is the input.
A vegetation contractor cutting right of way for a county, a fire safe council or a municipal utility files the record every week or every month for the life of the contract. Where federal money buys covered construction, it files a second record weekly, in a different format, identifying each worker by a number rather than by a full social security number.
This page covers what goes in the file, what the schema will reject, when the filing is due, and what the missed filing costs. Whether the work is a public work at all is decided under Labor Code section 1720, and the prevailing wage page covers that line. Everything below assumes the answer was yes.
Who files, and the four ways out
Labor Code section 1771.4(a)(3)(A) puts the duty on every tier:
Each contractor and subcontractor shall furnish the records specified in Section 1776 directly to the Labor Commissioner
Every entity that employs a worker on the project files for its own workers. A five person hand crew working under a prime on a county fuel break files its own record, under its own registration number, every week it turns a saw. DIR treats that duty as standing alone:
Submitting certified payroll records to other agencies does not fulfill the requirement to submit certified payroll records to the Labor Commissioner/DIR.
There are four exits, and only four:
1. A legacy labor compliance program. DIR exempts projects monitored and enforced by Caltrans, the City of Los Angeles, Los Angeles Unified School District and the County of Sacramento. The list is published and runs "until further notice." 2. A qualifying project labor agreement. Section 1771.4(b)(2) reaches an agreement that binds all contractors on the project and includes a mechanism for resolving wage payment disputes.
3. The small project exemption. DIR states it applies to projects capped at "$25,000 for new construction, alteration, installation, demolition or repair" and "$15,000 for maintenance." Most routine vegetation work is maintenance, so the $15,000 line is the one that usually decides. 4. An unregistered contractor on a project below the registration threshold. Section 1771.4(a)(4) lets that contractor keep the section 1776 records instead of filing them, for at least three years after the work is complete.
Those four are the whole list. Section 1771.4 counts one filing, the one made to the Labor Commissioner, and every other copy a contractor sends out that week sits on top of it.
Two clocks run, and the short one starts on a written request
The monthly clock is the filing clock. Section 1771.4(a)(3)(A)(i) defines it:
For purposes of this clause, "monthly" means that a submission of records shall be made at least once every 30 days while work is being performed on the project and within 30 days after the final day of work performed on the project.
Miss it and the penalty is $100 for each day in violation, capped at $5,000 per project, and the Labor Commissioner may levy it once the filing is 14 days past due. DIR's own advice is to file faster than the statute: "The best practice is to submit the records weekly or at the conclusion of each payroll period."
The ten day clock is the production clock, and it is worse. Section 1776(h) runs on written request rather than on the calendar:
In the event that the contractor or subcontractor fails to comply within the 10-day period, the contractor or subcontractor shall, as a penalty to the state or political subdivision on whose behalf the contract is made or awarded, forfeit one hundred dollars ($100) for each calendar day, or portion thereof, for each worker, until strict compliance is effectuated.
Per worker, per calendar day, and open ended. A five person crew whose records are requested on March 2, due March 12, and produced on April 1 has run 20 days past the deadline across five workers: $10,000. The same five person crew that files its monthly eCPR 20 days late is exposed to $100 a day against a $5,000 ceiling, which is $2,000 if the count runs from the missed deadline.
Section 1771.4 is silent on whether the count runs from the deadline or from the end of the 14 day window, and the Labor Commissioner decides. Penalties under both sections stay with the party that failed. Section 1776(h) states that a contractor is not penalized for a subcontractor's failure, and section 1771.4(a)(3)(D) says penalties "may only accrue to the actual contractor or subcontractor who failed to furnish the records."
What the file has to contain
What the record has to show is set by section 1776(a), and the list is short:
Each contractor and subcontractor shall keep accurate payroll records, showing the name, address, social security number, work classification, straight time and overtime hours worked each day and week, and the actual per diem wages paid to each journeyman, apprentice, worker, or other employee employed by the contractor or subcontractor in connection with the public work.
The schema is where that list becomes a file. It is CPR.xsd, and its own first comment identifies it: `<!--XML SCHEMA for electronic California Payroll Records Version 1.3-->`. One file covers one contractor, one project, one contract relationship and one week ending date. Its three blocks are `contractorInfo`, `projectInfo` and `payrollInfo`, and the third holds an `employees` list with one `employee` per worker.
The constraints are where a payroll export fails. These are the ones that stop a file at validation:
Element | What it holds | What the schema accepts |
`contractorPWCR` | public works registration number | ten digits, or the literal `NA` |
`contractorFEIN` | federal employer ID | exactly nine digits; a sole proprietor without one enters a social security number |
`awardingBody`, `contractAgencyID`, `projectName` | placeholders | empty, and only empty; all three are declared `fixed=""` |
`contractAgency` | who you contract with | 1 to 56 characters, matching the Contract With field |
`projectID` | the DIR project ID | 1 to 18 digits |
`forWeekEnding` | last day of the payroll week | a date in `yyyy-mm-dd` form |
`employee` | one per worker | 0 to 500 per file |
`name` id attribute | `SSN::NAME` | the name portion in uppercase |
`ssn` | the worker's social security number | exactly nine digits, matching the id attribute |
`state` | address state | two uppercase letters |
`zip` | address zip | exactly five digits |
`day` | one per day of the payroll week | exactly seven, no more and no fewer |
`straightTime`, `overtime`, `doubletime` | that day's hours | a decimal under 100, two decimal places |
`workClass` | the craft | 1 to 300 characters of free text |
`checkNum` | how the worker was paid | 1 to 20 characters; `CASH` for cash, the transaction number for direct deposit |
`notes` | anything else | up to 256 characters, and the only optional element under `employee` |
Three of those are worth calling out. A payroll system that helpfully writes the awarding body's name into `awardingBody` fails, because the schema fixes that element at empty. A zip carrying the plus four fails. And the seven `day` elements are required even when the worker was there for two of them: a faller who started on the Thursday of a week ending Friday still gets seven elements, five of them carrying zeros in all three hour fields.
The classification is free text, and nothing checks it
`workClass` accepts any string between 1 and 300 characters. `Tree Trimmer`, `tree trimmer`, `TT` and `Groundperson after 6 months` all validate, because the schema checks length and stops there. The rate the crew is owed comes from the craft determination, and the file accepts a string that contradicts it.
Where it bites is on the way back. DIR's XML upload user guide lists the fields a corrected filing has to match for the correction to replace the original, and Craft and Base Hourly Rate are both on that list. On that guidance, a classification typed wrong in week one is filed again in week six as a second payroll record sitting beside the first, with both visible on the project. The section below on corrections says how far that 2016 guidance still describes the system.
Take the classification off the determination before the first filing, and carry that exact string through every week of the job.
Fringe benefits go in by the hour, deductions go in by the period
Both sit in the same `deductionsContribPay` block, and the schema treats every child identically: a decimal, two places, under 100,000,000. The distinction is in the March 2026 guidelines and nowhere in the schema:
When entering fringe benefits (e.g. pension) in the `<CPR:deductionsContribPay>` section, make sure to include hourly amounts. For deductions, enter the total lump sum amount for deductions such as $121.22 for FICA, which indicates a total amount paid to FICA of $121.22 for all hours worked in the pay period.
So `healthWelfare`, `pension`, `training`, `vacationHoliday` and `fundAdmin` are per hour, while `fedTax`, `FICA`, `stateTax`, `SDI`, `dues`, `savings` and `other` are the period total. A trimmer who worked 40 hours with $8.90 an hour of health and welfare goes in as `8.90`, not `356.00`. A file with `356.00` in that element validates cleanly and reports a fringe contribution forty times the real one.
A schema valid file can therefore overstate a fringe contribution by a factor of forty, and the upload accepts it in silence.
A week with no work is still a filing
Set `statementOfNP` to `true` and the employee list goes away. The schema documentation says what remains:
In that case, your payrollInfo element should only contain the statementOfNP element value of true, payrollNum element, forWeekEnding element and an empty employees tag.
A crew stood down for a week by rain, a burn window or a permit is a week of non-performance, and the project record should say so rather than showing a gap. The same mechanism undoes a mistake in the other direction: DIR states that where payroll was submitted for a period in which no work was performed, a Statement of Non-Performance filed for the same period "will take precedence over the record submitted in error."
Uploading the file is not filing it
The Upload eCPR guide puts the XML path at services.dir.ca.gov/pw, under Submit then XML next to the project. The form asks for three fields the file already carries:
Complete the required fields in the form: Contractor, Contract With, and DIR Project ID. Indicate whether this is an amendment to a previous payroll. Click Upload to attach your XML file (exported from your payroll system).
Then a signature, then Submit, then several minutes while the system builds the payroll record. The signature is the filing. Everything before it is a draft, and DIR is blunt about what the signature closes: "At any time before you sign the record, you can use the navigation tools to review and modify it. After the record is signed, you will no longer be able to access or change it."
What that signature carries is set by statute. Section 1776(a) requires a written declaration under penalty of perjury stating two things: that the information in the payroll record is true and correct, and that the employer has complied with sections 1771, 1811 and 1815 for the work performed. The second half is a statement about the rate and about overtime, which is wider ground than the arithmetic in the file. A crew supervisor who signs because the hours look right has certified the classification too.
Section 1776(c) draws the line between this filing and every other one: certified payroll records are on DLSE forms, or carry the same information, "unless required to be furnished directly to the Labor Commissioner in accordance with paragraph (3) of subdivision (a) of Section 1771.4."
The copy that goes to an awarding body or a Labor Compliance Program is governed by 8 CCR section 16401(b), which prints the words of certification down to the blanks, and by 8 CCR section 16404, which sets five conditions on submitting them electronically. Section 16404 was filed December 22, 2008 and became operative January 21, 2009, seven years before the electronic filing duty reached every public works contract on January 1, 2016, and its last condition reads oddly against that duty:
No contractor or subcontractor shall be mandated to submit or receive electronic reports when it otherwise lacks the resources or capacity to do so, nor shall any contractor or subcontractor be required to purchase or use proprietary software that is not generally available to the public.
DIR's answer for the filing made to the Labor Commissioner is that the eCPR system is the only route to it. Section 16404 governs the paper or electronic copy that goes elsewhere, and the reference format there is still DIR's Public Works Payroll Reporting Form A-1-131. A contractor that genuinely lacks the capacity to file electronically takes that to the Labor Commissioner rather than to the awarding body.
Two practical consequences follow. Whoever signs should be the person who can answer for the classification and the rate, which is rarely the person who exported the file. And the unredacted copy has one moment of availability, on the confirmation page, where DIR's guide tells contractors to save the PDF. What the public search returns afterward is fully redacted:
Full redaction removes all personal, identifiable employee information (name, address, phone number, and SSN) as well as the contractor's federal ID (FEIN) or SSN and email address.
Correcting a record, and the fields that decide whether it is an amendment
A submitted record cannot be edited or deleted. DIR's answer is to file again for the same period:
You cannot change or delete records that have already been submitted. However, you may correct errors by submitting a new record for the same pay period. The new or "amended" record for an employee will take precedence over the original record submitted.
The correction runs per employee. A file fixing one worker's hours carries that worker alone, and a file adding a worker left off the original carries just the new one. The original stays on file and is visible alongside every amendment, which is the point: the project record shows the correction as well as the error.
What decides whether the system treats the new file as an amendment or as a second record is the set of fields it matches on. DIR's XML upload user guide, dated July 2016, names six:
Field | Where it lives in the XML |
Contractor's SSN or FEIN | `contractorFEIN` |
DIR Project ID | `projectID` |
Contract agency name | `contractAgency` |
Week ending date | `forWeekEnding` |
Craft | `workClass` |
Base hourly rate | `hrlyPayRateStraightTime` |
That guide also warns that the contract agency name has to match the project registration exactly:
If the name is even slightly off (different spacing, punctuation, capitalization style or spelling), the system will create a new branch of payroll.
`County of Sonoma` and `County Of Sonoma` are two contract relationships as far as the record is concerned.
The current upload form asks the contractor to declare an amendment rather than inferring one, so the 2016 matching behavior may describe a system that has since moved on. The underlying advice survives the change either way: hold those six fields constant across a correction, and pick the contract agency string once at the start of the job.
The guidelines the eCPR page links are from January 2016
DIR publishes two documents with the same title, and they disagree. The Certified Payroll Reporting page, datestamped May 2026, names "CPR XML schema V1.3" and links a PDF headed "eCPR XML Guidelines, January, 2016, Version 1.10." The Support Center links a different PDF, headed "eCPR XML Guidelines, March 2026, Version 2.0." Both are live. They differ on four points:
Point | January 2016, version 1.10 | March 2026, version 2.0 |
File name | `[last 4 digits of FEIN]_[Project ID]_[week ending date].xml`, example `6789_DIR001_010915.xml` | any name ending in `xml`, example `testpayroll123.xml` |
`projectInfo` fields | Contract Agency and Project ID are mandatory and "All other fields must be empty" | "the only mandatory field for eCPR submission is Project ID" |
Fringe benefits | not addressed | hourly amounts for fringes, lump sum for deductions |
Day elements | not addressed | "Day id should begin at '1' and then increment for each day included in the payroll" |
The last row is a real conflict. The March 2026 guideline says the number of `day` elements should equal the number of days in the payroll. The schema declares `<xs:element name="day" minOccurs="7" maxOccurs="7">`, which requires exactly seven. The schema is what runs the validation, so a four day file is rejected whatever the guideline says.
DIR has not reconciled the two documents, and the schema comment still reads version 1.3. Follow the March 2026 guideline on fringes, deductions and file naming, and follow the schema on structure. If an upload is rejected and the error is unhelpful, count the `day` elements first.
One more thing worth knowing before anyone uses it as a starting point. DIR's sample file carries `<CPR:forWeekEnding>2015-02-01</CPR:forWeekEnding>` above seven day elements dated 2015-12-01 through 2015-12-07. The schema lets it through, because XML validation checks each element against the schema alone. A template copied from the sample inherits a week ending date unrelated to the days below it, and the record files cleanly with the wrong week on it.
Federal money puts a second certified payroll on the same crew
Federal funding can put the Davis-Bacon clauses at 29 CFR 5.5 alongside the state duty. The rule reaches a covered contract over $2,000 "entered into for the actual construction, alteration and/or repair, including painting and decorating, of a public building or public work, or building or work financed in whole or in part from Federal funds."
Whether a hand crew cutting fuel breaks is doing construction, alteration or repair within that sentence is a coverage question, answered by the funding agency and the Wage and Hour Division and usually settled in the grant agreement. Where the clauses are in, the federal filing is weekly:
The contractor or subcontractor must submit weekly, for each week in which any DBA- or Related Acts-covered work is performed, certified payrolls
The two regimes want opposite things from the same time sheet. California's schema requires the full nine digit social security number in `ssn` and again inside the `name` id attribute. The federal rule forbids it:
full Social Security numbers and last known addresses, telephone numbers, and email addresses must not be included on weekly transmittals. Instead, the certified payrolls need only include an individually identifying number for each worker (e.g., the last four digits of the worker's Social Security number).
Three other differences matter on a contract:
Form. Optional Form WH-347 satisfies the federal Statement of Compliance, and so does any other format carrying the same information. The federal rule prescribes no schema, and leaves each agency or prime to decide whether to permit or require an electronic system with a legally valid electronic signature.
Who is responsible. 29 CFR 5.5(a)(3)(ii)(A) states that "The prime contractor is responsible for the submission of all certified payrolls by all subcontractors." California runs the other way, with penalties accruing only to the party that failed.
Retention. The federal rule requires certified payrolls to be preserved for three years after all work on the prime contract is completed, and the signature to be an original handwritten one or a legally valid electronic signature.
A crew on a covered federally assisted job therefore produces two certified payrolls from one set of hours: a weekly transmittal carrying an identifying number for each worker, and an XML file carrying nine digits, filed at least every 30 days.
Where this lands on a contract
Five things belong in the document rather than in the first compliance review.
Frequency. Section 1771.4 sets a floor of 30 days and lets the contract go tighter. If the awarding body wants weekly, the contract has to say weekly, because the statutory penalty attaches to the statutory clock and a contract silence defaults to monthly.
The Project ID, and who supplies it. The XML requires one, and the number exists only because the awarding body registered the project. Section 1773.3 gives it 30 days from award and no later than the first day workers are employed. A contract that obliges the contractor to file weekly from day one, on a project the agency has yet to register, asks for something the portal will refuse.
The contract agency string. Pick the exact spelling of the Contract With value at the preconstruction meeting and put it in the minutes. One capital letter separates a continuous payroll history from two of them.
Classification. Name the craft determination in the contract as well as the rate. `workClass` is free text, and the only defense against a wrong classification propagating through eight months of filings is that somebody wrote the right one down before the first one went in.
Withholding. Penalties stay with the party that failed, so a prime carrying a sub that skips its filings has neither exposure nor a statutory lever. If the prime wants one, it comes from the subcontract: a right to withhold progress payments against a missing eCPR, with the flow-down clauses that make the sub's obligation to the Labor Commissioner an obligation to the prime as well.
Further reading
DIR prevailing wage on public works vegetation contracts: The determination that sets the rate the payroll record has to show, and the classification that goes in the workClass element.
Public works contractor registration with the DIR: The ten digit registration number the contractorPWCR element wants, and the $15,000 maintenance line below which none of this applies.
Flow-down clauses in a vegetation subcontract: What a prime can and cannot make a subcontractor promise about payroll records it has no penalty exposure for.
Frequently asked questions
Can a subcontractor file its certified payroll through the prime contractor?
No. DIR's public works FAQ states that each contractor and subcontractor must submit certified payroll records directly to the Labor Commissioner, and that submitting certified payroll records to other agencies does not fulfill that requirement. A five person hand crew working under a prime files its own eCPR, under its own registration number, for every week it works. Records sent to the prime, to a union, to the awarding body or to a Labor Compliance Program are separate obligations that sit on top of the one owed to the Labor Commissioner.
What happens if the awarding body never registered the project?
The filing cannot be made, because the XML file has to carry a DIR Project ID for a registered project and the schema requires it. DIR's guidance is to contact the awarding body and ask it to complete the registration, then to contact DIR at publicworks@dir.ca.gov if it still has not. Labor Code section 1773.3 already obliges the awarding body to give notice within 30 days of the award and no later than the first day workers are employed, so a missing Project ID in week two is an awarding body failure, not a contractor one. Document the request in writing on the day you find out.
Does an electronic certified payroll record satisfy a trust fund's request for payroll?
No. Labor Code section 1776(e)(2), as amended effective January 1, 2026, states that copies of electronic certified payroll records shall not satisfy payroll records requests made by Taft-Hartley trust funds and joint labor-management committees, and that records furnished to them shall be on forms provided by the Division of Labor Standards Enforcement or contain the same information. A contractor filing eCPRs still has to produce a separate record on the A-1-131 form or its equivalent when a trust fund asks.
How many workers fit in one XML file?
Five hundred. The employee element in CPR.xsd carries minOccurs of 0 and maxOccurs of 500, so one file covers up to 500 workers for one project, one contract relationship and one week ending date. The limit that bites first is not the worker count. It is the one file per project per week structure: a crew that worked three DIR registered projects in the same week produces three files, each with its own Project ID and its own signature.



