Forms / IRS
Fill Form W-4 programmatically
Form W-4 — Employee's Withholding Certificate. Official IRS PDF, 5 pages, 48 fields read automatically.
Every US hire starts with a W-4, and every HR platform re-solves the same problem: the employee already typed their details into your onboarding flow, and now someone — or something — has to get those answers onto the IRS's PDF. Hand the employee the blank form and you get typos and a scanning step; rebuild the form in your own UI and you own keeping it faithful to each year's revision.
What you send
Real field names, straight from the PDF — the excerpt shows the first 5 of 48. The full list is in the table below, and the template hands you the complete JSON schema to copy.
{
"data": {
"topmostSubform[0].Page1[0].Step1a[0].f1_01[0]": "string",
"topmostSubform[0].Page1[0].Step1a[0].f1_02[0]": "string",
"topmostSubform[0].Page1[0].Step1a[0].f1_03[0]": "string",
"topmostSubform[0].Page1[0].Step1a[0].f1_04[0]": "string",
"topmostSubform[0].Page1[0].f1_05[0]": "string"
}
}
// …plus 43 more fields, all listed belowWhat you get back
The completed Form W-4, streamed back as the response — or delivered to your webhook, HMAC-signed.
curl -X POST https://www.doc2api.co/api/v1/templates/<ID>/fill \ -H "X-Api-Key: d2a_live_…" \ -H "Content-Type: application/json" \ -d @payload.json -o filled.pdf # → the completed Form W-4 as a PDF. # With a webhook configured, the reply is JSON and the # document arrives at your endpoint as a signed URL.
Or skip the mapping entirely: embed the actual form on your site and let the person it belongs to fill and sign it — you receive the values as JSON and the finished PDF.
Every field on Form W-4
Extracted automatically from the official PDF — this table is generated by the same code that reads your uploads. In the editor, each of these is highlighted on the page itself, so you never map a name blind.
| Field name | Type | Notes |
|---|---|---|
| topmostSubform[0].Page1[0].Step1a[0].f1_01[0] | text | |
| topmostSubform[0].Page1[0].Step1a[0].f1_02[0] | text | |
| topmostSubform[0].Page1[0].Step1a[0].f1_03[0] | text | |
| topmostSubform[0].Page1[0].Step1a[0].f1_04[0] | text | |
| topmostSubform[0].Page1[0].f1_05[0] | text | max 11 chars |
| topmostSubform[0].Page1[0].c1_1[0] | checkbox | |
| topmostSubform[0].Page1[0].c1_1[1] | checkbox | |
| topmostSubform[0].Page1[0].c1_1[2] | checkbox | |
| topmostSubform[0].Page1[0].c1_2[0] | checkbox | |
| topmostSubform[0].Page1[0].Step3_ReadOrder[0].f1_06[0] | text | |
| topmostSubform[0].Page1[0].Step3_ReadOrder[0].f1_07[0] | text | |
| topmostSubform[0].Page1[0].f1_08[0] | text | |
| topmostSubform[0].Page1[0].f1_09[0] | text | |
| topmostSubform[0].Page1[0].f1_10[0] | text | |
| topmostSubform[0].Page1[0].f1_11[0] | text | |
| topmostSubform[0].Page1[0].c1_3[0] | checkbox | |
| topmostSubform[0].Page1[0].f1_12[0] | text (multiline) | |
| topmostSubform[0].Page1[0].f1_13[0] | text | |
| topmostSubform[0].Page1[0].f1_14[0] | text | max 10 chars |
| topmostSubform[0].Page3[0].f3_01[0] | text | |
| topmostSubform[0].Page3[0].f3_02[0] | text | |
| topmostSubform[0].Page3[0].f3_03[0] | text | |
| topmostSubform[0].Page3[0].f3_04[0] | text | |
| topmostSubform[0].Page3[0].f3_05[0] | text | |
| topmostSubform[0].Page3[0].f3_06[0] | text | |
| topmostSubform[0].Page4[0].f4_01[0] | text | |
| topmostSubform[0].Page4[0].f4_02[0] | text | |
| topmostSubform[0].Page4[0].f4_03[0] | text | |
| topmostSubform[0].Page4[0].f4_04[0] | text | |
| topmostSubform[0].Page4[0].f4_05[0] | text | |
| topmostSubform[0].Page4[0].f4_06[0] | text | |
| topmostSubform[0].Page4[0].f4_07[0] | text | |
| topmostSubform[0].Page4[0].f4_08[0] | text | |
| topmostSubform[0].Page4[0].f4_09[0] | text | |
| topmostSubform[0].Page4[0].f4_10[0] | text | |
| topmostSubform[0].Page4[0].f4_11[0] | text | |
| topmostSubform[0].Page4[0].f4_12[0] | text | |
| topmostSubform[0].Page4[0].f4_13[0] | text | |
| topmostSubform[0].Page4[0].f4_14[0] | text | |
| topmostSubform[0].Page4[0].f4_15[0] | text | |
| topmostSubform[0].Page4[0].f4_16[0] | text | |
| topmostSubform[0].Page4[0].f4_17[0] | text | |
| topmostSubform[0].Page4[0].f4_18[0] | text | |
| topmostSubform[0].Page4[0].f4_19[0] | text | |
| topmostSubform[0].Page4[0].f4_20[0] | text | |
| topmostSubform[0].Page4[0].f4_21[0] | text | |
| topmostSubform[0].Page4[0].f4_22[0] | text | |
| topmostSubform[0].Page4[0].f4_23[0] | text |
Five steps, and most people only fill two
Most employees complete Step 1 and Step 5 and skip the rest — but Steps 2 through 4 still have to be present, empty, and *intentionally* empty. Conditional logic handles this shape well: mark the optional sections' fields as visible only when your payload says they apply, and the server drops hidden fields from the fill rather than printing stray zeros on a federal form.
Questions people ask
- Does a new IRS revision break my integration?
- A revision is a new upload. If the IRS keeps its field names — it usually does between annual revisions — your payload works unchanged; if names change, the schema you copy from the new template tells you exactly what moved.
- Can employees sign it?
- Yes — the embedded form supports draw-to-sign, and the signature is stamped into the PDF itself.
See your Form W-4 pipeline working in the next five minutes
The button uploads the official PDF into the editor as a live template with an API key — no account, nothing to cancel. Trial documents are watermarked and kept for 24 hours; sign up to keep your work.
Doc2api is not affiliated with the Internal Revenue Service. Form W-4 is a public government work; the copy here is the official revision, refreshed from irs.gov. Nothing on this page is tax or legal advice — how a completed form may be signed, filed or retained is defined by the issuing agency.