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 | Every line item of each tax transaction |
| Summarized export | Tax transaction line items aggregated into totals per jurisdiction |
| Location report | Tax transaction data formatted for a specific filing portal (supported US states and Canadian registrations) |
Caution
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_, total, and so on) and filing (filing_, filing_) | Both integration (total_) and filing (filing_) | 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.
Filter the itemized export to match what the summarized export includes
Summarized exports always exclude transactions with these
taxability_values:reason 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_, andterritory product_). To get a clean match, also drop any rows whosenot_ supported taxability_isreason not_,collecting not_, orsubject_ to_ tax not_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.supported Voided transactions don’t need special handling. They’re subtracted from all totals automatically, so they cancel against the original transaction.
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_, andrate transaction_. Then sum using this mapping:currency Summarized column Equivalent in itemized export total_sales SUM(gross_over rows whereamount) transaction_type = 'transaction' totalSUM(total)over rows wheretransaction_type = 'transaction' total_taxable_ sales SUM(taxable_over rows whereamount) transaction_type = 'transaction' total_nontaxable_ sales SUM(non_over rows wheretaxable_ amount) transaction_type = 'transaction' total_tax_ payable SUM(tax_over rows whereamount) transaction_type = 'transaction' total_sales_ refunded SUM(gross_over rows whereamount) transaction_type = 'reversal' total_taxable_ refunded SUM(filing_over rows wheretaxable_ amount) transaction_(filing currency)type = 'reversal' total_tax_ refunded SUM(tax_over rows whereamount) transaction_type = 'reversal' filing_tax_ payable SUM(filing_over transactions, minustax_ amount) SUM(filing_over reversalstax_ amount) 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_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,code AB,BC,ON). This means the standard six-column key won’t join these rows.To reconcile Canadian federal tax rows:
- Identify rows in both reports where
country_,code = 'CA' jurisdiction_, andlevel = 'country' jurisdiction_.name = 'CANADA' - For those rows only, drop
state_from the grouping key. Group bycode country_,code jurisdiction_,name jurisdiction_,level tax_, andrate transaction_(five columns instead of six).currency - Sum and compare as normal using the mapping above.
Provincial-level rows (where
jurisdiction_islevel state) are not affected — both reports populatestate_consistently.code - Identify rows in both reports where
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_ values that the itemized export’s “Exclude non-taxable” toggle leaves in: not_, not_, and not_. 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_, total, taxable_, non_) 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_ and filing_ 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), or deduplicate by id and line_ 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_, transactions created through the Stripe Tax API, and transactions sent through tax transaction imports. Anything that bypassed Stripe Tax (raw PaymentIntents 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/calculationsin one period and/v1/tax/transactions/create_in a later one, location reports record the liability against the calculation date (from_ calculation tax_) while itemized and summarized exports record it against the commit date (date transaction_). Each new commit can shift past-period totals on a location report.date - Imports for past dates. Tax transaction imports, including a corrected re-upload with a higher
versionnumber, 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_ 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.
Pull itemized data through the API
Connect platforms can run the itemized export through the Reports API instead of the Dashboard. Use tax. for the transactions the platform is liable for, or connected_ (with parameters[connected_ 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_ on voids aren’t included. The reconciliation mapping in 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 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 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.