The 1099 family is where document intake gets messy. A client with a side business, a brokerage account, and a rental property can hand you five different 1099s — NEC, MISC, INT, DIV, and a consolidated brokerage statement — each with different boxes meaning different things. Re-keying them is slow; parsing them with a single generic "1099 template" is how wrong numbers end up on returns.
This guide covers what each common 1099 variant contains, how to structure schemas per variant, and how to inspect the returned data, model-reported confidence map, and validation details.
What the 1099 variants contain
Every 1099 shares a common frame: payer name, address, and TIN; recipient name, address, and TIN; account number; and federal/state withholding boxes. What differs — and what makes a per-variant schema the right design — is the numbered boxes:
- ▪1099-NEC — nonemployee compensation. Box 1 is the headline number (compensation paid to a contractor); Box 4 is federal tax withheld. Since 2020 this replaced 1099-MISC Box 7 for contractor pay.
- ▪1099-MISC — the miscellaneous catch-all: Box 1 rents, Box 2 royalties, Box 3 other income, Box 4 withholding, plus specialty boxes (fishing boat proceeds, crop insurance, legal settlements).
- ▪1099-INT — interest income: Box 1 taxable interest, Box 3 US savings bond/Treasury interest, Box 4 withholding, Box 8 tax-exempt interest.
- ▪1099-DIV — dividends: Box 1a total ordinary dividends, Box 1b qualified dividends, Box 2a total capital gain distributions, Box 4 withholding.
- ▪Consolidated brokerage 1099s — multi-page packets from brokers that bundle INT, DIV, B, and supplemental detail into one statement with the broker’s own layout.
The extraction schema
The highest-accuracy setup is one schema per variant you actually process. Here is a representative 1099-NEC schema — the INT and DIV equivalents swap the box fields:
| Field | Type | Required | Notes |
|---|---|---|---|
| payer_name | string | Yes | |
| payer_tin | string | Yes | EIN or SSN format — validation anchor |
| recipient_name | string | Yes | |
| recipient_tin_last4 | string | No | Forms often show only the last 4 digits |
| tax_year | string | Yes | Printed prominently on every 1099 |
| nonemployee_compensation_box1 | currency | Yes | The headline NEC amount |
| federal_tax_withheld_box4 | currency | No | |
| state_income_box7 | currency | No | |
| state | string | No |
Fixed forms, variable packets
Standalone 1099s are IRS-standardized forms — like W-2s, the box numbering is consistent, which makes them among the more parseable documents in tax intake. Payer software still varies the typography and spacing, and recipient copies often arrive as photos or perforated-page scans, but the field semantics never move.
Consolidated brokerage statements are the opposite case: every brokerage designs its own multi-page layout, mixing summary tables with per-security detail. That is a variable-layout problem, and it is where template-based parsers give up. Schema-first extraction handles it the same way it handles an invoice it has never seen — by mapping content to your named fields — though for very long consolidated statements it is worth splitting your schema into the summary totals you need rather than trying to capture every per-lot detail row.
One operational tip that pays for itself: put tax_year in every 1099 schema. Clients routinely upload last year’s form, and catching that at intake with a cheap field comparison beats catching it at review.
API integration
One schema per variant means one slug per variant — 1099-nec-parser, 1099-int-parser, and so on. Extraction is the same call each time:
Request — POST /api/v1/extract
curl -X POST https://dokyumi.com/api/v1/extract \
-H "Authorization: Bearer dk_live_your_api_key" \
-F "file=@contractor-1099-nec.pdf" \
-F "schema=1099-nec-parser"Response
{
"id": "9bd9c8f3-51d0-4f5a-857a-d2cd92748d65",
"status": "review",
"request_id": "de15e360-0664-402b-a969-61ad58c5cff3",
"schema": "1099-nec-parser",
"data": {
"payer_name": "Foglight Media LLC",
"payer_tin": "47-8812345",
"recipient_name": "J. Alvarez",
"recipient_tin_last4": "6631",
"tax_year": "2025",
"nonemployee_compensation_box1": 41200.00,
"federal_tax_withheld_box4": 0.00,
"state_income_box7": 41200.00,
"state": "CA"
},
"confidence": {
"payer_tin": 0.96,
"nonemployee_compensation_box1": 0.98,
"federal_tax_withheld_box4": 0.64,
"tax_year": 0.99
},
"validation": {
"valid": true,
"errors": [],
"low_confidence_fields": ["federal_tax_withheld_box4"]
},
"meta": {
"processing_time_ms": 980,
"page_count": 1,
"credits_used": 1,
"ocr_cached": false,
"model": "anthropic/claude-sonnet-4"
}
}This example shows one review path: Box 4 was reported below the default 0.8 confidence threshold. For every review result, inspect both validation.errors and validation.low_confidence_fields, and treat a required field missing from the confidence map as review in your workflow.
If you do not know which variant a client uploaded, run a cheap classification pass first (a tiny schema with just form_type and tax_year), then route to the right variant schema — the same pattern described in our document routing guide.
Accuracy, validation, and the empty-box problem
1099s have a quirk that makes review handling especially valuable: most boxes on most forms are legitimately empty. Dokyumi returns a model-reported confidence map that may omit fields plus validation details. Branch on status, inspect both validation arrays, and do not treat missing confidence as approval.
Format checks can also help: TINs have fixed shapes, tax years are four digits within a known range, and currency fields must parse as numbers. Inspect validation errors and apply your own business rules before writing any result downstream.
What it costs
Flat monthly credit tiers — a consolidated statement up to 5 pages uses one credit, and longer statements use another credit for each additional 5-page block:
A firm processing a few hundred contractor 1099s each January fits in Starter at $99 for 500 credits. Multiple variant schemas (NEC, INT, DIV) count against the schema limit, not the credit limit — Starter includes 10 schemas.
- ▪Free — $0/month: 25 extraction credits, 2 schemas. Enough to validate extraction quality on your real documents before paying anything.
- ▪Starter — $99/month: 500 extraction credits, 10 schemas, REST API and webhook delivery.
- ▪Growth — $499/month: 3,000 extraction credits, 50 schemas, 25 white-label upload portals.
- ▪Enterprise — quoted: custom volume, documents beyond the 50-page self-serve limit, unlimited schemas and portals, schemas built for you.
- ▪One credit covers a document of up to 5 pages. A 6–10 page document uses 2 credits, 11–15 uses 3, and so on up to the 50-page self-serve ceiling — no per-page metering and no overage billing.
Full details on the pricing page.