QuantCalc QuantCalc State tax engine docs

State tax docs / Calculation order

How the state tax engine computes a year of tax

Every step the engine takes, in the order it takes them, from the API request to the final tax. Each step names the code that performs it, the configuration and inputs it reads, the jurisdictions it applies to, and where its sources are. The state pages walk the same steps for one jurisdiction with its own figures (States). Engine version 1.5.0, tax year 2026.

This page is generated from the engine's calculation registry (research/data/state-tax-calc-registry.json). A build gate reads the engine source and fails when a function, a marked step, a configuration field or an input the engine reads is not in the registry, when a step has no source or is missing from this page or a state page, or when a line reference here is out of date.

The pipeline in brief

  1. Parse and check the request; map it onto the engine input (request handling).
  2. Pick the jurisdiction, the filing status's rate schedule and deduction (configuration).
  3. Form the income total the income tests use, nest the income subsets, attribute income to each spouse (income).
  4. Take out what the state excludes: military pay, public and employer pensions, Social Security, retirement income, conversions, gains (exclusions).
  5. Subtract the standard deduction, exemptions and age subtractions, and any federal-tax deduction (deductions, taxable income).
  6. Apply the rate schedule and the state's recapture, gains rates and minimum tax (tax).
  7. Subtract nonrefundable credits, floored at zero (credits).
  8. Add the county tax, capital-gains surcharge and surtax (after credits).

Request handling (API and library entry point)

Three stages: parse, evaluate, respond

The JSON body is parsed (type checks only), then evaluated (value checks, mapping onto the engine input, the engine call), then turned into the response. A typed caller can enter at the second stage with the same checks. A body that is not JSON returns 400 before any of this.

Code: state_tax_json_handle, state_tax_json_eval at backend/src/state_tax_json.c:703 (marker CALC-STEP: api-pipeline).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

State code

state (or state_code) must be a non-empty string. A code longer than seven characters is read as unknown. The lookup is case-insensitive.

Code: state_tax_json_parse, jstr at backend/src/state_tax_json.c:178 (marker CALC-STEP: api-parse-state).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Filing status

filingStatus (or filing_status): absent or null means single; otherwise one of seven case-insensitive strings. A non-string or any other value is refused with 400. The response echoes the status as single, mfj, mfs or hoh.

Code: parse_filing_status, filing_status_name at backend/src/state_tax_json.c:26 (marker CALC-STEP: api-filing-status).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

The four original fields

ordinaryIncome, socialSecurity and capitalGains are optional numbers and age an optional whole number: absent or null means 0 (not given). Since engine 1.5.0 a value of the wrong type, or an age that is not a whole number, is refused with 400 naming the field, like the newer fields (the first release read a wrong type as 0 and truncated the age); an age outside 0 to 120 keeps its original message.

Code: opt_number at backend/src/state_tax_json.c:211 (marker CALC-STEP: api-legacy-fields).

Applies to: The API and the library entry point. Engine convention, no external source: Backward compatibility with the first API release.

Optional amounts added in 1.1.0

wages, iraDistributions, pensionPrivate, pensionPublic, pensionMilitary, rothConversion, shortTermGains, socialSecurityGross, federalTax and federalNiit: absent or null means not supplied; anything but a number is refused with 400 naming the field. Snake-case spellings are accepted.

Code: opt_number, parse_person_amounts at backend/src/state_tax_json.c:73 (marker CALC-STEP: api-optional-amounts).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Social Security coverage of a public pension

pensionPublicSsCovered must be true or false; absent or null means unknown. Only false reaches the engine (as pension_public_not_ss_covered = 1).

Code: state_tax_json_parse at backend/src/state_tax_json.c:254 (marker CALC-STEP: api-ss-covered).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Blindness and disability

blind and disabled (and spouse.blind, spouse.disabled) must be true or false; absent or null means false. They reach the engine per person: the top-level pair is the primary filer, the spouse pair the spouse on a joint return.

Code: opt_bool at backend/src/state_tax_json.c:270 (marker CALC-STEP: api-blind-disabled).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Spouse object

spouse must be an object whose keys are only age, wages, iraDistributions, pensionPrivate, pensionPublic, pensionMilitary, rothConversion, blind and disabled (or their snake-case forms). spouse.age must be a whole number from 1 to 120.

Code: state_tax_json_parse at backend/src/state_tax_json.c:277 (marker CALC-STEP: api-spouse).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Value checks

In this order: state present, state known, the three original amounts not negative, age 0 to 120, every other amount finite, not negative and at most $100,000,000,000, socialSecurityGross at least socialSecurity when both are given, spouse only with mfj, spouse.age 1 to 120, then the spouse's amounts. The first failure is returned.

Code: state_tax_request_eval at backend/src/state_tax_json.c:333 (marker CALC-STEP: api-validate).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Amount limits

Each amount added in 1.1.0 must be finite, not negative, and at most $100,000,000,000.

Code: check_amount, check_person_amounts at backend/src/state_tax_json.c:89 (marker CALC-STEP: api-amount-checks).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Mapping the request onto the engine input

Other ordinary income = ordinaryIncome + wages + shortTermGains. Retirement distributions = IRA + private pension + public pension + military pay. Pension income = private + public pension. With a spouse object the person amounts are summed for the household and the spouse's own share is passed as the split. federalTax and federalNiit are unknown (no deduction) when absent. The federal-taxable-income inputs are always unknown on the API. An absent spouse.age means the primary filer's age.

Code: state_tax_request_eval at backend/src/state_tax_json.c:387 (marker CALC-STEP: api-map-input). Engine inputs: other_ordinary, wages, short_term_gains, retirement_distributions, pension_income, pension_public, pension_military, roth_conversion, ss_income, ss_gross, capital_gains, age, federal_tax, federal_niit, fed_taxable_ordinary, fed_taxable_ltcg, has_spouse_split, sp2_age, pension_public_not_ss_covered.

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Effective rate

effectiveRate = tax divided by the sum of every income amount supplied (both spouses' amounts included); 0 when that sum is 0.

Code: state_tax_request_eval at backend/src/state_tax_json.c:443 (marker CALC-STEP: api-effective-rate).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Response document

The response carries the state, the tax, the effective rate, the input as read, the rules block, the breakdown, a note, the state's documentation link, the tax year and the engine version.

Code: state_tax_json_response at backend/src/state_tax_json.c:531 (marker CALC-STEP: api-response).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

The rules block

rules reports the state's parameters for the request: Social Security rule, bracket count, standard deduction, personal exemption, senior subtraction, capital-gains treatment, the retirement exclusion, the military and wage rules and the local tax. Since engine 1.5.0 the scalar amounts are the ones the engine uses for the request's filing status (a head-of-household or separate schedule, deduction, exemption or exclusion cap where the state has one; an income-tiered exemption at the request's income total), before age additions, phase-outs and credits.

Code: military_rules_json, wages_rules_json, ss_rule_name, add_amount_or_null at backend/src/state_tax_json.c:463 (marker CALC-STEP: api-response-rules).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Amounts for the filing status

The schedule the filing status uses (its bracket count), its own standard deduction (head of household, separate), its personal exemption (head-of-household amount, or the income tier for the request), the senior subtraction and the retirement exclusion cap (the separate cap where the state sets one), as the calculation selects them.

Code: state_tax_status_rules at backend/src/state_tax.c:3482 (marker CALC-STEP: status-rules).

Applies to: The API and the library entry point. Engine convention, no external source: Reporting only; the calculation selects the same values.

The breakdown and perPerson blocks

breakdown is the engine's detail record summed over the household; perPerson (with a spouse object) is one entry per person, from the same record.

Code: person_json, state_tax_json_response at backend/src/state_tax_json.c:509 (marker CALC-STEP: api-response-breakdown).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Error body

Every 400 has the body {"error": "<message>"}; the messages are listed verbatim on the API reference.

Code: state_tax_json_error_body at backend/src/state_tax_json.c:688 (marker CALC-STEP: api-errors).

Applies to: The API and the library entry point. Engine convention, no external source: API design, not tax law.

Configuration, filing status and entry points

Each jurisdiction's configuration

On first use the engine fills one configuration record per jurisdiction (rate schedules, deductions, exclusions, flags), each value cited beside it in the source. The record is read-only afterwards; every calculation reads from it.

Code: init_state_data, build_no_tax, build_flat, build_progressive, build_ca, build_ny, build_dc, mark_ss_taxed, set_full_retirement_exclusion_age, set_full_retirement_exclusion, set_capped_retirement_exclusion_full, set_capped_retirement_exclusion, set_code_name, copy_fixed at backend/src/state_tax.c:1107 (marker CALC-STEP: config-tables).

Applies to: Every calculation (engine-wide). Each value is cited in the engine source beside it and, with its official source, in every rule section of each state page.

Military and wage rules

Military retirement and earned-income rules are set per jurisdiction in a second pass over the same records.

Code: init_military_and_wage_rules, state_slot, mil_exempt, mil_taxable, mil_capped at backend/src/state_tax.c:339 (marker CALC-STEP: config-tables-military).

Applies to: Every calculation (engine-wide). Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

Blindness, disability and the 1.5.0 additions

A third pass over the same records sets the engine 1.5.0 rules: blind amounts, disability routes, head-of-household amounts and the personal and senior credits the blind-and-disability survey found, each cited beside it.

Code: init_engine_150_rules at backend/src/state_tax.c:694 (marker CALC-STEP: config-tables-150).

Applies to: Every calculation (engine-wide). Each value is cited in the engine source beside it and, with its official source, in every rule section of each state page.

Looking up a jurisdiction

A two-letter code (case-insensitive) or NONE selects a configuration. Initialisation runs once, thread-safely. NONE has no brackets, so its tax is always 0.

Code: state_tax_get_by_code, state_tax_list_codes, ensure_initialized, state_tax_init_once_cb, state_tax_config_init_none at backend/src/state_tax.c:3380 (marker CALC-STEP: state-lookup).

Applies to: Every calculation (engine-wide). Engine convention, no external source: Engine design, not tax law.

Entry points

compute_state_tax_detail() is the calculation; compute_state_tax_v4() calls it without a detail record. The older v3, v2 and compute_state_tax() pass the documented unknowns: no public-pension or pension split, no federal tax (so no Alabama or Oregon deduction) and no federal taxable income (so the component model).

Code: compute_state_tax_v4, compute_state_tax_v3, compute_state_tax_v2, compute_state_tax, st_finish, compute_state_tax_detail at backend/src/state_tax.c:4130 (marker CALC-STEP: entry-points).

Applies to: Every calculation (engine-wide). Engine convention, no external source: Engine design, not tax law.

Per-person mode joint returns with the spouse's age given

On a joint return with the spouse's age given, every age test the state applies per taxpayer is evaluated for each spouse at their own age. Without it one household age applies to both.

Code: compute_state_tax_detail at backend/src/state_tax.c:4145 (marker CALC-STEP: per-person-mode). Engine inputs: age, sp2_age.

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: The engine cannot know the second spouse's age unless told.

Blindness and disability, per person only when the caller says a person is blind or disabled

The filer is person one; the spouse counts only on a joint return and only when the caller says so (there is no household convention as for age). Where a state lets a disabled person (and, where it says so, a blind one, or one whose spouse is disabled) qualify for its general retirement exclusion before the age, that person is treated as having reached the age for that exclusion only. Of the 42 taxing jurisdictions, these have a blind amount: Arizona, Arkansas, California, Colorado, Delaware, the District of Columbia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, New Jersey, New Mexico, North Dakota, Oklahoma, Oregon, Utah, Vermont and Virginia; these have none: Alabama, Connecticut, Georgia, Louisiana, New York, North Carolina, Ohio, Pennsylvania, Rhode Island, South Carolina, West Virginia and Wisconsin. A disability route is calculated in Arkansas, the District of Columbia, Georgia, Hawaii, Idaho, Iowa, Maryland, Michigan, New Jersey, Oregon and West Virginia.

Code: compute_state_tax_detail at backend/src/state_tax.c:4154 (marker CALC-STEP: blind-disabled-persons). Configuration read: retirement_disabled_age, retirement_blind_qualifies, retirement_disabled_spouse_counts. Engine inputs: blind, sp2_blind, disabled, sp2_disabled.

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: Who is blind or disabled is the caller's statement; the engine has no household convention for it.

Rate schedule and standard deduction by filing status

Single uses the single schedule and deduction; married filing jointly the joint ones. Head of household and married filing separately follow the two steps below.

Code: select_brackets at backend/src/state_tax.c:3425 (marker CALC-STEP: select-schedule). Configuration read: num_brackets_single, num_brackets_mfj, brackets_single, brackets_mfj, std_deduction_single, std_deduction_mfj.

Applies to: Every jurisdiction with an income tax (42). Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

Married filing separately

Where the state publishes its own separate schedule, that one (with half the joint deduction unless a separate deduction is set). Where one schedule applies to every status, that schedule unscaled with the single deduction. Otherwise the joint schedule with every threshold and the deduction halved (computed as the joint tax on twice the income, halved).

Code: select_brackets at backend/src/state_tax.c:3433 (marker CALC-STEP: mfs-schedule). Configuration read: num_brackets_mfs, brackets_mfs, mfj_schedule_equals_single.

Applies to: Every jurisdiction with an income tax (42). Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

Head of household

The state's head-of-household schedule where it has one, else the single schedule; the head-of-household deduction where set, else the single deduction.

Code: select_brackets at backend/src/state_tax.c:3459 (marker CALC-STEP: hoh-schedule). Configuration read: num_brackets_hoh, brackets_hoh, std_deduction_hoh.

Applies to: Every jurisdiction with an income tax (42). Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

A separate deduction for married filing separately married filing separately

Where set, this amount replaces the deduction the schedule rule above gives married filing separately.

Code: compute_state_tax_detail at backend/src/state_tax.c:4206 (marker CALC-STEP: mfs-std-deduction). Configuration read: std_deduction_mfs.

Applies to: WI. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

No broad income tax

A jurisdiction with no brackets returns 0 at once, except Washington's capital-gains excise below. Military pay is still attributed per person in the detail record.

Code: compute_state_tax_detail at backend/src/state_tax.c:4211 (marker CALC-STEP: no-income-tax).

Applies to: AK, FL, NV, NH, SD, TN, TX, WA, WY. Official sources: the No broad income tax section of each state page this step applies to (linked above), each with its checked date.

Washington capital-gains excise

The excise rate on long-term gain above the excise deduction, plus the additional rate on gain above the high threshold. Nothing else is taxed.

Code: compute_state_tax_detail at backend/src/state_tax.c:4227 (marker CALC-STEP: wa-cg-excise). Configuration read: cg_excise_rate, cg_excise_deduction, cg_excise_high_rate, cg_excise_high_threshold.

Applies to: WA. Official sources: the Capital gains section of each state page this step applies to (linked above), each with its checked date.

Income normalisation and attribution

The income total every income test uses

Other ordinary income + retirement distributions (before any exclusion) + conversion + federally taxable Social Security + long-term gains. It stands in for federal adjusted gross income in every threshold, cliff and phase-out below; state subtractions do not reduce it.

Code: compute_state_tax_detail at backend/src/state_tax.c:4246 (marker CALC-STEP: agi-proxy). Engine inputs: other_ordinary, retirement_distributions, roth_conversion, ss_income, capital_gains.

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: The inputs are the federal AGI components, so their sum is federal AGI for these income types.

Short-term gains exempt

Short-term gain (a part of other ordinary income) leaves the base; it stays in the income total above.

Code: compute_state_tax_detail at backend/src/state_tax.c:4256 (marker CALC-STEP: st-gains-exempt). Configuration read: exempts_short_term_gains. Engine inputs: short_term_gains.

Applies to: MO. Official sources: the Capital gains section of each state page this step applies to (linked above), each with its checked date.

Nesting the income subsets

Public pension ⊆ pension income ⊆ retirement distributions; military pay ⊆ distributions and apart from pension income; wages ⊆ other ordinary income. Each subset is clamped into its parent, so an inconsistent input cannot exclude dollars that are not there.

Code: compute_state_tax_detail at backend/src/state_tax.c:4281 (marker CALC-STEP: normalise-subsets). Engine inputs: pension_income, pension_public, pension_military, wages.

Applies to: Every calculation (engine-wide). Engine convention, no external source: Input normalisation.

Attributing income to each spouse joint returns with each spouse's own amounts given

With a caller's split (the API's spouse object), each spouse's own distributions, pension, public pension, conversion, wages and military pay; spouse 2's shares are clamped into the household totals and spouse 1 gets the rest. Without a split, in per-person mode, every item is divided 50/50. Social Security, other ordinary income and gains are always divided 50/50 where a rule needs a per-person amount. The split is used only where a state's rule is per taxpayer; household totals stay authoritative for the base and the income tests.

Code: compute_state_tax_detail at backend/src/state_tax.c:4320 (marker CALC-STEP: attribution). Configuration read: exclusion_cap_per_taxpayer. Engine inputs: has_spouse_split, sp2_retirement_distributions, sp2_pension_income, sp2_pension_public, sp2_roth_conversion, sp2_wages, sp2_pension_military.

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: Equal attribution is the neutral split when the owner of a dollar is not known.

Keeping the per-spouse shares inside the household joint returns with each spouse's own amounts given

After the public-pension and employer-pension carve-outs, if the two spouses' remaining shares add up to more than the household's exclusion-eligible distributions (an inconsistent split), spouse 1's share is reduced so they do not.

Code: compute_state_tax_detail at backend/src/state_tax.c:4694 (marker CALC-STEP: coherence-clamp).

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: Input normalisation.

Exclusions: military pay, pensions, Social Security, retirement income, conversions and gains

Military retirement pay

The state's military rule runs first, on military pay alone, per taxpayer: each spouse's own pay at their own age when attributed, otherwise half each at the household age on a joint return. Exempt dollars leave the base; the rest become pension dollars for the general retirement rules. Where the state lets a disabled retiree qualify at any age, a disabled person is treated as having reached the rule's age.

Code: compute_state_tax_detail at backend/src/state_tax.c:4404 (marker CALC-STEP: military). Configuration read: military_treatment, military_remainder_general, military_disabled_any_age. Engine inputs: pension_military.

Applies to: Every jurisdiction with an income tax (42). Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

One taxpayer's military exemption

Exempt: all of it (below the age split, up to the younger cap). Capped: up to the cap for the age tier, plus the earned-income bonus below the age split when the taxpayer's own wages exceed the threshold, less the taxpayer's own Social Security where the rule says so. Percentage: the percentage (below the age split, up to the younger cap). Then the income limit: above it the exemption is lost, or phased out over the range where one is set.

Code: military_exempt_one at backend/src/state_tax.c:4055 (marker CALC-STEP: military-exempt-one). Configuration read: military_cap, military_min_age, military_cap_young, military_pct, military_earned_bonus, military_earned_threshold, military_cap_reduced_by_ss, military_income_limit_single, military_income_limit_mfj, military_income_range_single, military_income_range_mfj.

Applies to: AZ, CO, ID, IL, IN, MA, MI, NC, PA, AL, AR, CA, CT, DE, GA, HI, IA, KS, LA, ME, MD, MN, MS, MO, NE, NJ, NM, NY, ND, OH, OK, RI, SC, VT, VA, WV, WI. Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

One military cap per joint return joint returns

On a joint return the cap is one amount for the couple, over the pay of the spouses who pass the age test, reduced by the household's Social Security where the rule says so, then the income test.

Code: compute_state_tax_detail at backend/src/state_tax.c:4421 (marker CALC-STEP: military-per-return). Configuration read: military_cap_mfj.

Applies to: ID, CA. Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

Military exclusion reduces other caps

Where the statute says so, the military amount a taxpayer excluded reduces that taxpayer's general retirement-exclusion cap, their age-65 subtraction, or both.

Code: compute_state_tax_detail at backend/src/state_tax.c:4501 (marker CALC-STEP: military-reduces-general). Configuration read: military_reduces_general.

Applies to: MI, AR, SC, WV. Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

Military pay barred from the general exclusion

Where a state's military rule leaves dollars taxable and bars them from the general retirement exclusion, they are added back to the base after the exclusions. No jurisdiction currently does this.

Code: compute_state_tax_detail at backend/src/state_tax.c:5295 (marker CALC-STEP: military-ineligible). Configuration read: military_remainder_general.

Applies to: No jurisdiction in this tax year. Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

Non-covered public pension excluded in full only when the caller says the pension was not covered by Social Security

Only when the caller says the public pension was not covered by Social Security: the pension takes the uncapped public-pension exemption below (per taxpayer, without using the general retirement exclusion).

Code: compute_state_tax_detail at backend/src/state_tax.c:4542 (marker CALC-STEP: ok-csrs-exclusion). Configuration read: noncov_pension_fully_exempt. Engine inputs: pension_public_not_ss_covered.

Applies to: OK. Official sources: the Public pensions section of each state page this step applies to (linked above), each with its checked date.

Public pension exemption

Public-pension dollars leave the base, uncapped or up to the per-taxpayer cap (each spouse's own public pension against their own cap when attributed), without using up the general exclusion the remaining distributions may claim. Capped-out public dollars stay taxable and cannot draw the private exclusion.

Code: compute_state_tax_detail at backend/src/state_tax.c:4555 (marker CALC-STEP: public-pension). Configuration read: public_pension_fully_exempt, public_pension_exclusion_cap_single, public_pension_exclusion_cap_mfj. Engine inputs: pension_public.

Applies to: AZ, MA, HI, KS, LA, MO, NY, WV. Official sources: the Public pensions section of each state page this step applies to (linked above), each with its checked date.

Public pension exemption reduced by the Social Security exemption

From age 62 the capped public-pension exemption is reduced by the federally taxable Social Security (per spouse, half each, in per-person mode).

Code: compute_state_tax_detail at backend/src/state_tax.c:4607 (marker CALC-STEP: public-pension-ss-offset). Configuration read: public_pension_excl_reduced_by_taxable_ss.

Applies to: MO. Official sources: the Public pensions section of each state page this step applies to (linked above), each with its checked date.

Employer pension exemption

Employer (defined-benefit) pension dollars, public or private, leave the base; IRA dollars keep the capped exclusion.

Code: compute_state_tax_detail at backend/src/state_tax.c:4661 (marker CALC-STEP: db-pension-exempt). Configuration read: pension_income_fully_exempt. Engine inputs: pension_income.

Applies to: AL. Official sources: the Public pensions section of each state page this step applies to (linked above), each with its checked date.

Colorado: per spouse, own ages joint returns with the spouse's age given

Per spouse at their own ages (both ages known): each spouse's own distributions and half the Social Security through the subtraction below, at that spouse's age; the income test for ages 55 to 64 uses the joint income total. A conversion is taxed in full.

Code: compute_state_tax_detail at backend/src/state_tax.c:4712 (marker CALC-STEP: co-per-person).

Applies to: CO. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Colorado: per spouse, household age joint returns

Joint return without the spouse's age: still per spouse, each at the household age, with the distributions split by the caller's split or 50/50 and Social Security 50/50. A conversion is taxed in full.

Code: compute_state_tax_detail at backend/src/state_tax.c:4734 (marker CALC-STEP: co-per-spouse-household). Configuration read: co_cap_per_spouse_household.

Applies to: CO. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Colorado: one filer

Otherwise (single, separate and head-of-household returns): one subtraction on the whole amount. A conversion is taxed in full.

Code: compute_state_tax_detail at backend/src/state_tax.c:4764 (marker CALC-STEP: co-household).

Applies to: CO. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Colorado Social Security and pension subtraction

65 or older: Social Security fully subtracted; pension and annuity income up to $24,000 less the Social Security subtracted. 55 to 64 with income at or below the threshold: the same with a $20,000 cap. 55 to 64 above it: one shared $20,000, Social Security first. Under 55: no subtraction.

Code: co_retirement_in_state_base at backend/src/state_tax.c:3803 (marker CALC-STEP: co-subtraction). Configuration read: ss_exempt_agi_single, ss_exempt_agi_mfj, ss_hoh_uses_mfj.

Applies to: CO. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Which Social Security threshold applies

Joint returns use the joint threshold; head of household uses it too where the state says so, otherwise the single one; married filing separately uses its own threshold where set, else the single one. Benefits are tested against the income total above.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3528 (marker CALC-STEP: ss-threshold). Configuration read: taxes_ss, ss_exempt_agi_single, ss_exempt_agi_mfj, ss_exempt_agi_mfs, ss_hoh_uses_mfj.

Applies to: CO, UT, CT, MN, MT, NM, RI, VT. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security exempt

None of the federally taxable benefit enters the base.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3625 (marker CALC-STEP: ss-exempt). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: AZ, ID, IL, IN, KY, MA, MI, NC, PA, AL, AR, CA, DE, GA, HI, IA, KS, LA, ME, MD, MS, MO, NE, NJ, NY, ND, OH, OK, OR, SC, VA, WV, WI, DC. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: exempt up to a threshold, then all

At or below the threshold nothing enters; above it the whole federally taxable amount does (a cliff).

Code: ss_amount_in_state_base at backend/src/state_tax.c:3548 (marker CALC-STEP: ss-nm-cliff). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: NM. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: the federal amount

The federally taxable amount enters the base as it is.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3543 (marker CALC-STEP: ss-mt-full). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: MT. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: a share of gross benefits above a threshold

At or below the threshold nothing enters. Above it, 25% of gross benefits, capped at the federally taxable amount; without gross benefits the engine estimates them as the taxable amount divided by 0.85.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3553 (marker CALC-STEP: ss-ct-25). Configuration read: ss_rule, ss_ct_quarter_of_gross. Engine inputs: ss_income, ss_gross.

Applies to: CT. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: stepped subtraction

At or below the threshold nothing enters. Above it, 10% of the benefit enters for each $4,000 of income over ($2,000 married filing separately), or part of one, up to all of it.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3570 (marker CALC-STEP: ss-mn-step). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: MN. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: ratable phase-out

At or below the threshold nothing enters. Above it the share entering rises in proportion over the next $10,000 of income, up to all of it.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3581 (marker CALC-STEP: ss-vt-ramp). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: VT. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: credit phase-out

The credit removes the tax on benefits at or below the threshold. Above it the credit falls by 2.5% per dollar over; the engine carries this as the taxed share of benefits rising by that rate divided by the tax rate per dollar over, up to all of it.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3591 (marker CALC-STEP: ss-ut-credit). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: UT. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: age and income test

Exempt only at full retirement age (67) or older with income at or below the threshold; otherwise the whole federally taxable amount enters.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3602 (marker CALC-STEP: ss-ri-fra). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: RI. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Social Security: Colorado age bands (Social Security alone)

The same age bands as the Colorado subtraction, on Social Security alone. In a calculation Colorado always takes the joint subtraction above; this branch serves callers of the Social Security rule by itself.

Code: ss_amount_in_state_base at backend/src/state_tax.c:3611 (marker CALC-STEP: ss-co-bands). Configuration read: ss_rule. Engine inputs: ss_income.

Applies to: CO. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Rhode Island: per-spouse age test joint returns with the spouse's age given

With both ages known, each spouse's half of the benefits is exempt only if that spouse is at full retirement age, against the joint income test.

Code: compute_state_tax_detail at backend/src/state_tax.c:4774 (marker CALC-STEP: ss-ri-per-person).

Applies to: RI. Official sources: the Social Security section of each state page this step applies to (linked above), each with its checked date.

Does a conversion draw the retirement cap?

Where the state lets a conversion draw the capped exclusion, and the filer is at or above the conversion age, the conversion is pooled with distributions against the cap.

Code: compute_state_tax_detail at backend/src/state_tax.c:4793 (marker CALC-STEP: conversion-pooled-test). Configuration read: conversion_eligible_for_capped_exclusion, conversion_exclusion_min_age.

Applies to: KY, MI, AL, LA, NJ, NY, OK, SC, WI. Official sources: the Roth conversions section of each state page this step applies to (linked above), each with its checked date.

Retirement exclusion per spouse (both ages known) joint returns with the spouse's age given

Full-exclusion states exclude each qualifying spouse's own dollars. Capped states give each spouse the single cap for their own age against their own eligible dollars (pension dollars only where the exclusion is pension-only; employer dollars only below the IRA age), less their military exclusion and half of any Social Security offset. Per-return states (and the pooled-if-both-qualify rule when both qualify) apply the joint cap to the couple's pooled eligible dollars when either spouse qualifies. The income tests then apply once to the summed deduction.

Code: compute_state_tax_detail, per_taxpayer_cap_single at backend/src/state_tax.c:4798 (marker CALC-STEP: retirement-per-person). Configuration read: exclusion_cap_per_return, exclusion_cap_pooled_if_both_qualify.

Applies to: IL, KY, MI, PA, AL, AR, DE, GA, IA, LA, ME, MD, MS, MO, NJ, NY, OK, RI, SC, WI. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Income-tested percentage of distributions

Distributions are deductible at the percentage for the income band (joint column for joint returns, and for head of household unless it uses the single column). Where the state says so a conversion draws the same percentage; otherwise it is taxed in full. In per-person mode the excluded amount is shown for each spouse in proportion to their own distributions (reporting only).

Code: compute_state_tax_detail at backend/src/state_tax.c:4961 (marker CALC-STEP: ct-phasedown-apply). Configuration read: ct_pension_hoh_single_column, ct_conversion_in_phasedown.

Applies to: CT. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

The percentage table

The deductible share by income. Single, head-of-household and separate filers: 100% from $0; 85% from $75,000; 70% from $77,500; 55% from $80,000; 40% from $82,500; 25% from $85,000; 10% from $87,500; 5% from $90,000; 2.5% from $95,000; 0% from $100,000. Joint filers: 100% from $0; 85% from $100,000; 70% from $105,000; 55% from $110,000; 40% from $115,000; 25% from $120,000; 10% from $125,000; 5% from $130,000; 2.5% from $140,000; 0% from $150,000. The table lives in code; these values are read back from it.

Code: ct_pension_deductible_pct at backend/src/state_tax.c:3857 (marker CALC-STEP: ct-pension-phasedown). Configuration read: ct_pension_phasedown.

Applies to: CT. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Conversion pooled with distributions

The conversion joins the distributions against the one cap (with a spouse split in a per-taxpayer state, each spouse's own distributions and conversion against that spouse's cap). Nothing of the conversion is added separately.

Code: compute_state_tax_detail at backend/src/state_tax.c:5005 (marker CALC-STEP: conversion-pooled).

Applies to: KY, MI, AL, LA, NJ, NY, OK, SC, WI. Official sources: the Roth conversions section of each state page this step applies to (linked above), each with its checked date.

Pension-only exclusion

Only pension and annuity dollars draw the capped exclusion; IRA dollars and conversions are taxed in full.

Code: compute_state_tax_detail at backend/src/state_tax.c:5041 (marker CALC-STEP: pension-sourced-only). Configuration read: exclusion_pension_sourced_only.

Applies to: MD, RI. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

No retirement exclusion (age deduction instead)

Distributions and conversions stay in the base; the age deduction below applies against any income.

Code: compute_state_tax_detail at backend/src/state_tax.c:5051 (marker CALC-STEP: age-deduction-no-exclusion). Configuration read: age_deduction_any_income.

Applies to: VA. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Retirement exclusion (household)

The distributions eligible for the exclusion go through the exclusion below. Taxable public-pension dollars left by a cap are not eligible; below the IRA age only employer-plan dollars are.

Code: compute_state_tax_detail at backend/src/state_tax.c:5071 (marker CALC-STEP: retirement-default). Configuration read: retirement_exclusion_ira_min_age.

Applies to: AZ, ID, IL, IN, KY, MA, MI, NC, PA, UT, AL, AR, CA, DE, GA, HI, IA, KS, LA, ME, MN, MS, MO, MT, NE, NJ, NM, NY, ND, OH, OK, OR, SC, VT, WV, WI, DC. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Retirement exclusion per spouse (declared split) joint returns with each spouse's own amounts given

With a spouse split in a per-taxpayer state, each spouse's own eligible dollars draw that spouse's single cap (less their military exclusion); an income limit then applies once to the sum.

Code: compute_state_tax_detail, per_taxpayer_cap_single at backend/src/state_tax.c:5091 (marker CALC-STEP: retirement-split). Configuration read: exclusion_cap_per_taxpayer.

Applies to: AL, AR, DE, LA, MO, OK, SC. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Conversion taxed or exempt

In full-exclusion states a conversion is exempt at the qualifying age (at any age where the state says so). Elsewhere, unless pooled above, it is ordinary income taxed in full.

Code: compute_state_tax_detail at backend/src/state_tax.c:5158 (marker CALC-STEP: conversion-treatment). Configuration read: conversion_exempt_regardless_of_age. Engine inputs: roth_conversion.

Applies to: AZ, ID, IL, IN, KY, MA, MI, NC, PA, UT, AL, AR, CA, DE, GA, HI, IA, KS, LA, ME, MN, MS, MO, MT, NE, NJ, NM, NY, ND, OH, OK, OR, SC, VT, WV, WI, DC. Official sources: the Roth conversions section of each state page this step applies to (linked above), each with its checked date.

Full exclusion

All distributions are excluded at or above the exclusion age; below it they are taxed.

Code: retirement_distributions_in_state_base at backend/src/state_tax.c:3648 (marker CALC-STEP: retirement-full-exclusion). Configuration read: exempts_qualified_retirement_income, retirement_exclusion_min_age.

Applies to: IL, PA, IA, MS. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Graduated exclusion by income band

Below the exclusion age nothing is excluded. Otherwise the share of the exclusion granted falls with income (Social Security left out); in the middle bands it is a percentage by filing status of the whole pension, limited to the pension, where the state's worksheet says so, otherwise of the capped amount. The separate-return cap applies where set. Engine values, single and head of household: 100% from $0; 37.5% over $100,000; 18.75% over $125,000; 0% over $150,000; joint: 100% from $0; 50% over $100,000; 25% over $125,000; 0% over $150,000; separate: 100% from $0; 25% over $100,000; 12.5% over $125,000; 0% over $150,000.

Code: retirement_distributions_in_state_base at backend/src/state_tax.c:3658 (marker CALC-STEP: retirement-nj-bands). Configuration read: partial_exclusion_pct_bands, partial_exclusion_pct_of_whole, retirement_income_exclusion_mfs.

Applies to: NJ. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Income limit on the exclusion

When the income total (Social Security left out where the state says so) exceeds the limit, the exclusion is lost (a cliff), reduced dollar for dollar after the cap (subtractive), or phased out in proportion over the range.

Code: retirement_distributions_in_state_base at backend/src/state_tax.c:3702 (marker CALC-STEP: retirement-income-limit). Configuration read: retirement_exclusion_income_limit, retirement_exclusion_income_limit_mfj, retirement_exclusion_income_is_ramp, retirement_exclusion_income_ramp_subtractive, retirement_exclusion_income_range_single, retirement_exclusion_income_range_mfj, retirement_exclusion_income_excludes_ss.

Applies to: ME, MO, RI. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Cap by age tier

The full cap at or above the exclusion age, the lower cap at or above the partial age, otherwise none. Joint returns use the joint cap; every other status the single cap.

Code: retirement_distributions_in_state_base at backend/src/state_tax.c:3722 (marker CALC-STEP: retirement-cap-age-tiers). Configuration read: retirement_income_exclusion_single, retirement_income_exclusion_mfj, retirement_exclusion_min_age, retirement_exclusion_partial_single, retirement_exclusion_partial_mfj, retirement_exclusion_partial_min_age.

Applies to: KY, MI, AL, AR, DE, GA, LA, ME, MD, MO, NJ, NY, OK, RI, SC, WI. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Cap reduced by Social Security

The cap is reduced dollar for dollar by Social Security received: gross benefits when supplied, otherwise the federally taxable amount.

Code: retirement_distributions_in_state_base at backend/src/state_tax.c:3741 (marker CALC-STEP: retirement-cap-ss-offset). Configuration read: retirement_exclusion_reduced_by_ss. Engine inputs: ss_gross.

Applies to: ME, MD. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

The capped deduction

Deduction = the smaller of the eligible distributions and the cap, then reduced by the income limit above; the rest of the distributions stays in the base.

Code: retirement_distributions_in_state_base at backend/src/state_tax.c:3757 (marker CALC-STEP: retirement-capped-deduction).

Applies to: KY, MI, AL, AR, DE, GA, LA, ME, MD, MO, NJ, NY, OK, RI, SC, WI. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

One taxpayer's cap joint returns with the spouse's age given

For per-spouse calculations, each spouse's cap is the single-column cap for their age tier.

Code: per_taxpayer_cap_single at backend/src/state_tax.c:4026 (marker CALC-STEP: per-taxpayer-cap).

Applies to: KY, MI, AL, AR, DE, GA, LA, ME, MD, MO, NJ, NY, OK, RI, SC, WI. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Long-term gains in the base

Where gains are taxed as ordinary income: net long-term gain less the flat exclusion (never below zero), times the inclusion share. Elsewhere none enters.

Code: compute_state_tax_detail at backend/src/state_tax.c:5178 (marker CALC-STEP: ltcg-base). Configuration read: taxes_ltcg_as_ordinary, cg_flat_exclusion, ltcg_inclusion_ratio. Engine inputs: capital_gains.

Applies to: Every jurisdiction with an income tax (42). Official sources: the Capital gains section of each state page this step applies to (linked above), each with its checked date.

Retirement and investment pool per spouse joint returns with the spouse's age given

Each spouse's pool = own distributions + own conversion + half the long-term gain in the base + (where the state counts earned income) up to the earned-income amount of their own wages, against the cap for their own age. The pool above the caps is taxed.

Code: compute_state_tax_detail at backend/src/state_tax.c:5193 (marker CALC-STEP: pool-per-person). Configuration read: retirement_exclusion_pools_investment_income, earned_income_in_retirement_exclusion.

Applies to: DE, GA. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Retirement and investment pool

Distributions + conversion + long-term gain in the base (+ wages up to the earned-income amount per qualifying person) form one pool against the cap for the household age (each spouse's own pool and cap with a split in a per-taxpayer state). The pool above the cap is taxed as ordinary income; conversions and gains are not added separately.

Code: compute_state_tax_detail at backend/src/state_tax.c:5231 (marker CALC-STEP: pool-household). Configuration read: retirement_exclusion_pools_investment_income, earned_income_in_retirement_exclusion.

Applies to: DE, GA. Official sources: the IRA, 401(k) and private pensions section of each state page this step applies to (linked above), each with its checked date.

Public pension not covered by Social Security only when the caller says the pension was not covered by Social Security

Only when the caller says the public pension was not covered: the smaller of the public pension still in the base and the cap, reduced above the income start (by a percentage per step, or linearly over a range). Where it is an election instead of the Social Security exclusion, the engine keeps whichever excludes more.

Code: compute_state_tax_detail at backend/src/state_tax.c:5308 (marker CALC-STEP: noncovered-pension). Configuration read: noncov_pension_cap_single, noncov_pension_cap_mfj, noncov_pension_phaseout_start_single, noncov_pension_phaseout_start_mfj, noncov_pension_phaseout_start_mfs, noncov_pension_phaseout_step, noncov_pension_phaseout_step_pct, noncov_pension_phaseout_range, noncov_pension_elect_vs_ss. Engine inputs: pension_public_not_ss_covered.

Applies to: ID, MN, VT. Official sources: the Public pensions section of each state page this step applies to (linked above), each with its checked date.

Non-covered pension: age test and shared cap only when the caller says the pension was not covered by Social Security

Where the state sets them: only a recipient at or above the age qualifies (each spouse's own public pension in per-person mode); the cap is reduced by the Social Security received (gross when supplied) and by the military pay the same deduction already excluded. A disabled recipient qualifies from the lower disability age where the state sets one.

Code: compute_state_tax_detail at backend/src/state_tax.c:5323 (marker CALC-STEP: noncovered-pension-limits). Configuration read: noncov_pension_min_age, noncov_pension_cap_reduced_by_ss, noncov_pension_shares_military_cap, noncov_pension_disabled_min_age.

Applies to: ID. Official sources: the Public pensions section of each state page this step applies to (linked above), each with its checked date.

Deductions, exemptions and age subtractions

Additional standard deduction at 65

The unmarried amount for a single or head-of-household filer 65 or older, the married amount for each spouse 65 or older, added to the standard deduction before any phase-out.

Code: compute_state_tax_detail at backend/src/state_tax.c:5382 (marker CALC-STEP: std-aged-add). Configuration read: std_deduction_aged_add_unmarried, std_deduction_aged_add_married.

Applies to: CO, ID, IA, KS, ME, MN, MO, MT, NM, ND, OR, DC. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Additional standard deduction for blindness only when the caller says a person is blind or disabled

The unmarried amount for a blind single or head-of-household filer, the married amount for each blind spouse, added to the standard deduction before any phase-out. Age and blindness are separate boxes, so a person 65 or older and blind gets both.

Code: compute_state_tax_detail at backend/src/state_tax.c:5393 (marker CALC-STEP: std-blind-add). Configuration read: blind_std_add_unmarried, blind_std_add_married.

Applies to: CO, ID, IA, KS, ME, MN, MO, MT, NE, NM, ND, OR, DC. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Standard deduction phase-out

Above the start the deduction is scaled by 1 − (income − start) / width, down to zero, with head-of-household and separate starts where the state has them; where the state says so a head of household never gets less than the single deduction at the same income. Where the state rounds the reduction, it is rounded down to that multiple before it is taken.

Code: compute_state_tax_detail at backend/src/state_tax.c:5408 (marker CALC-STEP: std-phaseout). Configuration read: std_deduction_phaseout_start_single, std_deduction_phaseout_start_mfj, std_deduction_phaseout_denom_single, std_deduction_phaseout_denom_mfj, std_deduction_phaseout_start_hoh, std_deduction_phaseout_denom_hoh, std_deduction_phaseout_start_mfs, std_deduction_phaseout_denom_mfs, std_phaseout_hoh_floor_single, std_phaseout_round_down.

Applies to: ME, SC, WI. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Standard deduction limited at high income

Above the income threshold the deduction (with its age and blindness amounts) is limited to the status amount: the state adds the rest back. On the component path only; where the caller supplies federal taxable income that figure is used as given.

Code: compute_state_tax_detail at backend/src/state_tax.c:5454 (marker CALC-STEP: std-addback). Configuration read: std_addback_agi_threshold, std_addback_keep_single, std_addback_keep_mfj.

Applies to: CO. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Exemption phase-out on state income

The exemption the engine carries as the deduction is lost in whole steps for each step (or part) of income over the start, or linearly over the range; the income here is what enters the state base (exempt Social Security left out).

Code: compute_state_tax_detail at backend/src/state_tax.c:5470 (marker CALC-STEP: ct-exemption-phaseout). Configuration read: exemption_phaseout_start_single, exemption_phaseout_start_mfj, exemption_phaseout_start_hoh, exemption_phaseout_start_mfs, exemption_phaseout_step, exemption_phaseout_range_single, exemption_phaseout_range_mfj.

Applies to: CT. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Taxpayer credit instead of a deduction

No deduction is subtracted: the deduction amount (plus the federal additional amount per taxpayer 65 or older) becomes the base of the credit applied after the schedule. The federal blind amount joins the base the same way, per blind person.

Code: compute_state_tax_detail at backend/src/state_tax.c:5506 (marker CALC-STEP: ut-credit-base). Configuration read: taxpayer_credit_rate, taxpayer_credit_aged_add_single, taxpayer_credit_aged_add_married, blind_credit_base_add_unmarried, blind_credit_base_add_married.

Applies to: UT. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Personal exemption

The joint amount on a joint return, the head-of-household amount where set, otherwise the single amount.

Code: compute_state_tax_detail at backend/src/state_tax.c:5535 (marker CALC-STEP: personal-exemption). Configuration read: personal_exemption_single, personal_exemption_mfj, personal_exemption_hoh.

Applies to: AL, HI, KS, ME, MS, OK, RI, VT, VA, WI. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Exemption set by income

The amount per exemption is the first tier whose income limit the income total does not exceed (joint limits for joint returns, and for head of household where set), else the amount above the tiers; two exemptions on a joint return, one otherwise. It replaces the flat exemption.

Code: compute_state_tax_detail at backend/src/state_tax.c:5545 (marker CALC-STEP: exemption-tiers). Configuration read: exemption_tier_count, exemption_tier_amount, exemption_tier_agi_single, exemption_tier_agi_joint, exemption_tier_hoh_joint, exemption_tier_amount_above.

Applies to: MD, OH. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Exemption phase-out

Above the filing status's start the exemption is scaled by 1 − (income − start) / range, down to zero.

Code: compute_state_tax_detail at backend/src/state_tax.c:5561 (marker CALC-STEP: exemption-ratable-phaseout). Configuration read: exemption_ratable_phaseout_start_single, exemption_ratable_phaseout_start_mfj, exemption_ratable_phaseout_start_hoh, exemption_ratable_phaseout_start_mfs, exemption_ratable_phaseout_range, exemption_ratable_phaseout_range_mfs.

Applies to: ME. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Low- and middle-income exemption

At any age, per exemption (the filer, and the spouse on a joint return; the engine has no dependents): the amount less the filing status's rate times the income total above its base, not below zero, and none once the income total is over the status's limit.

Code: compute_state_tax_detail at backend/src/state_tax.c:5582 (marker CALC-STEP: lmi-exemption). Configuration read: lmi_exemption, lmi_agi_limit_single, lmi_agi_limit_mfj, lmi_agi_limit_hoh, lmi_agi_limit_mfs, lmi_base_single, lmi_base_mfj, lmi_base_hoh, lmi_base_mfs, lmi_rate_single, lmi_rate_mfj, lmi_rate_hoh, lmi_rate_mfs.

Applies to: NM. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Exemption for blindness only when the caller says a person is blind or disabled

An extra exemption for each blind person (the filer, and the spouse on a joint return). Where the state's exemption is for a person who is blind or disabled, a disabled person below the state's age limit (if any) qualifies too, one exemption per person either way.

Code: compute_state_tax_detail at backend/src/state_tax.c:5604 (marker CALC-STEP: blind-exemption). Configuration read: blind_exemption, blind_exemption_disabled_max_age.

Applies to: AZ, IL, IN, MA, MI, DE, MD, MS, NJ, OK, VT, VA. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Income exclusion for disability only when the caller says a person is blind or disabled

Up to the amount of income for each disabled person, while the income total is under the limit, taken against the base (the engine does not know each person's own income; taxable income cannot go below zero).

Code: compute_state_tax_detail at backend/src/state_tax.c:5620 (marker CALC-STEP: disabled-income-exclusion). Configuration read: disabled_income_exclusion, disabled_income_exclusion_agi_limit.

Applies to: DC. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Age subtraction

At or above the age: the single amount, or the joint amount on a joint return (both spouses at the household age). In per-person mode, half the joint amount (or the single amount) per qualifying spouse. Plus the low-income amount below the income test; less the military exclusion where the statute says so; limited to the spouse's own income where the statute says so.

Code: compute_state_tax_detail at backend/src/state_tax.c:5633 (marker CALC-STEP: senior-subtraction). Configuration read: senior_subtraction_single, senior_subtraction_mfj, senior_subtraction_min_age, senior_subtraction_lowincome_bonus_single, senior_subtraction_lowincome_bonus_mfj, senior_subtraction_lowincome_agi, senior_subtraction_lowincome_agi_mfs, senior_subtraction_own_income.

Applies to: AZ, IL, IN, MA, DE, HI, MD, MS, MT, NE, NJ, SC, VT, VA, WV, WI. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Age subtraction for a disabled person only when the caller says a person is blind or disabled

Where the state gives its age subtraction to a permanently and totally disabled person at any age: per disabled spouse in per-person mode; on the household path below the age, one amount per disabled person, reduced as at the age.

Code: compute_state_tax_detail at backend/src/state_tax.c:5699 (marker CALC-STEP: senior-disabled). Configuration read: senior_subtraction_disabled_qualifies.

Applies to: WV. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Age subtraction reduced by Social Security and public pension

Each qualifying taxpayer's amount is reduced by their own taxable Social Security (half each on a joint return) and their own public-pension exemption.

Code: compute_state_tax_detail at backend/src/state_tax.c:5709 (marker CALC-STEP: senior-reduced-by-ss). Configuration read: senior_subtraction_reduced_by_ss.

Applies to: WV. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Extra exemption at 65 for low income

One more exemption per taxpayer at or above the age when the income total (conversions left out where the state says so) is at most the filing status's limit.

Code: compute_state_tax_detail at backend/src/state_tax.c:5732 (marker CALC-STEP: senior-lowincome-exemption). Configuration read: senior_lowinc_exemption, senior_lowinc_min_age, senior_lowinc_agi_single, senior_lowinc_agi_mfj, senior_lowinc_agi_mfs, senior_lowinc_agi_hoh, senior_lowinc_agi_excludes_conversion.

Applies to: OK. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Age exemption stepped down by income

For each taxpayer at or above the age (each spouse on a joint return): the full amount while the income total is at most the status's start, then less the decrement for each width of income (or part of one) above it; head of household reads the joint column where the state says so. Where the state says so, a blind person qualifies too, with one exemption per person.

Code: compute_state_tax_detail at backend/src/state_tax.c:5759 (marker CALC-STEP: senior-step-exemption). Configuration read: senior_step_exemption, senior_step_min_age, senior_step_agi_single, senior_step_agi_mfj, senior_step_agi_mfs, senior_step_width_single, senior_step_width_mfj, senior_step_width_mfs, senior_step_decrement, senior_step_hoh_joint, senior_step_blind_qualifies.

Applies to: NM. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Federal senior deduction taken against the state base

For each taxpayer 65 or older: the amount, reduced by the rate times the income total above the status's start (joint start on a joint return); none for married filing separately. In the states whose base is federal taxable income it is taken only when the caller does not supply that figure (it is already in it).

Code: compute_state_tax_detail at backend/src/state_tax.c:5794 (marker CALC-STEP: fed-senior-deduction). Configuration read: fed_senior_deduction, fed_senior_phaseout_single, fed_senior_phaseout_mfj, fed_senior_phaseout_rate.

Applies to: AZ, CO, ID, IA, MT, ND. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Disability exemption instead of the regular ones only when the caller says a person is blind or disabled

A person who is blind (or disabled) takes the state's disability exemption instead of their own regular and age exemptions; the other spouse keeps theirs.

Code: compute_state_tax_detail at backend/src/state_tax.c:5818 (marker CALC-STEP: blind-in-lieu-exemption). Configuration read: blind_in_lieu_exemption.

Applies to: HI. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Age deduction against any income

The amount per taxpayer at or above the age, reduced dollar for dollar by income (taxable Social Security left out) over the limit; on a joint return the combined amount is reduced once by the joint excess.

Code: compute_state_tax_detail at backend/src/state_tax.c:5856 (marker CALC-STEP: va-age-deduction). Configuration read: age_deduction_any_income, retirement_income_exclusion_single, retirement_income_exclusion_mfj, retirement_exclusion_min_age, retirement_exclusion_income_limit, retirement_exclusion_income_limit_mfj, retirement_exclusion_income_excludes_ss.

Applies to: VA. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Taxable income

State taxable income

Other ordinary income + Social Security, retirement income, conversion and gains left in the base − standard deduction − personal exemption − age subtractions.

Code: compute_state_tax_detail at backend/src/state_tax.c:5902 (marker CALC-STEP: taxable-income).

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: The order of subtraction follows the state forms; each amount is sourced at its own step.

Starting from federal taxable income only when the caller supplies federal taxable income (the planner; not the API)

When the caller supplies federal taxable income (the planner does; the API does not), the base starts from it, adds the gains in it (less the state's gain subtraction), and subtracts the state's own exclusions and subtractions; the state's deduction is not subtracted again.

Code: compute_state_tax_detail at backend/src/state_tax.c:5906 (marker CALC-STEP: conformity-base). Configuration read: state_base_is_federal_taxable_income. Engine inputs: fed_taxable_ordinary, fed_taxable_ltcg.

Applies to: CO, IA, MT, ND. Official sources: the Interaction with the federal return section of each state page this step applies to (linked above), each with its checked date.

Federal income tax deduction only when the caller supplies federal tax

Only when the caller supplies federal tax. Full: the federal tax plus the net investment income tax. Capped: the federal tax (without the net investment income tax where the state says so) up to the cap, which loses 20% of itself for each band of income from the start (joint and head-of-household returns on the joint bands, separate returns half the cap).

Code: compute_state_tax_detail at backend/src/state_tax.c:5961 (marker CALC-STEP: fit-deduction). Configuration read: fit_deduction_full, fit_deduction_cap_single, fit_deduction_cap_mfj, fit_phaseout_start_single, fit_phaseout_start_mfj, fit_phaseout_step_single, fit_phaseout_step_mfj, fit_excludes_niit. Engine inputs: federal_tax, federal_niit.

Applies to: AL, OR. Official sources: the Interaction with the federal return section of each state page this step applies to (linked above), each with its checked date.

Detail record

The bases, exclusions and subtractions are recorded per person (or for the household) for the breakdown.

Code: compute_state_tax_detail at backend/src/state_tax.c:6008 (marker CALC-STEP: detail-fill).

Applies to: Every calculation (engine-wide). Engine convention, no external source: Engine output, not tax law.

Rule names in the detail record

Each person's record names the military, retirement and age rule the state applies.

Code: retirement_rule_name, state_tax_military_treatment_name at backend/src/state_tax.c:4106 (marker CALC-STEP: detail-labels).

Applies to: Every calculation (engine-wide). Engine convention, no external source: Engine output, not tax law.

No tax at or below zero

State taxable income at or below zero returns a tax of 0 (credits are not refundable and nothing below applies).

Code: compute_state_tax_detail at backend/src/state_tax.c:6039 (marker CALC-STEP: zero-floor).

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: Every credit the engine carries is nonrefundable, so nothing below can make a zero tax negative; each credit is sourced at its own step.

Tax: the schedule, recapture, gains rates and minimum tax

Each spouse's own zero-rate band joint returns

On a joint return the first (zero-rate) bracket is widened to the sum over the spouses of the smaller of the band and that spouse's income (own wages, retirement and conversion income by the caller's split, everything else half each), and the brackets above shift with it.

Code: compute_state_tax_detail at backend/src/state_tax.c:6042 (marker CALC-STEP: ms-zero-band). Configuration read: mfj_zero_band_per_spouse.

Applies to: MS. Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

Separate-return scaling married filing separately

For the halved-joint rule, taxable income is doubled before the schedule and the result halved.

Code: compute_state_tax_detail at backend/src/state_tax.c:6097 (marker CALC-STEP: mfs-scale).

Applies to: Every jurisdiction with an income tax (42). Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

The rate schedule

Each bracket's rate on the part of taxable income inside it, summed. No rounding: the result is carried in full precision.

Code: apply_state_brackets at backend/src/state_tax.c:3404 (marker CALC-STEP: bracket-tax).

Applies to: Every jurisdiction with an income tax (42). Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

Fixed amount above the zero bracket

Once taxable income passes the threshold a fixed amount is added (halved with the schedule for a separate return).

Code: compute_state_tax_detail at backend/src/state_tax.c:6112 (marker CALC-STEP: bracket-cliff). Configuration read: bracket_cliff_amount, bracket_cliff_threshold.

Applies to: OH. Official sources: the Rate schedule section of each state page this step applies to (linked above), each with its checked date.

Tax-benefit recapture

On state AGI (the income in the base before deductions) above the start, the recapture below is added.

Code: compute_state_tax_detail at backend/src/state_tax.c:6123 (marker CALC-STEP: ny-recapture-apply). Configuration read: ny_recapture, ny_recapture_first_flat.

Applies to: NY. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

The recapture worksheets

For each bracket below the filer's top one, its benefit (flat rate times the bracket bottom, less the schedule tax on it, less the lower brackets' benefit) is phased in over $50,000 of income above the larger of $107,650 and the bracket bottom. Fully phased in, all taxable income is taxed at the top rate. Where the first worksheet applies to taxable income below its bracket, the flat rate of that bracket applies to all of it, phased in the same way.

Code: ny_tax_benefit_recapture at backend/src/state_tax.c:3968 (marker CALC-STEP: ny-recapture).

Applies to: NY. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

Add-back and recapture

On state AGI (the income in the base), the add-back and the recapture below are added to the schedule tax.

Code: compute_state_tax_detail at backend/src/state_tax.c:6136 (marker CALC-STEP: ct-addback-apply). Configuration read: ct_addback_recapture.

Applies to: CT. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

Rate phase-out add-back (Table C)

A fixed amount per step (or part) of income over the start, up to a maximum, by filing status. The table lives in code; the state page prints engine values.

Code: ct_2pct_phaseout_addback at backend/src/state_tax.c:3899 (marker CALC-STEP: ct-addback).

Applies to: CT. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

Benefit recapture (Table D)

Three tiers per filing status (separate returns use the single tiers); each adds a fixed amount per step (or part) of income over its start, up to its own maximum.

Code: ct_benefit_recapture at backend/src/state_tax.c:3917 (marker CALC-STEP: ct-recapture).

Applies to: CT. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

Own schedule for long-term gains

The gain in the base (at most the taxable income) is taken out of the schedule and taxed at the lower gains rate up to the first ordinary bracket's top, stacked on the ordinary income, and at the upper rate above; this replaces the schedule part of the tax, and amounts added on top of the schedule before it (a fixed amount, recapture) are kept.

Code: compute_state_tax_detail at backend/src/state_tax.c:6154 (marker CALC-STEP: mt-cg-schedule). Configuration read: cg_own_rate_low, cg_own_rate_high.

Applies to: MT. Official sources: the Capital gains section of each state page this step applies to (linked above), each with its checked date.

Alternative capital-gains tax

The schedule part of the tax is the smaller of the regular schedule tax and the schedule tax on income without the gain plus the alternative rate times the gain; amounts added on top of the schedule before it are kept.

Code: compute_state_tax_detail at backend/src/state_tax.c:6176 (marker CALC-STEP: hi-alt-cg). Configuration read: cg_alt_rate.

Applies to: HI. Official sources: the Capital gains section of each state page this step applies to (linked above), each with its checked date.

Minimum tax

Above the income threshold the tax before credits is at least the rate times the income total.

Code: compute_state_tax_detail at backend/src/state_tax.c:6196 (marker CALC-STEP: vt-min-tax). Configuration read: min_tax_agi_rate, min_tax_agi_threshold.

Applies to: VT. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

Credits

Per-exemption credit

The credit per exemption: two on a joint return, one otherwise, or the state's own count for a head of household. Where the state sets an income limit there is no credit above it (the joint limit for joint returns and heads of household).

Code: compute_state_tax_detail at backend/src/state_tax.c:6207 (marker CALC-STEP: exemption-credit). Configuration read: exemption_credit_per, exemption_credit_count_hoh, exemption_credit_agi_limit_single, exemption_credit_agi_limit_joint.

Applies to: AR, CA, DE, IA, NE, OR. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Senior credit

The credit per taxpayer at or above the age: two on a joint return at the household age, one per qualifying spouse in per-person mode. A head of household's extra personal credit is not a second senior credit.

Code: compute_state_tax_detail at backend/src/state_tax.c:6231 (marker CALC-STEP: senior-credit). Configuration read: senior_credit_per, credit_senior_min_age.

Applies to: KY, AR, CA, DE, IA. Official sources: the Age 65+ subtractions and credits section of each state page this step applies to (linked above), each with its checked date.

Credit for blindness only when the caller says a person is blind or disabled

The credit for each blind person.

Code: compute_state_tax_detail at backend/src/state_tax.c:6250 (marker CALC-STEP: blind-credit). Configuration read: blind_credit.

Applies to: KY, AR, CA, IA. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Personal, senior and blind credits phased out

Above the status threshold each personal, senior and blind credit loses the amount for each step of income (or part of one), not below zero; the separate step applies to married filing separately.

Code: compute_state_tax_detail at backend/src/state_tax.c:6255 (marker CALC-STEP: credit-phaseout). Configuration read: credit_phaseout_start_single, credit_phaseout_start_mfj, credit_phaseout_start_hoh, credit_phaseout_step, credit_phaseout_step_mfs, credit_phaseout_amount.

Applies to: CA. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Credit for severe disability only when the caller says a person is blind or disabled

One more credit for each disabled person while the income total is at most the limit.

Code: compute_state_tax_detail at backend/src/state_tax.c:6291 (marker CALC-STEP: disabled-credit). Configuration read: disabled_credit, disabled_credit_agi_limit.

Applies to: OR. Official sources: the Blindness and disability section of each state page this step applies to (linked above), each with its checked date.

Taxpayer tax credit

The credit rate times the credit base, less the phase-out rate times taxable income above the filing status's base, not below zero.

Code: compute_state_tax_detail at backend/src/state_tax.c:6301 (marker CALC-STEP: ut-taxpayer-credit). Configuration read: taxpayer_credit_rate, taxpayer_credit_phaseout_rate, taxpayer_credit_phaseout_base_single, taxpayer_credit_phaseout_base_mfj, taxpayer_credit_phaseout_base_hoh.

Applies to: UT. Official sources: the Deductions, exemptions and credits section of each state page this step applies to (linked above), each with its checked date.

Married couple credit joint returns with each spouse's own amounts given

Joint returns with the spouse's age and a spouse split only, and only when no retirement exclusion was taken: the rate times the lower-earning spouse's wages, up to the maximum.

Code: compute_state_tax_detail at backend/src/state_tax.c:6322 (marker CALC-STEP: wi-married-couple-credit). Configuration read: married_couple_credit_rate, married_couple_credit_max.

Applies to: WI. Official sources: the Wages section of each state page this step applies to (linked above), each with its checked date.

Joint filing credit joint returns with each spouse's own amounts given

Joint returns with the spouse's age and a spouse split only, income total under $750,000, and each spouse with at least $500 of wages, retirement or conversion income: a share of the tax by taxable income, 15% from the first dollar of tax; 10% over $50,000; 5% over $75,000, at most $650.

Code: compute_state_tax_detail at backend/src/state_tax.c:6337 (marker CALC-STEP: oh-joint-filing-credit). Configuration read: joint_filing_credit.

Applies to: OH. Official sources: the Wages section of each state page this step applies to (linked above), each with its checked date.

Military retirement credit

The credit rate times the military pay.

Code: compute_state_tax_detail at backend/src/state_tax.c:6356 (marker CALC-STEP: military-credit). Configuration read: military_credit_rate.

Applies to: UT. Official sources: the Military retirement pay section of each state page this step applies to (linked above), each with its checked date.

Credits cannot make the tax negative

The credits are subtracted and the result floored at zero.

Code: compute_state_tax_detail at backend/src/state_tax.c:6365 (marker CALC-STEP: credit-floor).

Applies to: Every jurisdiction with an income tax (42). Engine convention, no external source: Every credit the engine carries is nonrefundable; each credit is sourced at its own step.

After credits: county tax, surcharges and surtaxes

County income tax

The county rate times state taxable income, after credits and not reduced by them.

Code: compute_state_tax_detail at backend/src/state_tax.c:6375 (marker CALC-STEP: local-tax). Configuration read: local_tax_applies, local_tax_rate.

Applies to: IN, MD. Official sources: the Local income tax section of each state page this step applies to (linked above), each with its checked date.

Capital-gains surcharge

When the income total exceeds the threshold, the rate times net long-term gain.

Code: compute_state_tax_detail at backend/src/state_tax.c:6383 (marker CALC-STEP: md-cg-surcharge). Configuration read: cg_surcharge_rate, cg_surcharge_agi_threshold.

Applies to: MD. Official sources: the Capital gains section of each state page this step applies to (linked above), each with its checked date.

Surtax on high income

The rate times state taxable income over the filing status's threshold.

Code: compute_state_tax_detail at backend/src/state_tax.c:6393 (marker CALC-STEP: top-surtax). Configuration read: top_surtax_rate, top_surtax_threshold, top_surtax_threshold_mfj, top_surtax_threshold_hoh, top_surtax_threshold_mfs.

Applies to: MA, CA, ME. Official sources: the Surtaxes and recapture section of each state page this step applies to (linked above), each with its checked date.

Conventions: rounding and later years

Rounding

The engine does not round, except where a form rounds a computed amount: South Carolina rounds the reduction of its income-adjusted deduction down to a whole ten dollars, and the engine does the same. Otherwise brackets, phase-outs and credits are computed in double precision, and the API returns the tax unrounded. Step functions that the forms define in whole steps use ceilings (Minnesota's Social Security and public-pension steps, Connecticut's exemption, add-back and recapture steps, California's credit phase-out) or floors (Oregon's federal-tax bands). Where a state's instructions look tax up in a table of income bands, the engine applies the rate schedule to the exact amount, so results can differ from the table by a few dollars. The pages on this site show amounts rounded to the cent.

Code: apply_state_brackets at backend/src/state_tax.c:3403.

Applies to: Every calculation (engine-wide). Engine convention, no external source: The engine's own choice, described above.

Later years: indexing dollar amounts

The engine's tables are for the tax year shown. For later years the planner scales every dollar amount the statutes index by one inflation factor; rates, percentages, ages and the amounts the statutes fix stay as they are. The calculation-order page lists which fields scale and which do not.

Code: scale_state_tax_config_for_year at backend/src/monte_carlo.c:2368.

Applies to: Every calculation (engine-wide). Engine convention, no external source: A projection, not a published figure.

The lines the worked examples show

The engine records these as it computes (its detail record); the state pages print them for each worked example. The documentation build checks that they add up: taxable income = the income in the base − the deductions, exemptions and age subtractions − the federal-tax deduction (floored at zero), and tax = schedule tax + the additions and adjustments − the credits used + the county tax, surcharge and surtax.

Record fieldLineStep
agi_proxyIncome total used by the income testsThe income total every income test uses
short_term_gains_exemptShort-term gain exempted (not in the base)Short-term gains exempt
military_excludedMilitary pay excluded (not in the base)Military retirement pay
retirement_excludedRetirement income and conversions excluded (not in the base)The capped deduction
earned_income_excludedWages inside the retirement exclusion (not in the base)Retirement and investment pool
noncovered_pension_excludedNon-covered public pension subtracted (already out of the retirement line below)Public pension not covered by Social Security
ordinary_in_base+ Other ordinary income in the baseState taxable income
ss_in_base+ Social Security in the baseWhich Social Security threshold applies
retirement_in_base+ Retirement income in the baseThe capped deduction
conversion_in_base+ Roth conversion in the baseConversion taxed or exempt
ltcg_in_base+ Long-term gain in the baseLong-term gains in the base
standard_deduction− Standard deductionStandard deduction phase-out
personal_exemption− Personal exemptionPersonal exemption
senior_total− Age subtractions and deductionsAge subtraction
federal_tax_deduction− Federal income tax deductionFederal income tax deduction
taxable_income= State taxable incomeState taxable income
zero_band_widthJoint zero-rate band after per-spouse wideningEach spouse's own zero-rate band
bracket_taxTax from the rate scheduleThe rate schedule
bracket_cliff+ Fixed amount above the zero bracketFixed amount above the zero bracket
recapture+ Tax-benefit recaptureThe recapture worksheets
ct_addback+ Rate phase-out add-back (Table C)Rate phase-out add-back (Table C)
ct_recapture+ Benefit recapture (Table D)Benefit recapture (Table D)
cg_schedule_adjustment± Own gains schedule (replaces the schedule tax on the gain)Own schedule for long-term gains
cg_alt_adjustment− Alternative capital-gains tax savingAlternative capital-gains tax
min_tax_topup+ Minimum tax top-upMinimum tax
tax_before_credits= Tax before creditsMinimum tax
credit_exemptionPer-exemption creditPer-exemption credit
credit_seniorSenior creditSenior credit
credit_blindBlind creditCredit for blindness
credit_disabledDisability creditCredit for severe disability
credit_taxpayerTaxpayer tax creditTaxpayer tax credit
credit_married_coupleMarried couple creditMarried couple credit
credit_joint_filingJoint filing creditJoint filing credit
military_creditMilitary retirement creditMilitary retirement credit
credits_applied− Credits used (never more than the tax)Credits cannot make the tax negative
local_tax+ County income taxCounty income tax
cg_surcharge+ Capital-gains surchargeCapital-gains surcharge
surtax+ SurtaxSurtax on high income
cg_exciseCapital-gains exciseWashington capital-gains excise
tax= TaxCredits cannot make the tax negative

Later years: which amounts are indexed

The engine's tables are for tax year 2026. The planner projects later years by multiplying dollar amounts by one inflation factor in scale_state_tax_config_for_year() (backend/src/monte_carlo.c:2368). Rate tables scale their thresholds; the rates do not change. Tables that live in code rather than in the configuration (the Connecticut percentage, add-back and recapture tables, the New York recapture start and width, the Colorado caps, the Minnesota Social Security step, the Ohio joint filing credit bands) are not scaled. The API computes tax year 2026 only.

Scaled every later year

FieldMeaningWhen
brackets_*Every bracket threshold of every schedulealways
std_deduction_singleStandard deduction (or folded personal exemption), single/MFSalways
std_deduction_mfjStandard deduction (or folded personal exemption), MFJalways
std_deduction_hohHead-of-household standard deduction (0 = the single amount)always
std_deduction_phaseout_start_singleIncome above which the standard deduction phases out, singlealways
std_deduction_phaseout_start_mfjIncome above which the standard deduction phases out, MFJalways
std_deduction_phaseout_denom_singleWidth of the standard-deduction phase-out, singlealways
std_deduction_phaseout_denom_mfjWidth of the standard-deduction phase-out, MFJalways
personal_exemption_singlePersonal exemption subtracted in addition to the standard deduction, singlealways
personal_exemption_mfjPersonal exemption subtracted in addition to the standard deduction, MFJalways
exemption_phaseout_start_singleIncome above which the exemption phases out, single (CT)always
exemption_phaseout_start_mfjIncome above which the exemption phases out, MFJ (CT)always
exemption_phaseout_range_singleWidth of the exemption phase-out, single (CT)always
exemption_phaseout_range_mfjWidth of the exemption phase-out, MFJ (CT)always
exemption_credit_perNonrefundable credit per exemption (1 single, 2 MFJ)always
senior_credit_perAdditional nonrefundable credit per taxpayer at or above the senior agealways
taxpayer_credit_phaseout_base_singleTaxpayer credit phase-out base, single/MFSalways
taxpayer_credit_phaseout_base_mfjTaxpayer credit phase-out base, MFJalways
taxpayer_credit_phaseout_base_hohTaxpayer credit phase-out base, HOHalways
senior_subtraction_singleSubtraction from the base at or above the senior age, singlealways
senior_subtraction_mfjSubtraction from the base at or above the senior age, MFJalways
senior_subtraction_lowincome_bonus_singleExtra senior subtraction below the low-income test, singlealways
senior_subtraction_lowincome_bonus_mfjExtra senior subtraction below the low-income test, MFJalways
senior_subtraction_lowincome_agiIncome below which the extra senior subtraction appliesalways
ss_exempt_agi_singleIncome threshold for the Social Security exemption, singlealways
ss_exempt_agi_mfjIncome threshold for the Social Security exemption, MFJalways
ss_exempt_agi_mfsDedicated MFS threshold (0 = the single threshold)always
retirement_income_exclusion_singleCapped retirement-income exclusion, single (per taxpayer)always
retirement_income_exclusion_mfjCapped retirement-income exclusion, MFJ (both spouses)always
retirement_exclusion_partial_singleLower-tier cap for a younger age band, singlealways
retirement_exclusion_partial_mfjLower-tier cap for a younger age band, MFJalways
retirement_exclusion_income_limitIncome limit for the exclusion, singlealways
retirement_exclusion_income_limit_mfjIncome limit for the exclusion, MFJalways
retirement_exclusion_income_range_singlePhase-out width over the income limit, singlealways
retirement_exclusion_income_range_mfjPhase-out width over the income limit, MFJalways
public_pension_exclusion_cap_singleCap on the public-pension exemption, per taxpayer (0 = uncapped)only where public_pension_cap_indexed is set (the cap follows an indexed figure); held where the statute fixes it
public_pension_exclusion_cap_mfjCap on the public-pension exemption, MFJonly where public_pension_cap_indexed is set (the cap follows an indexed figure); held where the statute fixes it
cg_flat_exclusionFirst dollars of gain excludedalways
cg_surcharge_agi_thresholdIncome threshold for the capital-gains surchargealways
cg_excise_deductionCapital-gains excise standard deductionalways
cg_excise_high_thresholdTaxable gain above which the additional excise appliesalways
top_surtax_thresholdSurtax thresholdonly where top_surtax_threshold_indexed is set
fit_deduction_cap_singleCap on the federal-tax subtraction, single/HOHalways
fit_deduction_cap_mfjCap on the federal-tax subtraction, MFJalways
military_capMilitary pay exempt per taxpayer at or above the age split (optional cap for the percent rule)always
military_cap_mfjMilitary cap per joint return (0 = per taxpayer)except where military_amounts_fixed is set (the statute fixes the amounts); held there with the per-taxpayer cap and the income limits
military_cap_youngMilitary pay exempt per taxpayer below the age splitalways
military_income_limit_singleIncome limit for the military exemption, singlealways
military_income_limit_mfjIncome limit for the military exemption, MFJalways
military_income_range_singlePhase-out width above the military income limit, single (0 = cliff)always
military_income_range_mfjPhase-out width above the military income limit, MFJalways
military_earned_bonusExtra military exemption below the age split when own earned income exceeds the thresholdalways
military_earned_thresholdEarned income needed for the extra military exemptionalways
earned_income_in_retirement_exclusionEarned income per taxpayer that counts toward the retirement exclusionalways
std_deduction_mfsMFS standard deduction where it is neither half the MFJ one nor the single one (0 = the default rule)always
std_deduction_phaseout_start_hohIncome above which the standard deduction phases out, HOH (0 = single values)always
std_deduction_phaseout_denom_hohWidth of the standard-deduction phase-out, HOHalways
std_deduction_phaseout_start_mfsIncome above which the standard deduction phases out, MFS (0 = single values)always
std_deduction_phaseout_denom_mfsWidth of the standard-deduction phase-out, MFSalways
personal_exemption_hohPersonal exemption, HOH, where it differs from single (0 = single)always
exemption_tier_amountPer-exemption amount for each income tieralways
exemption_tier_agi_singleUpper income of each exemption tier, single/MFSalways
exemption_tier_agi_jointUpper income of each exemption tier, MFJalways
exemption_tier_amount_abovePer-exemption amount above the last tieralways
exemption_phaseout_stepExemption lost in whole steps of this size (0 = linear)always
exemption_phaseout_start_hohIncome above which the exemption phases out, HOH (0 = single)always
exemption_phaseout_start_mfsIncome above which the exemption phases out, MFS (0 = single)always
taxpayer_credit_aged_add_singleFederal additional standard deduction per 65+ taxpayer added to the taxpayer-credit base, single/HOHalways
taxpayer_credit_aged_add_marriedSame, marriedalways
bracket_cliff_amountFixed amount owed once bracket income exceeds the thresholdalways
bracket_cliff_thresholdIncome above which the fixed amount is owedalways
top_surtax_threshold_mfjSurtax threshold, MFJ (0 = the single threshold)only where top_surtax_threshold_indexed is set
top_surtax_threshold_hohSurtax threshold, HOH (0 = the single threshold)only where top_surtax_threshold_indexed is set
top_surtax_threshold_mfsSurtax threshold, MFS (0 = the single threshold)only where top_surtax_threshold_indexed is set
retirement_income_exclusion_mfsRetirement exclusion cap, MFS (0 = the single cap)always
std_deduction_aged_add_unmarriedAdditional standard deduction per taxpayer 65 or older, single/HOH (part of the phased-out deduction)always
std_deduction_aged_add_marriedAdditional standard deduction per spouse 65 or older, MFJ/MFSalways
exemption_ratable_phaseout_start_singleIncome above which the personal exemption phases out ratably, single (0 = no phase-out)always
exemption_ratable_phaseout_start_mfjSame, MFJalways
exemption_ratable_phaseout_start_hohSame, HOHalways
exemption_ratable_phaseout_start_mfsSame, MFSalways
exemption_ratable_phaseout_rangeWidth of the ratable exemption phase-outalways
exemption_ratable_phaseout_range_mfsWidth of the ratable exemption phase-out, MFS (0 = the general width)always
senior_lowinc_exemptionExtra exemption per taxpayer at the age below when federal AGI is at most the filing-status limitalways
senior_lowinc_agi_singleFederal AGI limit for the low-income extra exemption, singlealways
senior_lowinc_agi_mfjSame, MFJalways
senior_lowinc_agi_mfsSame, MFSalways
senior_lowinc_agi_hohSame, HOHalways
noncov_pension_cap_singleSubtraction for a public pension earned without Social Security coverage, per return, single/HOH/MFS (needs the caller's say-so)always
noncov_pension_cap_mfjSame, MFJalways
noncov_pension_phaseout_start_singleIncome above which that subtraction phases out, single/HOHalways
noncov_pension_phaseout_start_mfjSame, MFJalways
noncov_pension_phaseout_start_mfsSame, MFS (0 = the single start)always
blind_std_add_unmarriedAdditional standard deduction per blind person, single/HOH (part of the phased-out deduction)always
blind_std_add_marriedSame, per blind spouse, MFJ/MFSalways
blind_credit_base_add_unmarriedFederal blind amount added to the taxpayer-credit base per blind person, single/HOHalways
blind_credit_base_add_marriedSame, per blind spouse, MFJ/MFSalways
senior_subtraction_lowincome_agi_mfsIncome below which the extra senior subtraction applies, married filing separately (0 = the general test)always

Not scaled

FieldMeaningWhy
taxpayer_credit_rateTaxpayer tax credit rate on the deduction base (UT); nonzero means no deduction is subtractedA rate.
taxpayer_credit_phaseout_rateTaxpayer credit reduction per dollar of taxable income over the baseA rate.
ltcg_inclusion_ratioShare of net long-term gain entering the base (0 = all of it)A share.
cg_alt_rateAlternative maximum rate on net long-term gainA rate.
cg_own_rate_lowOwn lower capital-gains rate (two-rate schedule)A rate.
cg_own_rate_highOwn upper capital-gains rate (two-rate schedule)A rate.
cg_surcharge_rateSurcharge on net capital gain above an income thresholdA rate.
cg_excise_rateCapital-gains excise rate (no-income-tax state)A rate.
cg_excise_high_rateAdditional excise rate above the high thresholdA rate.
top_surtax_rateFlat surtax on taxable income over the thresholdA rate.
fit_phaseout_start_singleIncome at which the federal-tax cap starts to step down, singleHeld at the tax-year amount: the engine treats the band edges as fixed in statute.
fit_phaseout_start_mfjIncome at which the federal-tax cap starts to step down, MFJ/HOHHeld at the tax-year amount: the engine treats the band edges as fixed in statute.
fit_phaseout_step_singleWidth of each 20% step, singleHeld at the tax-year amount: the engine treats the band widths as fixed in statute.
fit_phaseout_step_mfjWidth of each 20% step, MFJ/HOHHeld at the tax-year amount: the engine treats the band widths as fixed in statute.
local_tax_rateDefault local rate (overridable per request)A rate.
military_pctShare of military pay exempt (percent rule)A share.
military_credit_rateCredit rate on military pay in the base (credit rule)A rate.
married_couple_credit_rateMarried couple credit rate on the lower-earning spouse's earned incomeA rate.
married_couple_credit_maxMarried couple credit maximumHeld at the tax-year amount.
min_tax_agi_rateMinimum tax as a share of federal AGI above the thresholdA rate.
min_tax_agi_thresholdFederal AGI above which the minimum tax appliesHeld at the tax-year amount: the engine treats it as fixed in statute.
noncov_pension_phaseout_stepThe subtraction falls by the step percentage for each step of income (or part) over the startHeld at the tax-year amount: a step width the engine treats as fixed in statute.
noncov_pension_phaseout_step_pctShare of the subtraction lost per stepA share.
noncov_pension_phaseout_rangeWidth over which the subtraction phases out linearly (when there is no step)Held at the tax-year amount: a phase-out width the engine treats as fixed in statute.
senior_step_exemptionExemption per taxpayer at the age below, stepped down by federal AGI (full up to the start, less the decrement per width or part above it)Held at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_agi_singleFederal AGI up to which the stepped exemption is in full, singleHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_agi_mfjSame, MFJ (and HOH where HOH reads the joint column)Held at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_agi_mfsSame, MFSHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_width_singleWidth of each AGI step, singleHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_width_mfjSame, MFJHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_width_mfsSame, MFSHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
senior_step_decrementAmount the stepped exemption falls per stepHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_exemptionLow- and middle-income exemption per exemption (filer; both spouses on MFJ), any ageHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_agi_limit_singleFederal AGI limit for the low- and middle-income exemption, singleHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_agi_limit_mfjSame, MFJHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_agi_limit_hohSame, HOHHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_agi_limit_mfsSame, MFSHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_base_singleFederal AGI above which that exemption is reduced, singleHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_base_mfjSame, MFJHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_base_hohSame, HOHHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_base_mfsSame, MFSHeld at the tax-year amount: fixed in the New Mexico statute, not indexed.
lmi_rate_singleReduction per dollar of AGI above the base, singleA rate.
lmi_rate_mfjSame, MFJA rate.
lmi_rate_hohSame, HOHA rate.
lmi_rate_mfsSame, MFSA rate.
fed_senior_deductionThe federal senior deduction the state allows, per taxpayer 65 or older (none on MFS)Held at the tax-year amount: the federal statute fixes it (and ends it after the 2028 tax year, which the scaler cannot see).
fed_senior_phaseout_singleAGI above which each senior deduction is reduced, single/HOHHeld at the tax-year amount: the federal statute fixes it (and ends it after the 2028 tax year, which the scaler cannot see).
fed_senior_phaseout_mfjSame, MFJHeld at the tax-year amount: the federal statute fixes it (and ends it after the 2028 tax year, which the scaler cannot see).
fed_senior_phaseout_rateReduction of each senior deduction per dollar of AGI above the startA rate.
std_phaseout_round_downThe standard-deduction phase-out's reduction is rounded down to a multiple of this (0 = unrounded)A rounding unit, not an amount that indexes.
blind_exemptionExtra exemption subtracted per blind personHeld at the tax-year amount: fixed in most of the statutes that set it; where a state indexes it, later-year results are conservative.
blind_creditNonrefundable credit per blind personHeld at the tax-year amount: fixed in most of the statutes that set it; where a state indexes it, later-year results are conservative.
blind_in_lieu_exemptionExemption for a blind or disabled person instead of their own regular and age exemptionsHeld at the tax-year amount: fixed in most of the statutes that set it; where a state indexes it, later-year results are conservative.
disabled_income_exclusionIncome excluded per disabled person while the income total is under the limitHeld at the tax-year amount: fixed in statute.
disabled_income_exclusion_agi_limitIncome total under which that exclusion appliesHeld at the tax-year amount: fixed in statute.
credit_phaseout_start_singleFederal AGI above which the personal, senior and blind credits phase out, single/MFS (0 = none)Held at the tax-year amount, like the credits it reduces.
credit_phaseout_start_mfjSame, MFJHeld at the tax-year amount, like the credits it reduces.
credit_phaseout_start_hohSame, HOHHeld at the tax-year amount, like the credits it reduces.
credit_phaseout_stepAGI step (or part) per which each credit is reducedHeld at the tax-year amount, like the credits it reduces.
credit_phaseout_step_mfsSame, MFS (0 = the general step)Held at the tax-year amount, like the credits it reduces.
credit_phaseout_amountReduction of each credit per stepHeld at the tax-year amount, like the credits it reduces.
exemption_credit_agi_limit_singleNo personal exemption credit above this federal AGI, single/MFS (0 = no limit)Held at the tax-year amount: fixed in statute.
exemption_credit_agi_limit_jointSame, MFJ and HOHHeld at the tax-year amount: fixed in statute.
disabled_creditExtra credit per disabled person while federal AGI is at most the limitHeld at the tax-year amount; the credit it equals is indexed, so later-year results are conservative.
disabled_credit_agi_limitFederal AGI limit for that creditHeld at the tax-year amount: fixed in statute.
std_addback_agi_thresholdAbove this income total the standard deduction is limited to the status amount below (0 = none)Held at the tax-year amount: fixed in statute.
std_addback_keep_singleDeduction kept above that income total, single/HOH/MFSHeld at the tax-year amount: fixed in statute.
std_addback_keep_mfjSame, MFJHeld at the tax-year amount: fixed in statute.

What the engine does not calculate

What it does not calculate for one jurisdiction is listed on that jurisdiction's page, under "What the engine does not calculate".