Extracting Income Figures From a 1099-NEC or 1099-MISC
9 min read · updated August 11, 2026
“Extract the data from this 1099” is not a well-formed request. There are more than a dozen forms in the series, each with its own box map, and two of them have swapped a field with each other within the last few years.
There is no such thing as a 1099
The 1099 series is a family of information returns that share a name and a general shape — payer block, recipient block, taxpayer identification numbers, a grid of numbered boxes, state boxes at the bottom — and nothing else. NEC reports nonemployee compensation. MISC reports rents, royalties and a long tail of other payments. INT reports interest, DIV dividends, K payment-card and third-party network transactions, R retirement distributions, B broker transactions, S real estate proceeds. A given box number means something different on each.
So the first extraction step is not reading a value. It is identifying the form: the variant is printed at the top right beside the words “Form 1099-”, the tax year is printed in large type near it, and a revision marker appears in small type at the bottom left of the form face. Read all three before reading a single amount.
NEC box 1 against the MISC boxes
The two forms this page is about are the ones a small business actually receives.
On the 1099-NEC, box 1 is nonemployee compensation — the payment for services that a contractor reports as business income — and box 4 is federal income tax withheld, which is normally zero and is not zero when backup withholding applied. The form also carries a checkbox for payers who made direct sales above a threshold for resale, and state boxes at the foot.
On the 1099-MISC, box 1 is rents and box 2 royalties; box 3 is other income, which is the catch-all that ends up on a different line of a return from box 1; box 4 is federal income tax withheld; box 6 is medical and health care payments; and gross proceeds paid to an attorney has its own box distinct from attorney fees for services, which go on the NEC. The higher-numbered boxes cover substitute payments, crop insurance, deferrals and excess parachute payments.
Two of those deserve emphasis because they are where money goes to the wrong line. Box 3 “other income” on the MISC is not self-employment income and does not belong in the same place as NEC box 1. And the attorney distinction is a genuine trap: the same lawyer can receive one of each in one year for different things.
The IRS publishes the definitive box list for each in the shared instructions for these two forms, linked from About Form 1099-NEC and About Form 1099-MISC. Read the caption printed on the form in front of you rather than trusting any box list — including this one — for a form from a year you have not checked.
The boxes moved, and old forms circulate
This is the fact that makes a naive schema wrong rather than merely incomplete. Nonemployee compensation used to be reported in box 7 of the 1099-MISC. For tax year 2020 the IRS reinstated Form 1099-NEC and moved it there, to box 1, and MISC box 7 became a checkbox for direct sales. Later revisions of the MISC have shifted other boxes as content was added.
So a schema that maps “1099-MISC box 7” to a compensation field is correct for forms from before 2020 and badly wrong for everything since — and both circulate, because amended returns, prior-year filings and archived document sets are all real workloads. A number in a checkbox field is not a parse failure your code will notice; it is a plausible dollar amount landing in the wrong concept.
The fix is to treat the box map as versioned data rather than as code:
box_maps = {
("1099-NEC", 2020, None): { "1": "nonemployee_compensation",
"4": "federal_income_tax_withheld" },
("1099-MISC", 2020, None): { "1": "rents", "2": "royalties",
"3": "other_income",
"4": "federal_income_tax_withheld" },
("1099-MISC", None, 2019): { "1": "rents", "2": "royalties",
"3": "other_income",
"7": "nonemployee_compensation" },
}
# keyed on (variant, valid_from_year, valid_to_year); select the map
# from the tax year printed on the form, never from today's date.Selecting on the printed tax year rather than the processing date is the part people get wrong when they finally add versioning, and it fails silently every January.
Tag the variant on every field
Carry the provenance into the output. Every extracted value should know which form variant, which tax year and which box it came from, and — this is the cheap insurance — the caption printed beside that box.
{
"form": "1099-NEC",
"tax_year": 2025,
"revision": "2024-01",
"payer_tin": "XX-XXXXXXX",
"boxes": [
{ "box": "1",
"caption_as_printed": "Nonemployee compensation",
"value": 48250.00,
"semantic": "nonemployee_compensation" }
]
}The stored caption is what lets you recover from a wrong map. When you discover months later that a variant was mapped incorrectly, the caption tells you what each value actually was without re-reading a single document, and it lets you detect the problem in the first place by asserting that the caption you read matches the caption your map expects. That assertion costs nothing per document and catches an entire class of silent versioning failure.
The taxpayer identification numbers deserve a word. They are sensitive personal data on a document you hold for a business purpose. Store them only where you need them, mask them in logs and in anything sent to a model you do not control, and keep them out of any prompt that does not require them — the general handling is covered in PII redaction.
Corrected boxes and which copy you have
Two checkboxes at the top of the form change the meaning of everything below them. A CORRECTED box means this form replaces one already issued, and a pipeline that ignores it will hold both and double the reported income. A VOID box means the form should be disregarded entirely. Both are small marks in a crowded header and both are frequently skipped by an extraction focused on the numbered grid. Extract them first, before the amounts, and let the result decide whether the rest is even processed.
The copy matters too. Copy A is the version filed with the IRS, printed in a dropout red ink designed to be invisible to the scanner, which is why a downloaded and printed Copy A cannot be filed. A recipient receives Copy B and Copy 2, which are black-on-white and laid out slightly differently from the red sample everyone reproduces in documentation. Building against a picture of Copy A and then processing Copy B is a small, avoidable source of positional mismatch, and one more reason to key on printed captions rather than on coordinates.