W-2 parsing API: map box-level JSON to your application

A real W-2 is a single page split into lettered identifier boxes and numbered data boxes. Here is what each region contains and how to read it.

What a W-2 looks like

W-2 — sample layoutannotated
Boxes a–f (identifiers)
Your SSN, the employer’s EIN, and both names and addresses. Box d is an optional payroll control number.
Box 1 — Wages, tips, other compensation
Your taxable wages for federal income tax. This is often lower than your gross pay because pre-tax 401(k) and health-insurance contributions are removed.
Box 2 — Federal income tax withheld
The total federal income tax your employer already sent to the IRS on your behalf.
Boxes 3 & 4 — Social Security wages / tax
Wages subject to Social Security (capped at the annual wage base) and the 6.2% tax withheld on them.
Boxes 5 & 6 — Medicare wages / tax
Wages subject to Medicare (no cap) and the 1.45% tax withheld, plus any additional 0.9% on high earners.
Box 12 — Coded amounts
Letter codes for specific items: D = 401(k) contributions, DD = cost of employer health coverage, W = HSA contributions, and more.
Box 13 — Checkboxes
Flags for statutory employee, participation in a retirement plan, and third-party sick pay.
Boxes 15–17 — State
The state, the employer’s state ID number, state wages, and state income tax withheld. A W-2 can list several states.
Boxes 18–20 — Local
Local wages, local income tax, and the locality name for city or county taxes.

Illustrative layout for education. A real w-2 may vary by issuer.

Evaluate this workflow

For developers integrating a w-2 endpoint

Establish a stable mapping between returned field keys and your internal schema.

Check before you accept a record

  • Use box1_wages and box2_federal_tax rather than guessing display-label keys.
  • Treat null, zero, and an absent key as different states.
  • Keep the source file reference with your own application record.

An exception to hold for review

If a required field is null or listed in needsReview, retain the response for review instead of substituting zero.

Run a small evaluation

  1. POST a representative W-2 with an API key.
  2. Validate the response shape, warnings, and required fields in your code.
  3. Test the mapping on your form years and state layouts before expanding.

Record the number of files submitted, failed files, required-field corrections, and minutes spent reviewing each file. Those observations tell you whether this workflow fits your documents; a sample response does not measure extraction accuracy.

Example reviewed September 16, 2026 against the configured field names. Fictional values, partial field set, and a suggested human workflow; not a recorded extraction or a promise of automatic approval.

A measured synthetic extraction

On September 16, 2026 Pacific time, we sent one labeled text PDF for this document type to our production extraction service. It returned HTTP 200 in 4.90 seconds, including network time. This was a backend request, not a test of signup, payment or the complete upload interface.

1 selected field comparison differed after the production field mapping. Successful delivery does not establish extraction accuracy.

Inspect the field differences
[
  {
    "path": "tax_year",
    "expected": 2025,
    "actual": "2025",
    "actualMissing": false
  }
]

Expected values were fixed before the run. Comparison uses exact values and types, checks the expected object fields and requires exact array lengths. A numeric string differs from a number; missing and null values differ. These easy, clearly labeled synthetic pages do not represent scanned documents, complex official forms or customer accuracy. One observation cannot establish typical latency.

Field contract correction

We replayed the same recorded response after correcting field aliases, declared tax-number types and bank last-four handling. This is an offline replay, not another extraction request. 0 selected field comparisons still differ from the original expected sample. The original benchmark stays available; unsupported distinctions and source wording are not invented to make the comparison pass.

Inspect the corrected mapping results

Download the 15-page synthetic input packetDownload expected and returned fields

Illustrative structured output

These synthetic values explain the field layout; they are not a measured extraction result or an accuracy benchmark. Actual coverage depends on your document.

{
  "tax_year": 2025,
  "employer_name": "Example Workshop (fictional)",
  "employee_name": "Sample Employee",
  "employee_ssn_last4": "0000",
  "box1_wages": 58000,
  "box2_federal_tax": 6500,
  "state_wages": 58000,
  "state_tax": 2400
}

Try the interactive sample without signupReview CSV, Excel, and JSON exportsSee the extraction API

Extract from your own w-2 — 3 free, no credit card

Want the W-2 extraction guide?

Get a free step-by-step guide to extracting and reviewing data from W-2s — plus tips for recurring workflows.

Free. No credit card. Unsubscribe anytime.

FAQ

What does a W-2 look like?

A real W-2 is a single page split into lettered identifier boxes and numbered data boxes. Here is what each region contains and how to read it. The annotated example above shows each region and what it contains.

Can I use this W-2 sample as a template?

Use it to understand the layout and fields. When you need the actual data off a real w-2, upload it and get structured JSON/CSV back — no manual typing.

When should I receive my W-2?

Employers must furnish W-2s by January 31. If you have not received it by mid-February, contact your employer or payroll department.

Why is Box 1 different from my salary?

Box 1 shows federal taxable wages. Pre-tax contributions (401(k), health premiums, HSA) reduce it below your gross salary, which is why the numbers differ.

This page shows an illustrative W-2 example for educational purposes and is not tax, legal, or financial advice.

W-2 parsing API: map box-level JSON to your application | W-2 Parser