# Reconcile numbers across tax reports Understand what to expect when comparing numbers across your tax reports Stripe Tax generates three report types from the same underlying transaction data. Because each report applies different filters, time zones, and jurisdiction-specific logic, totals don’t match if you compare them without first aligning your inputs. Use this guide to understand which numbers must align, where differences are expected, and what’s causing them, to either fix a discrepancy or explain one to an auditor. | Report type | What it shows | | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | [Itemized export](https://docs.stripe.com/tax/reports.md#itemized-exports) | Every line item of each tax transaction | | [Summarized export](https://docs.stripe.com/tax/reports.md#summarized-exports) | Tax transaction line items aggregated into totals per jurisdiction | | [Location report](https://docs.stripe.com/tax/reports.md#us-location-reports) | Tax transaction data formatted for a specific filing portal (supported US states and Canadian registrations) | > Stripe Tax reports use accrual accounting — transactions are recorded when they finalize (for example, when an invoice finalizes or a payment completes), not when the customer pays. Don’t reconcile these reports against cash-basis records. Open or unpaid invoices appear in the report before you receive payment. ## Before you begin Most reconciliation issues come from comparing two reports generated with different inputs. Before investigating any difference, confirm these dimensions match across both reports: - Both reports use the same **time zone** (location reports always use UTC). - Both reports use the same **date range** (location reports use fixed filing periods, not arbitrary ranges). - You are comparing the same **currency** for both reports (integration currency, filing currency, or both). - You’ve accounted for **non-taxable transaction filtering** (summarized exports always exclude non-taxable rows; itemized exports include them by default). - The **data availability window** covers the same transactions (itemized and summarized exports start at 2023-10-01; location reports vary by jurisdiction). The following table shows how each dimension differs across the three report types. | Dimension | Itemized export | Summarized export | Location report | | ------------------------ | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | Time zone | The time zone you select at export time | The time zone you select at export time | Always UTC | | Currency | Both integration (`tax_amount`, `total`, and so on) and filing (`filing_tax_amount`, `filing_total`) | Both integration (`total_tax_collected`) and filing (`filing_tax_payable`) | Filing currency only | | Non-taxable transactions | Included by default, toggle to exclude | Always excluded | Bucketed according to the jurisdiction’s filing form | | Earliest available data | 2023-10-01 or your account creation date, whichever is later | 2023-10-01 or your account creation date, whichever is later | Varies by jurisdiction. For US states: 2023-01-01 (2022-12-01 for New York). For Canadian registrations: see the period selector in the report. | | Date-range selection | Any range | Any range | Fiscal periods only (monthly, quarterly, annual, fiscal annual) determined by the location’s filing frequency | ## Reconcile an itemized export against a summarized export Itemized and summarized exports are the most directly reconcilable pair. They’re built from the same source data, use the same date column, and accept the same time zone selection. If you align the inputs and apply the correct filters to the itemized export, the totals match. 1. Filter the itemized export to match what the summarized export includes Summarized exports always exclude transactions with these `taxability_reason` values: - `no_tax` - `seller_not_registered` - `jurisdiction_unsupported` - `excluded_territory` - `product_not_supported` - `not_collecting` - `not_subject_to_tax` - `not_supported` The itemized export’s **Exclude non-taxable transactions** toggle removes a smaller subset (`no_tax`, `seller_not_registered`, `jurisdiction_unsupported`, `excluded_territory`, and `product_not_supported`). To get a clean match, also drop any rows whose `taxability_reason` is `not_collecting`, `not_subject_to_tax`, or `not_supported` after exporting. These three values appear on imported third-party transactions and a handful of Connect flows, so the residual is zero in most cases. When it isn’t zero, this is the single most common reason summarized totals come in lower than the itemized totals you computed. Voided transactions don’t need special handling. They’re subtracted from all totals automatically, so they cancel against the original transaction. 2. Group and sum After filtering the itemized export to the same date range, time zone, and jurisdiction filter you used for the summarized export, group the itemized rows by `country_code`, `state_code`, `jurisdiction_name`, `jurisdiction_level`, `tax_rate`, and `transaction_currency`. Then sum using this mapping: | Summarized column | Equivalent in itemized export | | ------------------------ | ---------------------------------------------------------------------------------------------- | | `total_sales` | `SUM(gross_amount)` over rows where `transaction_type = 'transaction'` | | `total` | `SUM(total)` over rows where `transaction_type = 'transaction'` | | `total_taxable_sales` | `SUM(taxable_amount)` over rows where `transaction_type = 'transaction'` | | `total_nontaxable_sales` | `SUM(non_taxable_amount)` over rows where `transaction_type = 'transaction'` | | `total_tax_payable` | `SUM(tax_amount)` over rows where `transaction_type = 'transaction'` | | `total_sales_refunded` | `SUM(gross_amount)` over rows where `transaction_type = 'reversal'` | | `total_taxable_refunded` | `SUM(filing_taxable_amount)` over rows where `transaction_type = 'reversal'` (filing currency) | | `total_tax_refunded` | `SUM(tax_amount)` over rows where `transaction_type = 'reversal'` | | `filing_tax_payable` | `SUM(filing_tax_amount)` over transactions, minus `SUM(filing_tax_amount)` over reversals | The same mapping works for the `filing_*` columns when you sum the corresponding `filing_*` columns from the itemized export. > #### Canadian federal tax > > Canadian federal tax rows require a modified grouping key. The itemized export leaves `state_code` empty for country-level Canadian tax (GST or the federal portion of HST), while the summarized export populates it with the province where the transaction occurred (for example, `AB`, `BC`, `ON`). This means the standard six-column key won’t join these rows. > > To reconcile Canadian federal tax rows: > > 1. Identify rows in both reports where `country_code = 'CA'`, `jurisdiction_level = 'country'`, and `jurisdiction_name = 'CANADA'`. 2. For those rows only, drop `state_code` from the grouping key. Group by `country_code`, `jurisdiction_name`, `jurisdiction_level`, `tax_rate`, and `transaction_currency` (five columns instead of six). 3. Sum and compare as normal using the mapping above. > > Provincial-level rows (where `jurisdiction_level` is `state`) are not affected — both reports populate `state_code` consistently. ## Reconcile transaction exports against location reports Location reports mirror a jurisdiction’s filing forms, meaning they aren’t designed to expose tax transactions one-to-one. As a result, there is no column-by-column equivalence between itemized and summarized exports. Reconciliation takes more work, and in some cases two reports won’t agree even when nothing is wrong. These are the reasons a location report can differ from the transaction exports for the same period and jurisdiction: ### Location reports always use UTC Itemized and summarized exports respect the time zone you select. Location reports are always built in UTC. If you have meaningful transaction volume around midnight UTC, a location report and a date-bounded export can disagree on which transactions belong to a given day. Re-export the itemized report in UTC if you need a clean comparison. ### Location reports follow each jurisdiction’s filing forms A location report does more than aggregate. It groups transactions and labels totals to match the filing form needs for that jurisdiction. For US states, this can include category-by-category breakdowns. For example, California separates sales of food, prescriptions, and certain other goods into their own schedules; Illinois groups grocery sales separately during a tax suspension; Washington separates retail sales from service revenue; and New York applies a clothing and footwear exemption to New York City sales. The categories on the form are determined by the jurisdiction, and a single tax transaction can affect more than one line on the form. Jurisdiction-specific logic also goes beyond which category a sale lands in. Some forms dictate how the totals on each line are derived. A few states recompute the tax shown on the form by re-applying the jurisdiction’s official rate to a derived taxable base, rather than summing the tax collected line by line. Others use form-specific splitting logic to distribute a transaction’s tax across multiple schedules so the cents add up the way the form expects. As a result, numbers won’t align with simple aggregations of data from itemized or summarized exports. A full reconciliation on a location report therefore requires experts who understand the specific rules for each location and can apply them to jurisdiction-level exports. ### Location reports use fixed filing periods You can run an itemized or summarized export for any date range, but location reports are tied to the filing frequency of the jurisdiction (monthly, quarterly, annual, or fiscal annual). A few US states use fiscal years that don’t start in January: - District of Columbia: October through September - Indiana, Kentucky, Tennessee: July through June - New York: March through February Canadian location reports use the filing frequency of the registration (monthly, quarterly, or annual). If you select a fiscal-year period in a location report and a calendar-year date range in an export, the two are by definition covering different transactions. Match the export’s date range to the period the location report shows. ## Reconcile against your filed return If you file with a partner or prepare returns manually, the numbers on the filed return might differ slightly from any of the three Stripe Tax reports. Filing tools might apply their own rounding and jurisdiction-specific filing logic, and filed returns also incorporate inputs Stripe Tax doesn’t see, such as credits, prepayments, vendor compensation, off-Stripe sales, use tax owed, and manual adjustments. Expect a small variance. Use the relevant Stripe Tax report as the authoritative record of what Stripe collected, and use the filed return as the legal artifact that incorporates the rest of your filing inputs. A line-by-line reconciliation isn’t usually worth the effort unless the gap is material. If the gap is material, focus on the largest transactions in the period rather than trying to match every column. ## Common differences between report types Each report type structures data differently, which affects how you compare them. ### Summarized versus itemized exports The summarized export filters out three additional `taxability_reason` values that the itemized export’s “Exclude non-taxable” toggle leaves in: `not_collecting`, `not_subject_to_tax`, and `not_supported`. If your summarized export shows a smaller total than your itemized export for the same jurisdiction and date range, drop those rows from the itemized export and re-sum. ### Itemized export column structure The itemized export has one row per tax jurisdiction, not one row per transaction. A single line item taxed in a state, county, city, and special district produces four rows, and most amount columns (`gross_amount`, `total`, `taxable_amount`, `non_taxable_amount`) repeat the line item’s value on every row. Summing those columns across all rows inflates the total by the number of jurisdictions per line item. Only `tax_amount` and `filing_tax_amount` are unique per row, so only those two are safe to sum directly. For sales-side amounts, group by jurisdiction first (as in [the mapping above](https://docs.stripe.com/tax/reports/reconcile.md#reconcile-an-itemized-export-against-a-summarized-export)), or deduplicate by `id` and `line_item_id` and sum within the unique rows. ### Location reports If a location report for a quarter shows different tax payable than your itemized export filtered to the same jurisdiction and quarter, the cause is one of: a time-zone mismatch (location reports always use UTC, so re-export in UTC), a fiscal-year offset (in the US, NY, IN, KY, TN, and DC have non-calendar fiscal years), or jurisdiction-specific filing categorization that buckets the same transactions differently on the form. ### Transactions in tax exports Tax exports only include transactions that Stripe Tax calculated tax for. That means invoices, subscriptions, Checkout Sessions, and Payment Links where `automatic_tax[enabled] = true`, transactions created through the [Stripe Tax API](https://docs.stripe.com/tax/standalone-tax-api.md), and transactions sent through [tax transaction imports](https://docs.stripe.com/tax/imports.md). Anything that bypassed Stripe Tax (raw `PaymentIntent`s and Charges without an invoice, invoices with manual or no tax, chargebacks, or payments through other systems) won’t appear, even if the same dollars show up in Payments or Revenue Recognition reports. ## Comparing reports across periods Report totals for a past period can change between runs. This section explains why. ### Changes on closed period totals A few things can change historical totals after you’ve already pulled a report: - **Tax API commits in a later period.** If you call `/v1/tax/calculations` in one period and `/v1/tax/transactions/create_from_calculation` in a later one, location reports record the liability against the calculation date (`tax_date`) while itemized and summarized exports record it against the commit date (`transaction_date`). Each new commit can shift past-period totals on a location report. - **Imports for past dates.** [Tax transaction imports](https://docs.stripe.com/tax/imports.md), including a corrected re-upload with a higher `version` number, are dated by the values in the file. Imports backfilled to past periods land in those periods’ reports the next time you run them. Stripe doesn’t rewrite reports retroactively when a tax rule or rate later changes. After a transaction is recorded with a given tax amount, it stays that way. ## Time zones You can only reconcile reports across different time zones by re-exporting one of them. Itemized and summarized exports remember the time zone you selected at export time, and a transaction near midnight UTC can fall into different periods depending on which time zone is in effect. Location reports are always UTC, so when comparing against them, re-export the itemized or summarized report in UTC as well. ## Connect platforms Connect platforms have additional considerations when reconciling tax data across accounts. ### Transactions in location reports Location reports only apply to transactions that ran through Stripe Tax (`automatic_tax[enabled] = true` for the relevant object). If a connected account’s transactions weren’t tax-calculated by Stripe, they won’t appear. See [Tax for software platforms](https://docs.stripe.com/tax/tax-for-platforms.md). ### Pull itemized data through the API Connect platforms can run the itemized export through the [Reports API](https://docs.stripe.com/reports/api.md) instead of the Dashboard. Use `tax.transactions.itemized.2` for the transactions the platform is liable for, or `connected_account_tax.transactions.itemized.2` (with `parameters[connected_account]` set) to pull rows on behalf of a connected account that’s liable. Both schemas are a subset of the Dashboard itemized export — some fields like origin-level address, UTC timestamps, and `refund_id` on voids aren’t included. The reconciliation mapping in [Reconcile an itemized export against a summarized export](https://docs.stripe.com/tax/reports/reconcile.md#reconcile-an-itemized-export-against-a-summarized-export) still works, just against the columns that ship in the API output. ## Dashboard The Dashboard displays tax data differently than exports. These differences are by design, not errors. ### Tax Overview tab The [Tax Overview](https://dashboard.stripe.com/tax) tab always uses UTC and shows totals in your settlement currency, regardless of any time zone or currency choices elsewhere. If you exported in a different time zone or want totals in the filing or integration currency, the numbers won’t match the Overview tab. For reconciliation, use an itemized or summarized export, and re-run it in UTC if you need to compare against the Overview tab directly. ### Tax Transactions page The [Tax Transactions](https://dashboard.stripe.com/tax/transactions) page lists individual tax transactions, with a detailed view that breaks each one down by jurisdiction and line item. It’s the right place to inspect what Stripe calculated and committed for a single transaction, not to reconcile against an export or report. The itemized export covers the same transactions but expands each one into one row per jurisdiction, so the way to validate a Dashboard transaction is to find it in the itemized export by id and confirm the per-jurisdiction breakdown matches the detail view. Summing the list-view totals and trying to match them to a report doesn’t work because the views are shaped differently.