Registry
Form 941 — programmatic fill compatibility
Employer's Quarterly Federal Tax Return · Internal Revenue Service (IRS) · Rev. March 2026. Tested 2026-08-07 on the unmodified upstream blank — every number below comes from a recorded run, not from documentation.
Verdict at a glance
| Tool | Version | Result | Detail |
|---|---|---|---|
| pdfops API | hosted, tested 2026-08-07 | verified + deterministic flatten | 116/116 supported fields landed; flatten=true byte-deterministic (sha256 2516f34ad02f…) |
| pdf-lib | 1.17.1 | verified (116/116) | 116 fields filled in-process; XFA layer dropped on save |
| @cantoo/pdf-lib (fork) | 2.6.5 | verified (116/116) | 116 fields filled in-process; XFA layer dropped on save |
| pypdf | 6.15.0 | text fields verified (92/92) | 92 text fields written and re-read (text fields only) |
| pdftk-java | 3.3.3 | verified (116/116) | 116 fields filled via FDF and re-dumped |
| qpdf --check | 11.9.0 | structurally clean | errors that qpdf cannot detect |
| poppler render check | 24.02.0 | values render (92/92) | 92/92 filled text values present in pdftotext output of the pdf-lib-filled file; page-1 raster sha256 3d58635c7a8a… |
File facts
- Source: https://www.irs.gov/pub/irs-pdf/f941.pdf (issuer page: here)
- Blank tested: irs-f941.pdf · 822 KB · sha256
38a3d8cf7a455101d52543c8c48e66202bc25c189ead878627e35c797c88e2ad - License: US federal government work — public domain (17 U.S.C. § 105). The hash-verified blank is redistributed here unmodified.
- Structure: 3 pages · AcroForm + XFA layer (hybrid)
- Fields: 116 (92 text, 24 checkbox)
Quirks & limitations
- Filed four times a year by nearly every US employer, which makes it one of the most automated forms in existence.
- Dollar-and-cents amounts are split into separate whole/cents fields in places; fillers that format currency as a single string need a mapping layer.
Tested request
This exact shape ran against the live API during the recorded test (values here shortened to two fields; the test filled all 116 supported fields). With flatten=true, two identical runs produced byte-identical output — sha256 2516f34ad02f45ebc33a8bdbc0e35133f12a522c564a289d612772d0a3c48f52.
curl -X POST https://pdfops.dev/api/fill-form \
-F "pdf=@irs-f941.pdf" \
-F 'fields={"topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_1[0]":"PD","topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_2[0]":"PDFops"}' \
-F "flatten=true" \
-o filled.pdf
Enumerate all 116 field names first with the inspector or POST /api/inspect.
Field schema
All 116 fields (name, type, maxLength, options)
| Field name | Type | maxLength | Options |
|---|---|---|---|
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_1[0] | TextField | 2 | |
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_2[0] | TextField | 7 | |
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_3[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_4[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_5[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_6[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_7[0] | TextField | 2 | |
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_8[0] | TextField | 10 | |
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_9[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_10[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].EntityArea[0].f1_11[0] | TextField | ||
topmostSubform[0].Page1[0].Header[0].ReportForQuarter[0].c1_1[0] | CheckBox | ||
topmostSubform[0].Page1[0].Header[0].ReportForQuarter[0].c1_1[1] | CheckBox | ||
topmostSubform[0].Page1[0].Header[0].ReportForQuarter[0].c1_1[2] | CheckBox | ||
topmostSubform[0].Page1[0].Header[0].ReportForQuarter[0].c1_1[3] | CheckBox | ||
topmostSubform[0].Page1[0].Header[0].AggregateReturn[0].c1_2[0] | CheckBox | ||
topmostSubform[0].Page1[0].Header[0].AggregateReturn[0].c1_2[1] | CheckBox | ||
topmostSubform[0].Page1[0].Header[0].AggregateReturn[0].c1_2[2] | CheckBox | ||
topmostSubform[0].Page1[0].f1_12[0] | TextField | ||
topmostSubform[0].Page1[0].f1_13[0] | TextField | ||
topmostSubform[0].Page1[0].f1_14[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_15[0] | TextField | ||
topmostSubform[0].Page1[0].f1_16[0] | TextField | 3 | |
topmostSubform[0].Page1[0].c1_3[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_17[0] | TextField | ||
topmostSubform[0].Page1[0].f1_18[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_19[0] | TextField | ||
topmostSubform[0].Page1[0].f1_20[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_21[0] | TextField | ||
topmostSubform[0].Page1[0].f1_22[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_23[0] | TextField | ||
topmostSubform[0].Page1[0].f1_24[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_25[0] | TextField | ||
topmostSubform[0].Page1[0].f1_26[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_27[0] | TextField | ||
topmostSubform[0].Page1[0].f1_28[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_29[0] | TextField | ||
topmostSubform[0].Page1[0].f1_30[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_31[0] | TextField | ||
topmostSubform[0].Page1[0].f1_32[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_33[0] | TextField | ||
topmostSubform[0].Page1[0].f1_34[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_35[0] | TextField | ||
topmostSubform[0].Page1[0].f1_36[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_37[0] | TextField | ||
topmostSubform[0].Page1[0].f1_38[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_39[0] | TextField | ||
topmostSubform[0].Page1[0].f1_40[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_41[0] | TextField | ||
topmostSubform[0].Page1[0].f1_42[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_43[0] | TextField | ||
topmostSubform[0].Page1[0].f1_44[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_45[0] | TextField | ||
topmostSubform[0].Page1[0].f1_46[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_47[0] | TextField | ||
topmostSubform[0].Page1[0].f1_48[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_49[0] | TextField | ||
topmostSubform[0].Page1[0].f1_50[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_51[0] | TextField | ||
topmostSubform[0].Page1[0].f1_52[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_53[0] | TextField | ||
topmostSubform[0].Page1[0].f1_54[0] | TextField | 3 | |
topmostSubform[0].Page1[0].f1_55[0] | TextField | ||
topmostSubform[0].Page1[0].f1_56[0] | TextField | 3 | |
topmostSubform[0].Page1[0].c1_4[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_4[1] | CheckBox | ||
topmostSubform[0].Page1[0].RoutingNo[0].f1_57[0] | TextField | 9 | |
topmostSubform[0].Page1[0].c1_5[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_5[1] | CheckBox | ||
topmostSubform[0].Page1[0].AccountNo[0].f1_58[0] | TextField | 17 | |
topmostSubform[0].Page2[0].Name_ReadOrder[0].f1_3[0] | TextField | ||
topmostSubform[0].Page2[0].EIN_Number[0].f1_1[0] | TextField | 2 | |
topmostSubform[0].Page2[0].EIN_Number[0].f1_2[0] | TextField | 7 | |
topmostSubform[0].Page2[0].c2_1[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_1[1] | CheckBox | ||
topmostSubform[0].Page2[0].f2_1[0] | TextField | ||
topmostSubform[0].Page2[0].f2_2[0] | TextField | 3 | |
topmostSubform[0].Page2[0].f2_3[0] | TextField | ||
topmostSubform[0].Page2[0].f2_4[0] | TextField | 3 | |
topmostSubform[0].Page2[0].f2_5[0] | TextField | ||
topmostSubform[0].Page2[0].f2_6[0] | TextField | 3 | |
topmostSubform[0].Page2[0].f2_7[0] | TextField | ||
topmostSubform[0].Page2[0].f2_8[0] | TextField | 3 | |
topmostSubform[0].Page2[0].c2_1[2] | CheckBox | ||
topmostSubform[0].Page2[0].c2_2[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_9[0] | TextField | 8 | |
topmostSubform[0].Page2[0].c2_3[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_4[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_10[0] | TextField | ||
topmostSubform[0].Page2[0].f2_11[0] | TextField | ||
topmostSubform[0].Page2[0].f2_12[0] | TextField | 5 | |
topmostSubform[0].Page2[0].c2_4[1] | CheckBox | ||
topmostSubform[0].Page2[0].f2_13[0] | TextField | ||
topmostSubform[0].Page2[0].f2_14[0] | TextField | ||
topmostSubform[0].Page2[0].f2_15[0] | TextField | ||
topmostSubform[0].Page2[0].c2_5[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_16[0] | TextField | ||
topmostSubform[0].Page2[0].f2_17[0] | TextField | 11 | |
topmostSubform[0].Page2[0].f2_18[0] | TextField | ||
topmostSubform[0].Page2[0].f2_19[0] | TextField | 10 | |
topmostSubform[0].Page2[0].f2_20[0] | TextField | ||
topmostSubform[0].Page2[0].f2_21[0] | TextField | ||
topmostSubform[0].Page2[0].f2_22[0] | TextField | ||
topmostSubform[0].Page2[0].f2_23[0] | TextField | 2 | |
topmostSubform[0].Page2[0].f2_24[0] | TextField | 10 | |
topmostSubform[0].Page3[0].EIN_Number[0].f1_1[0] | TextField | 2 | |
topmostSubform[0].Page3[0].EIN_Number[0].f1_2[0] | TextField | 7 | |
topmostSubform[0].Page3[0].f4_2[0] | TextField | ||
topmostSubform[0].Page3[0].f4_3[0] | TextField | 3 | |
topmostSubform[0].Page3[0].Line3_ReadOrder[0].c4_1[0] | CheckBox | ||
topmostSubform[0].Page3[0].Line3_ReadOrder[0].c4_1[1] | CheckBox | ||
topmostSubform[0].Page3[0].Line3_ReadOrder[0].c4_1[2] | CheckBox | ||
topmostSubform[0].Page3[0].Line3_ReadOrder[0].c4_1[3] | CheckBox | ||
topmostSubform[0].Page3[0].f1_3[0] | TextField | ||
topmostSubform[0].Page3[0].f4_5[0] | TextField | ||
topmostSubform[0].Page3[0].f4_6[0] | TextField |
Frequently asked
Can I fill the Form 941 programmatically?
Yes — the blank Rev. March 2026 Form 941 is a fillable AcroForm with 116 fields. In our tested run, all 116 supported fields were filled through the pdfops API and verified by re-inspecting the output; upstream pdf-lib also round-trips it, and pypdf handled its text fields. Field names are positional (e.g. topmostSubform[0].Page1[0].f1_01[0]) — enumerate them via inspection rather than guessing.
Is the Form 941 an XFA form?
It is a hybrid: the PDF carries both a standard AcroForm field tree and an XFA layer. Programmatic fillers in the pdf-lib family fill the AcroForm layer and drop the XFA layer on save, so the output is a plain AcroForm PDF — which every mainstream viewer renders. Only XFA-first viewers (older Adobe products) behave differently.
← All forms in the registry · Inspect your own PDF · Make a flat PDF fillable