Registry
IRS Form 1040 — programmatic fill compatibility
U.S. Individual Income Tax Return · Internal Revenue Service (IRS) · 2025 tax year. Tested 2026-08-06 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-06 | verified + deterministic flatten | 199/199 supported fields landed; flatten=true byte-deterministic (sha256 294cf3d8659b…) |
| pdf-lib | 1.17.1 | verified (199/199) | 199 fields filled in-process; XFA layer dropped on save |
| @cantoo/pdf-lib (fork) | 2.6.5 | verified (199/199) | 199 fields filled in-process; XFA layer dropped on save |
| pypdf | 6.15.0 | text fields verified (126/126) | 126 text fields written and re-read (text fields only) |
| pdftk-java | 3.3.3 | verified (199/199) | 199 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 (126/126) | 126/126 filled text values present in pdftotext output of the pdf-lib-filled file; page-1 raster sha256 f67b561b0b10… |
File facts
- Source: https://www.irs.gov/pub/irs-pdf/f1040.pdf (issuer page: here)
- Blank tested: irs-f1040.pdf · 215 KB · sha256
3d31c226df0d189ced80e039d01cf0f8820c1019681a0f0ca6264de277b7e982 - License: US federal government work — public domain (17 U.S.C. § 105). The hash-verified blank is redistributed here unmodified.
- Structure: 2 pages · AcroForm + XFA layer (hybrid)
- Fields: 199 (126 text, 73 checkbox)
Quirks & limitations
- The stress test of this corpus: ~200 fields on 2 pages, including split character-box fields with maxLength as low as 2. Any filler that synthesizes values without honoring maxLength gets a hard reject — the pdfops API returns a 400 naming the exact offending field rather than silently truncating.
- Re-issued every tax year at the same URL — pin by hash, not URL.
- Hybrid AcroForm/XFA, same fill-then-drop-XFA behavior as the other IRS forms.
- Several dollar-amount lines are text fields with no numeric format enforcement at the AcroForm level; validation lives in the form's JavaScript, which non-Adobe fillers do not execute. Validate amounts in your own 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 199 supported fields). With flatten=true, two identical runs produced byte-identical output — sha256 294cf3d8659be52d36c571b2086e2bc01139a0df649461211e30fc50e051c1c2.
curl -X POST https://pdfops.dev/api/fill-form \
-F "pdf=@irs-f1040.pdf" \
-F 'fields={"topmostSubform[0].Page1[0].f1_01[0]":"Jane Doe","topmostSubform[0].Page1[0].f1_02[0]":"Jane Doe"}' \
-F "flatten=true" \
-o filled.pdf
Enumerate all 199 field names first with the inspector or POST /api/inspect.
Field schema
All 199 fields (name, type, maxLength, options)
| Field name | Type | maxLength | Options |
|---|---|---|---|
topmostSubform[0].Page1[0].f1_01[0] | TextField | ||
topmostSubform[0].Page1[0].f1_02[0] | TextField | ||
topmostSubform[0].Page1[0].f1_03[0] | TextField | 2 | |
topmostSubform[0].Page1[0].c1_1[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_2[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_04[0] | TextField | ||
topmostSubform[0].Page1[0].c1_3[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_05[0] | TextField | 2 | |
topmostSubform[0].Page1[0].f1_06[0] | TextField | 2 | |
topmostSubform[0].Page1[0].f1_07[0] | TextField | 4 | |
topmostSubform[0].Page1[0].f1_08[0] | TextField | 2 | |
topmostSubform[0].Page1[0].f1_09[0] | TextField | 2 | |
topmostSubform[0].Page1[0].f1_10[0] | TextField | 4 | |
topmostSubform[0].Page1[0].c1_4[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_11[0] | TextField | ||
topmostSubform[0].Page1[0].f1_12[0] | TextField | ||
topmostSubform[0].Page1[0].f1_13[0] | TextField | ||
topmostSubform[0].Page1[0].f1_14[0] | TextField | ||
topmostSubform[0].Page1[0].f1_15[0] | TextField | ||
topmostSubform[0].Page1[0].f1_16[0] | TextField | 9 | |
topmostSubform[0].Page1[0].f1_17[0] | TextField | ||
topmostSubform[0].Page1[0].f1_18[0] | TextField | ||
topmostSubform[0].Page1[0].f1_19[0] | TextField | 9 | |
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_20[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_21[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_22[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_23[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_24[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_25[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_26[0] | TextField | ||
topmostSubform[0].Page1[0].Address_ReadOrder[0].f1_27[0] | TextField | ||
topmostSubform[0].Page1[0].c1_5[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_6[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_7[0] | CheckBox | ||
topmostSubform[0].Page1[0].Checkbox_ReadOrder[0].c1_8[0] | CheckBox | ||
topmostSubform[0].Page1[0].Checkbox_ReadOrder[0].c1_8[1] | CheckBox | ||
topmostSubform[0].Page1[0].Checkbox_ReadOrder[0].c1_8[2] | CheckBox | ||
topmostSubform[0].Page1[0].Checkbox_ReadOrder[0].f1_28[0] | TextField | ||
topmostSubform[0].Page1[0].c1_8[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_8[1] | CheckBox | ||
topmostSubform[0].Page1[0].f1_29[0] | TextField | ||
topmostSubform[0].Page1[0].c1_9[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_30[0] | TextField | ||
topmostSubform[0].Page1[0].c1_10[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_10[1] | CheckBox | ||
topmostSubform[0].Page1[0].Dependents_ReadOrder[0].c1_11[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row1[0].f1_31[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row1[0].f1_32[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row1[0].f1_33[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row1[0].f1_34[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row2[0].f1_35[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row2[0].f1_36[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row2[0].f1_37[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row2[0].f1_38[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row3[0].f1_39[0] | TextField | 9 | |
topmostSubform[0].Page1[0].Table_Dependents[0].Row3[0].f1_40[0] | TextField | 9 | |
topmostSubform[0].Page1[0].Table_Dependents[0].Row3[0].f1_41[0] | TextField | 9 | |
topmostSubform[0].Page1[0].Table_Dependents[0].Row3[0].f1_42[0] | TextField | 9 | |
topmostSubform[0].Page1[0].Table_Dependents[0].Row4[0].f1_43[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row4[0].f1_44[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row4[0].f1_45[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row4[0].f1_46[0] | TextField | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent1[0].c1_12[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent1[0].c1_13[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent2[0].c1_14[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent2[0].c1_15[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent3[0].c1_16[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent3[0].c1_17[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent4[0].c1_18[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row5[0].Dependent4[0].c1_19[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent1[0].c1_20[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent1[0].c1_21[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent2[0].c1_22[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent2[0].c1_23[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent3[0].c1_24[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent3[0].c1_25[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent4[0].c1_26[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row6[0].Dependent4[0].c1_27[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent1[0].c1_28[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent1[0].c1_28[1] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent2[0].c1_29[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent2[0].c1_29[1] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent3[0].c1_30[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent3[0].c1_30[1] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent4[0].c1_31[0] | CheckBox | ||
topmostSubform[0].Page1[0].Table_Dependents[0].Row7[0].Dependent4[0].c1_31[1] | CheckBox | ||
topmostSubform[0].Page1[0].c1_32[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_47[0] | TextField | ||
topmostSubform[0].Page1[0].f1_48[0] | TextField | ||
topmostSubform[0].Page1[0].f1_49[0] | TextField | ||
topmostSubform[0].Page1[0].f1_50[0] | TextField | ||
topmostSubform[0].Page1[0].f1_51[0] | TextField | ||
topmostSubform[0].Page1[0].f1_52[0] | TextField | ||
topmostSubform[0].Page1[0].f1_53[0] | TextField | ||
topmostSubform[0].Page1[0].f1_54[0] | TextField | ||
topmostSubform[0].Page1[0].f1_55[0] | TextField | ||
topmostSubform[0].Page1[0].f1_56[0] | TextField | ||
topmostSubform[0].Page1[0].f1_57[0] | TextField | ||
topmostSubform[0].Page1[0].f1_58[0] | TextField | ||
topmostSubform[0].Page1[0].f1_59[0] | TextField | ||
topmostSubform[0].Page1[0].f1_60[0] | TextField | ||
topmostSubform[0].Page1[0].f1_61[0] | TextField | ||
topmostSubform[0].Page1[0].c1_33[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_34[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_62[0] | TextField | ||
topmostSubform[0].Page1[0].f1_63[0] | TextField | ||
topmostSubform[0].Page1[0].c1_35[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_36[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_37[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_64[0] | TextField | ||
topmostSubform[0].Page1[0].f1_65[0] | TextField | ||
topmostSubform[0].Page1[0].f1_66[0] | TextField | ||
topmostSubform[0].Page1[0].c1_38[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_39[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_40[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_67[0] | TextField | ||
topmostSubform[0].Page1[0].f1_68[0] | TextField | ||
topmostSubform[0].Page1[0].f1_69[0] | TextField | ||
topmostSubform[0].Page1[0].c1_41[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_42[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_70[0] | TextField | ||
topmostSubform[0].Page1[0].c1_43[0] | CheckBox | ||
topmostSubform[0].Page1[0].c1_44[0] | CheckBox | ||
topmostSubform[0].Page1[0].f1_71[0] | TextField | ||
topmostSubform[0].Page1[0].f1_72[0] | TextField | ||
topmostSubform[0].Page1[0].f1_73[0] | TextField | ||
topmostSubform[0].Page1[0].f1_74[0] | TextField | ||
topmostSubform[0].Page1[0].f1_75[0] | TextField | ||
topmostSubform[0].Page2[0].f2_01[0] | TextField | ||
topmostSubform[0].Page2[0].c2_1[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_2[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_3[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_4[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_5[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_6[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_7[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_8[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_02[0] | TextField | ||
topmostSubform[0].Page2[0].f2_03[0] | TextField | ||
topmostSubform[0].Page2[0].f2_04[0] | TextField | ||
topmostSubform[0].Page2[0].f2_05[0] | TextField | ||
topmostSubform[0].Page2[0].f2_06[0] | TextField | ||
topmostSubform[0].Page2[0].c2_9[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_10[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_11[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_07[0] | TextField | ||
topmostSubform[0].Page2[0].f2_08[0] | TextField | ||
topmostSubform[0].Page2[0].f2_09[0] | TextField | ||
topmostSubform[0].Page2[0].f2_10[0] | TextField | ||
topmostSubform[0].Page2[0].f2_11[0] | TextField | ||
topmostSubform[0].Page2[0].f2_12[0] | TextField | ||
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].f2_16[0] | TextField | ||
topmostSubform[0].Page2[0].f2_17[0] | TextField | ||
topmostSubform[0].Page2[0].f2_18[0] | TextField | ||
topmostSubform[0].Page2[0].f2_19[0] | TextField | ||
topmostSubform[0].Page2[0].f2_20[0] | TextField | ||
topmostSubform[0].Page2[0].f2_21[0] | TextField | ||
topmostSubform[0].Page2[0].SSN_ReadOrder[0].f2_22[0] | TextField | 9 | |
topmostSubform[0].Page2[0].f2_23[0] | TextField | ||
topmostSubform[0].Page2[0].c2_12[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_13[0] | CheckBox | ||
topmostSubform[0].Page2[0].Line28_ReadOrder[0].c2_14[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_24[0] | TextField | ||
topmostSubform[0].Page2[0].f2_25[0] | TextField | ||
topmostSubform[0].Page2[0].f2_26[0] | TextField | ||
topmostSubform[0].Page2[0].f2_27[0] | TextField | ||
topmostSubform[0].Page2[0].f2_28[0] | TextField | ||
topmostSubform[0].Page2[0].f2_29[0] | TextField | ||
topmostSubform[0].Page2[0].f2_30[0] | TextField | ||
topmostSubform[0].Page2[0].c2_15[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_31[0] | TextField | ||
topmostSubform[0].Page2[0].RoutingNo[0].f2_32[0] | TextField | 9 | |
topmostSubform[0].Page2[0].c2_16[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_16[1] | CheckBox | ||
topmostSubform[0].Page2[0].AccountNo[0].f2_33[0] | TextField | 17 | |
topmostSubform[0].Page2[0].f2_34[0] | TextField | ||
topmostSubform[0].Page2[0].f2_35[0] | TextField | ||
topmostSubform[0].Page2[0].f2_36[0] | TextField | ||
topmostSubform[0].Page2[0].c2_17[0] | CheckBox | ||
topmostSubform[0].Page2[0].c2_17[1] | CheckBox | ||
topmostSubform[0].Page2[0].f2_37[0] | TextField | ||
topmostSubform[0].Page2[0].f2_38[0] | TextField | ||
topmostSubform[0].Page2[0].f2_39[0] | TextField | 5 | |
topmostSubform[0].Page2[0].f2_40[0] | TextField | ||
topmostSubform[0].Page2[0].f2_41[0] | TextField | 6 | |
topmostSubform[0].Page2[0].f2_42[0] | TextField | ||
topmostSubform[0].Page2[0].f2_43[0] | TextField | 6 | |
topmostSubform[0].Page2[0].f2_44[0] | TextField | ||
topmostSubform[0].Page2[0].f2_45[0] | TextField | ||
topmostSubform[0].Page2[0].f2_46[0] | TextField | ||
topmostSubform[0].Page2[0].f2_47[0] | TextField | 11 | |
topmostSubform[0].Page2[0].c2_18[0] | CheckBox | ||
topmostSubform[0].Page2[0].f2_48[0] | TextField | ||
topmostSubform[0].Page2[0].f2_49[0] | TextField | ||
topmostSubform[0].Page2[0].f2_50[0] | TextField | ||
topmostSubform[0].Page2[0].f2_51[0] | TextField | 10 |
Frequently asked
Can I fill the IRS Form 1040 programmatically?
Yes — the blank 2025 tax year IRS Form 1040 is a fillable AcroForm with 199 fields. In our tested run, all 199 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 IRS Form 1040 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