Schemas and export layouts
See which fields ScanToExcel extracts and how they appear in your downloads. A supported field is not a guarantee that your document contains it or that extraction will populate it.
On every plan, export templates use English headers and field names. Extracted text and source-table headers generally stay in the document’s language. Changing the website language does not translate downloads. JSON keys, predefined worksheet labels and accounting-template headers remain fixed. Dates, numbers, currency codes and some categories may be standardized; review the output.
Choose your output
- JSON
- JSON keeps nested document data, including lists of items and transactions. The downloaded file is the document object, without quota or file-transfer metadata. Flat settings do not change JSON.
- Flat
- Flat exports use a rectangular grid of rows and consistent columns. Each row represents an item or transaction, with document details repeated where needed. Every table has its own fixed column structure; Excel can contain multiple sheets, while CSV contains one grid.
- Non-flat
- Non-flat Excel and CSV exports place separate tables side by side, each with its own purpose and columns: document details, items, taxes, totals or warnings. They do not form one uniform data table. Word stacks these tables vertically. Paystubs and table images use dedicated layouts.
| Document | JSON | Layout | Xero CSV | QuickBooks CSV |
|---|---|---|---|---|
| Receipt | Yes | Flat / Non-flat | Yes | No |
| Invoice/Bill | Yes | Flat / Non-flat | Yes | No |
| Bank Statement | Yes | Flat / Non-flat | Yes | Yes |
| Credit Card Statement | Yes | Flat / Non-flat | Yes | Yes |
| Paystub/Payslip | Yes | Dedicated layout | No | No |
| Image of Table | Yes | Dedicated layout | No | No |
Accounting CSVs are Premium output options with their own templates. They produce downloadable files, not a direct connection to Xero or QuickBooks. Review fields and account mappings before importing. Pricing
Receipt
Vendor, date, currency, receipt number, item quantities and prices, taxes, payment method and totals. Tax rate values are fractions: 0.20 means 20%.
JSON fields
Types describe serialized JSON. Parent objects and arrays are listed before their children; [] marks repeated entries. Defaulted fields need not be supplied by extraction. Decimal values serialize as strings. Downloads retain defaulted fields; a missing extracted value is not the same as an omitted JSON key.
| Field path | JSON type | Presence |
|---|---|---|
vendor | string | null | Defaulted |
date | string | null | Defaulted |
currency | string | null | Defaulted |
document_number | string | null | Defaulted |
subtotal | string | null | Defaulted |
tax | string | null | Defaulted |
tax_inclusive | boolean | null | Defaulted |
tip | string | null | Defaulted |
payment_method | string | null | Defaulted |
total | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
line_items | array<object> | Defaulted |
line_items[].description | string | null | Defaulted |
line_items[].quantity | string | null | Defaulted |
line_items[].unit_price | string | null | Defaulted |
line_items[].total | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
taxes | array<object> | Defaulted |
taxes[].name | string | null | Defaulted |
taxes[].rate | string | null | Defaulted |
taxes[].base | string | null | Defaulted |
taxes[].amount | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
reconciliation_warnings | array<string> | Defaulted |
Flat
Flat includes item rows and a separate document summary in Excel. CSV contains only the item rows. Tax and tip adjustments can add rows: their line_total comes from tax, taxes[].amount or tip; their description is generated and their quantity, unit_price and line_no are blank.
| Output field | JSON source or export rule |
|---|---|
| doc_id | doc_id |
| source_filename | source_filename |
| vendor | vendor |
| date | date |
| currency | currency |
| document_number | document_number |
| line_no | index(line_items[]) + 1 |
| description | line_items[].description |
| quantity | line_items[].quantity |
| unit_price | line_items[].unit_price |
| line_total | line_items[].total |
| row_type | line | adjustment |
| Output field | JSON source or export rule |
|---|---|
| doc_id | doc_id |
| source_filename | source_filename |
| vendor | vendor |
| date | date |
| currency | currency |
| document_number | document_number |
| subtotal | subtotal |
| tax | tax |
| tax_inclusive | tax_inclusive |
| tip | tip |
| payment_method | payment_method |
| total | total |
| tax_breakdown | join(taxes[].name, taxes[].rate, taxes[].amount) |
| warnings | join(reconciliation_warnings[]) |
Non-flat
Non-flat places these tables side by side. Document details and totals use field/value rows; items and taxes use columns. Warnings appear only when present. unit_price is not included in the non-flat item table.
| Output field | JSON source or export rule |
|---|---|
| # | index(line_items[]) + 1 |
| Description | line_items[].description |
| Qty | line_items[].quantity |
| Line total | line_items[].total |
| Output field | JSON source or export rule |
|---|---|
| Doc ID | doc_id |
| Source | source_filename |
| Vendor | vendor |
| Date | date |
| Currency | currency |
| Document # | document_number |
| Payment method | payment_method |
| Output field | JSON source or export rule |
|---|---|
| Name | taxes[].name |
| Rate | taxes[].rate |
| Base | taxes[].base |
| Amount | taxes[].amount |
| Output field | JSON source or export rule |
|---|---|
| Subtotal | subtotal |
| Tax | tax |
| Tax inclusive | tax_inclusive |
| Tip | tip |
| Total | total |
| Output field | JSON source or export rule |
|---|---|
| # | index(reconciliation_warnings[]) + 1 |
| Warning | reconciliation_warnings[] |
Xero CSV
One summarized row per receipt. Fields without a source below are exported blank, including AccountCode and TaxType. Complete the required mappings before importing.
| Output field | JSON source or export rule |
|---|---|
| *ContactName | vendor || "Unknown vendor" |
| EmailAddress | Left blank |
| POAddressLine1 | Left blank |
| POAddressLine2 | Left blank |
| POAddressLine3 | Left blank |
| POAddressLine4 | Left blank |
| POCity | Left blank |
| PORegion | Left blank |
| POPostalCode | Left blank |
| POCountry | Left blank |
| *InvoiceNumber | document_number || "RCP-" + doc_id |
| Reference | "Receipt" |
| *InvoiceDate | date → DD/MM/YYYY |
| *DueDate | date → DD/MM/YYYY |
| Total | Left blank |
| InventoryItemCode | Left blank |
| *Description | join(line_items[].description) || vendor || "Receipt"; tip → "(incl. tip)" |
| *Quantity | 1 |
| *UnitAmount | subtotal / total / tax / tax_inclusive / tip |
| Discount | Left blank |
| *AccountCode | Left blank |
| *TaxType | Left blank |
| TaxAmount | tax (0 → blank) |
| TrackingName1 | Left blank |
| TrackingOption1 | Left blank |
| TrackingName2 | Left blank |
| TrackingOption2 | Left blank |
| Currency | currency |
| BrandingTheme | Left blank |
UnitAmount uses total (falling back to subtotal) when tax_inclusive is true. Otherwise it uses subtotal, or total minus tax when subtotal is missing. Missing amounts can fall back to zero. The exporter then adds tip. Review tax and tip handling before import.
QuickBooks CSV
No
Invoice/Bill
Invoice dates and references, sender and receiver details, line items, taxes, discounts, withholdings and totals. unit is the printed unit of measure; tax_rate is a fraction.
JSON fields
Types describe serialized JSON. Parent objects and arrays are listed before their children; [] marks repeated entries. Defaulted fields need not be supplied by extraction. Decimal values serialize as strings. Downloads retain defaulted fields; a missing extracted value is not the same as an omitted JSON key.
| Field path | JSON type | Presence |
|---|---|---|
invoice_number | string | null | Defaulted |
issue_date | string | null | Defaulted |
due_date | string | null | Defaulted |
currency | string | null | Defaulted |
payment_terms | string | null | Defaulted |
purchase_order | string | null | Defaulted |
notes | string | null | Defaulted |
subtotal | string | null | Defaulted |
discount | string | null | Defaulted |
tax | string | null | Defaulted |
tax_inclusive | boolean | null | Defaulted |
withholdings | string | null | Defaulted |
total | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
sender | object | null | Defaulted |
sender.name | string | null | Defaulted |
sender.address | object | null | Defaulted |
sender.address.line1 | string | null | Defaulted |
sender.address.line2 | string | null | Defaulted |
sender.address.city | string | null | Defaulted |
sender.address.region | string | null | Defaulted |
sender.address.postal_code | string | null | Defaulted |
sender.address.country | string | null | Defaulted |
sender.address.raw | string | null | Defaulted |
sender.tax_id | string | null | Defaulted |
sender.email | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
receiver | object | null | Defaulted |
receiver.name | string | null | Defaulted |
receiver.address | object | null | Defaulted |
receiver.address.line1 | string | null | Defaulted |
receiver.address.line2 | string | null | Defaulted |
receiver.address.city | string | null | Defaulted |
receiver.address.region | string | null | Defaulted |
receiver.address.postal_code | string | null | Defaulted |
receiver.address.country | string | null | Defaulted |
receiver.address.raw | string | null | Defaulted |
receiver.tax_id | string | null | Defaulted |
receiver.email | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
line_items | array<object> | Defaulted |
line_items[].description | string | null | Defaulted |
line_items[].quantity | string | null | Defaulted |
line_items[].unit | string | null | Defaulted |
line_items[].unit_price | string | null | Defaulted |
line_items[].total | string | null | Defaulted |
line_items[].tax_rate | string | null | Defaulted |
line_items[].tax_amount | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
taxes | array<object> | Defaulted |
taxes[].name | string | null | Defaulted |
taxes[].rate | string | null | Defaulted |
taxes[].base | string | null | Defaulted |
taxes[].amount | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
reconciliation_warnings | array<string> | Defaulted |
The tables map output fields to JSON paths. || means the first nonempty value; ?? means a fallback for null. Numbering, combined descriptions and formatting are export rules. Missing values generally become blank cells.
Flat exports have one line-item grid with repeated invoice details. Non-flat groups invoice details, parties, items, tax breakdown, totals and warnings; Word arranges sections vertically.
Flat
Lines contains one row per item with repeated invoice details. Additional adjustment rows use −discount, taxes[].amount (or tax) when tax_inclusive is not true, and −withholdings. Their descriptions are generated; line_no, quantity, unit and unit_price are blank. An invoice without items still produces a document row.
| Output field | JSON source or export rule |
|---|---|
| doc_id | doc_id |
| source_filename | source_filename |
| invoice_number | invoice_number |
| issue_date | issue_date |
| due_date | due_date |
| currency | currency |
| sender | sender.name |
| receiver | receiver.name |
| line_no | index(line_items[]) + 1 |
| description | line_items[].description |
| quantity | line_items[].quantity |
| unit | line_items[].unit |
| unit_price | line_items[].unit_price |
| line_total | line_items[].total |
| tax_rate | line_items[].tax_rate |
| tax_amount | line_items[].tax_amount |
| row_type | line | adjustment |
Non-flat
These tables sit side by side in Excel and CSV; Word stacks them. The current Excel item table omits Line total. CSV and Word include it. Document details and totals use field/value rows. Warnings appear only when present.
| Output field | JSON source or export rule |
|---|---|
| # | index(line_items[]) + 1 |
| Description | line_items[].description |
| Qty | line_items[].quantity |
| Unit | line_items[].unit |
| Unit price | line_items[].unit_price |
| Tax rate | line_items[].tax_rate |
| Tax amount | line_items[].tax_amount |
| Line total | line_items[].total |
| Output field | JSON source or export rule |
|---|---|
| Doc ID | doc_id |
| Source | source_filename |
| Invoice # | invoice_number |
| Issue date | issue_date |
| Due date | due_date |
| Currency | currency |
| Payment terms | payment_terms |
| PO # | purchase_order |
| Sender | sender.name |
| Sender tax ID | sender.tax_id |
| Sender address | sender.address.raw || join(sender.address.line1, line2, city, region, postal_code, country) |
| Receiver | receiver.name |
| Receiver tax ID | receiver.tax_id |
| Receiver address | receiver.address.raw || join(receiver.address.line1, line2, city, region, postal_code, country) |
| Output field | JSON source or export rule |
|---|---|
| Name | taxes[].name |
| Rate | taxes[].rate |
| Base | taxes[].base |
| Amount | taxes[].amount |
| Output field | JSON source or export rule |
|---|---|
| Subtotal | subtotal |
| Discount | discount |
| Tax | tax |
| Tax inclusive | tax_inclusive |
| Withholdings | withholdings |
| Total | total |
| Output field | JSON source or export rule |
|---|---|
| # | index(reconciliation_warnings[]) + 1 |
| Warning | reconciliation_warnings[] |
Xero CSV
One row per line item, with receiver details repeated. If there are no items, one fallback row uses notes (or “Invoice”) as Description, 1 as Quantity, total (or subtotal) as UnitAmount, and tax as TaxAmount. Zero TaxAmount values are blank. Unmapped columns are left blank; no separate discount or withholding adjustment rows are added.
| Output field | JSON source or export rule |
|---|---|
| *ContactName | receiver.name || "Unknown customer" |
| EmailAddress | receiver.email |
| POAddressLine1 | receiver.address.line1 |
| POAddressLine2 | receiver.address.line2 |
| POAddressLine3 | Left blank |
| POAddressLine4 | Left blank |
| POCity | receiver.address.city |
| PORegion | receiver.address.region |
| POPostalCode | receiver.address.postal_code |
| POCountry | receiver.address.country |
| *InvoiceNumber | invoice_number || "INV-" + doc_id |
| Reference | purchase_order |
| *InvoiceDate | issue_date → DD/MM/YYYY |
| *DueDate | (due_date || issue_date) → DD/MM/YYYY |
| Total | Left blank |
| InventoryItemCode | Left blank |
| *Description | line_items[].description |
| *Quantity | line_items[].quantity ?? 1 |
| *UnitAmount | line_items[].unit_price ?? (line_items[].total / (line_items[].quantity || 1)) |
| Discount | Left blank |
| *AccountCode | Left blank |
| *TaxType | Left blank |
| TaxAmount | line_items[].tax_amount (0 → "") |
| TrackingName1 | Left blank |
| TrackingOption1 | Left blank |
| TrackingName2 | Left blank |
| TrackingOption2 | Left blank |
| Currency | currency |
| BrandingTheme | Left blank |
QuickBooks CSV
No
Bank Statement
Issuer, statement period and accounts, each with identity, balances, totals and transactions. trnamt is signed: withdrawals are negative and deposits positive. dtposted is the posting date; dtuser is the value date.
JSON fields
Types describe serialized JSON. Parent objects and arrays are listed before their children; [] marks repeated entries. Defaulted fields need not be supplied by extraction. Decimal values serialize as strings. Downloads retain defaulted fields; a missing extracted value is not the same as an omitted JSON key.
| Field path | JSON type | Presence |
|---|---|---|
issuer | object | Defaulted |
issuer.name | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
statement | object | Defaulted |
statement.statement_date | string | null | Defaulted |
statement.period_start | string | null | Defaulted |
statement.period_end | string | null | Defaulted |
statement.currency_default | string | null | Defaulted |
statement.page_count | integer | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
accounts | array<object> | Defaulted |
accounts[].holder | object | Defaulted |
accounts[].holder.name | string | null | Defaulted |
accounts[].account | object | Defaulted |
accounts[].account.account_number | string | null | Defaulted |
accounts[].account.account_number_masked | string | null | Defaulted |
accounts[].account.iban | string | null | Defaulted |
accounts[].account.bic | string | null | Defaulted |
accounts[].account.sort_code | string | null | Defaulted |
accounts[].account.account_type | string | null | Defaulted |
accounts[].account.account_name | string | null | Defaulted |
accounts[].account.currency | string | null | Defaulted |
accounts[].account.card_last4 | string | null | Defaulted |
accounts[].balances | object | Defaulted |
accounts[].balances.opening | object | Defaulted |
accounts[].balances.opening.amount | string | null | Defaulted |
accounts[].balances.opening.as_of | string | null | Defaulted |
accounts[].balances.closing | object | Defaulted |
accounts[].balances.closing.amount | string | null | Defaulted |
accounts[].balances.closing.as_of | string | null | Defaulted |
accounts[].balances.available | string | null | Defaulted |
accounts[].totals | object | Defaulted |
accounts[].totals.credits_count | integer | null | Defaulted |
accounts[].totals.credits_amount | string | null | Defaulted |
accounts[].totals.debits_count | integer | null | Defaulted |
accounts[].totals.debits_amount | string | null | Defaulted |
accounts[].totals.fees_charged | string | null | Defaulted |
accounts[].totals.interest_paid | string | null | Defaulted |
accounts[].totals.interest_charged | string | null | Defaulted |
accounts[].transactions | array<object> | Defaulted |
accounts[].transactions[].trntype | string | null | Defaulted |
accounts[].transactions[].dtposted | string | null | Defaulted |
accounts[].transactions[].dtuser | string | null | Defaulted |
accounts[].transactions[].trnamt | string | null | Defaulted |
accounts[].transactions[].name | string | null | Defaulted |
accounts[].transactions[].memo | string | null | Defaulted |
accounts[].transactions[].running_balance | string | null | Defaulted |
accounts[].transactions[].fitid | string | null | Defaulted |
accounts[].transactions[].refnum | string | null | Defaulted |
accounts[].transactions[].checknum | string | null | Defaulted |
accounts[].transactions[].card_last4 | string | null | Defaulted |
accounts[].transactions[].fee | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
reconciliation_warnings | array<string> | Defaulted |
The tables map output fields to JSON paths. || means the first nonempty value; ?? means a fallback for null. Numbering, combined descriptions and formatting are export rules. Missing values generally become blank cells.
Flat exports contain transaction rows with repeated statement and account details. Non-flat output groups statement details and each account’s transactions, balances and totals. Account sections depend on the document.
Flat
Transactions repeats document and account details for each transaction. If transactions or accounts are missing, the flat exporter still writes an identity row with blank transaction fields.
| Output field | JSON source or export rule |
|---|---|
| doc_id | doc_id |
| source_filename | source_filename |
| bank | issuer.name |
| account_holder | accounts[].holder.name |
| account_number | accounts[].account.account_number_masked || accounts[].account.account_number || accounts[].account.iban |
| account_type | accounts[].account.account_type |
| currency | accounts[].account.currency || statement.currency_default |
| period_start | statement.period_start |
| period_end | statement.period_end |
| txn_no | index(accounts[].transactions[]) + 1 |
| date | accounts[].transactions[].dtposted |
| value_date | accounts[].transactions[].dtuser |
| description | joinDistinct(accounts[].transactions[].name, accounts[].transactions[].memo, " - ") |
| reference | accounts[].transactions[].refnum |
| check_number | accounts[].transactions[].checknum |
| type | accounts[].transactions[].trntype |
| amount | accounts[].transactions[].trnamt |
| fee | accounts[].transactions[].fee |
| running_balance | accounts[].transactions[].running_balance |
Non-flat
Each account has its own transaction and detail tables, placed side by side in Excel and CSV. Statement details accompany the first account; warnings appear only when present. Word stacks the sections. Field/value rows are shown individually below.
| Output field | JSON source or export rule |
|---|---|
| # | index(accounts[].transactions[]) + 1 |
| Date | accounts[].transactions[].dtposted |
| Value date | accounts[].transactions[].dtuser |
| Description | joinDistinct(accounts[].transactions[].name, accounts[].transactions[].memo, " - ") |
| Reference | accounts[].transactions[].refnum |
| Check # | accounts[].transactions[].checknum |
| Type | accounts[].transactions[].trntype |
| Amount | accounts[].transactions[].trnamt |
| Running balance | accounts[].transactions[].running_balance |
| Output field | JSON source or export rule |
|---|---|
| Holder | accounts[].holder.name |
| Account name | accounts[].account.account_name |
| Account number | accounts[].account.account_number_masked || accounts[].account.account_number |
| IBAN | accounts[].account.iban |
| BIC | accounts[].account.bic |
| Sort code | accounts[].account.sort_code |
| Card last 4 | accounts[].account.card_last4 |
| Account type | accounts[].account.account_type |
| Currency | accounts[].account.currency |
| Output field | JSON source or export rule |
|---|---|
| Opening | accounts[].balances.opening.amount |
| Opening as of | accounts[].balances.opening.as_of |
| Closing | accounts[].balances.closing.amount |
| Closing as of | accounts[].balances.closing.as_of |
| Available | accounts[].balances.available |
| Output field | JSON source or export rule |
|---|---|
| Credits count | accounts[].totals.credits_count |
| Credits amount | accounts[].totals.credits_amount |
| Debits count | accounts[].totals.debits_count |
| Debits amount | accounts[].totals.debits_amount |
| Fees charged | accounts[].totals.fees_charged |
| Interest paid | accounts[].totals.interest_paid |
| Interest charged | accounts[].totals.interest_charged |
| Output field | JSON source or export rule |
|---|---|
| Doc ID | doc_id |
| Source | source_filename |
| Bank | issuer.name |
| Statement date | statement.statement_date |
| Period start | statement.period_start |
| Period end | statement.period_end |
| Page count | statement.page_count |
| Output field | JSON source or export rule |
|---|---|
| # | index(reconciliation_warnings[]) + 1 |
| Warning | reconciliation_warnings[] |
Both exports combine transactions from all accounts. Xero skips null amounts; QuickBooks skips null and zero amounts. QuickBooks uses memo before name; a numeric-only description receives a trntype, name or “Txn” prefix. Credit-card amounts have their sign reversed. The files do not include a separate account-identity column.
Xero CSV
| Output field | JSON source or export rule |
|---|---|
| *Date | accounts[].transactions[].dtposted → DD/MM/YYYY |
| *Amount | accounts[].transactions[].trnamt |
| Payee | accounts[].transactions[].name |
| Description | joinDistinct(accounts[].transactions[].name, accounts[].transactions[].memo, " - ") |
| Reference | accounts[].transactions[].refnum |
| Cheque Number | accounts[].transactions[].checknum |
| Account code* | Left blank |
| Tax Rate (Display Name)* | Left blank |
| Tracking1 | Left blank |
| Tracking2 | Left blank |
| Transaction Type | accounts[].transactions[].trntype |
| Analysis code | Left blank |
QuickBooks CSV
| Output field | JSON source or export rule |
|---|---|
| Date | accounts[].transactions[].dtposted → DD/MM/YYYY |
| Description | accounts[].transactions[].memo || accounts[].transactions[].name || accounts[].transactions[].trntype || "Transaction" |
| Amount | accounts[].transactions[].trnamt |
Credit Card Statement
Issuer, statement period, account details, balances, credit limits, activity summaries and transactions. trnamt uses the opposite purchase convention to bank statements: charges are positive; payments and refunds are negative.
JSON fields
Types describe serialized JSON. Parent objects and arrays are listed before their children; [] marks repeated entries. Defaulted fields need not be supplied by extraction. Decimal values serialize as strings. Downloads retain defaulted fields; a missing extracted value is not the same as an omitted JSON key.
| Field path | JSON type | Presence |
|---|---|---|
issuer | object | Defaulted |
issuer.name | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
statement | object | Defaulted |
statement.statement_date | string | null | Defaulted |
statement.period_start | string | null | Defaulted |
statement.period_end | string | null | Defaulted |
statement.currency_default | string | null | Defaulted |
statement.page_count | integer | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
accounts | array<object> | Defaulted |
accounts[].holder | object | Defaulted |
accounts[].holder.name | string | null | Defaulted |
accounts[].account | object | Defaulted |
accounts[].account.account_number | string | null | Defaulted |
accounts[].account.account_number_masked | string | null | Defaulted |
accounts[].account.card_last4 | string | null | Defaulted |
accounts[].account.bin | string | null | Defaulted |
accounts[].account.card_network | string | null | Defaulted |
accounts[].account.card_brand | string | null | Defaulted |
accounts[].account.card_product | string | null | Defaulted |
accounts[].account.card_type | string | null | Defaulted |
accounts[].account.currency | string | null | Defaulted |
accounts[].balances | object | Defaulted |
accounts[].balances.previous_balance | object | Defaulted |
accounts[].balances.previous_balance.amount | string | null | Defaulted |
accounts[].balances.previous_balance.as_of | string | null | Defaulted |
accounts[].balances.new_balance | object | Defaulted |
accounts[].balances.new_balance.amount | string | null | Defaulted |
accounts[].balances.new_balance.as_of | string | null | Defaulted |
accounts[].balances.statement_balance | string | null | Defaulted |
accounts[].balances.minimum_payment_due | string | null | Defaulted |
accounts[].balances.payment_due_date | string | null | Defaulted |
accounts[].balances.past_due_amount | string | null | Defaulted |
accounts[].credit_limits | object | Defaulted |
accounts[].credit_limits.credit_limit | string | null | Defaulted |
accounts[].credit_limits.available_credit | string | null | Defaulted |
accounts[].credit_limits.cash_advance_limit | string | null | Defaulted |
accounts[].credit_limits.available_cash | string | null | Defaulted |
accounts[].credit_limits.over_limit_amount | string | null | Defaulted |
accounts[].summary | object | Defaulted |
accounts[].summary.previous_balance | string | null | Defaulted |
accounts[].summary.payments | string | null | Defaulted |
accounts[].summary.credits_returns | string | null | Defaulted |
accounts[].summary.purchases | string | null | Defaulted |
accounts[].summary.cash_advances | string | null | Defaulted |
accounts[].summary.balance_transfers | string | null | Defaulted |
accounts[].summary.fees_charged | string | null | Defaulted |
accounts[].summary.interest_charged | string | null | Defaulted |
accounts[].summary.adjustments | string | null | Defaulted |
accounts[].summary.new_balance | string | null | Defaulted |
accounts[].transactions | array<object> | Defaulted |
accounts[].transactions[].trntype | string | null | Defaulted |
accounts[].transactions[].dtposted | string | null | Defaulted |
accounts[].transactions[].dtuser | string | null | Defaulted |
accounts[].transactions[].trnamt | string | null | Defaulted |
accounts[].transactions[].name | string | null | Defaulted |
accounts[].transactions[].memo | string | null | Defaulted |
accounts[].transactions[].fitid | string | null | Defaulted |
accounts[].transactions[].refnum | string | null | Defaulted |
accounts[].transactions[].card_last4 | string | null | Defaulted |
accounts[].transactions[].cardholder_name | string | null | Defaulted |
accounts[].transactions[].is_foreign | boolean | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
reconciliation_warnings | array<string> | Defaulted |
The tables map output fields to JSON paths. || means the first nonempty value; ?? means a fallback for null. Numbering, combined descriptions and formatting are export rules. Missing values generally become blank cells.
Flat exports contain transaction rows with repeated statement and account fields. Non-flat output includes account sections for transactions, balances, limits and summaries. Multiple accounts change the number of sections.
Flat
Transactions repeats document and account details for each transaction. If transactions or accounts are missing, the flat exporter still writes an identity row with blank transaction fields.
| Output field | JSON source or export rule |
|---|---|
| doc_id | doc_id |
| source_filename | source_filename |
| issuer | issuer.name |
| cardholder | accounts[].transactions[].cardholder_name || accounts[].holder.name |
| card_last4 | accounts[].transactions[].card_last4 || accounts[].account.card_last4 |
| card_network | accounts[].account.card_network |
| card_brand | accounts[].account.card_brand |
| currency | accounts[].account.currency || statement.currency_default |
| period_start | statement.period_start |
| period_end | statement.period_end |
| txn_no | index(accounts[].transactions[]) + 1 |
| date | accounts[].transactions[].dtposted |
| posted_date | accounts[].transactions[].dtuser |
| description | joinDistinct(accounts[].transactions[].name, accounts[].transactions[].memo, " - ") |
| reference | accounts[].transactions[].refnum |
| type | accounts[].transactions[].trntype |
| amount | accounts[].transactions[].trnamt |
| is_foreign | accounts[].transactions[].is_foreign → Yes / No / "" |
Non-flat
Each account has its own transaction and detail tables, placed side by side in Excel and CSV. Statement details accompany the first account; warnings appear only when present. Word stacks the sections. Field/value rows are shown individually below.
| Output field | JSON source or export rule |
|---|---|
| # | index(accounts[].transactions[]) + 1 |
| Date | accounts[].transactions[].dtposted |
| Posted | accounts[].transactions[].dtuser |
| Description | joinDistinct(accounts[].transactions[].name, accounts[].transactions[].memo, " - ") |
| Reference | accounts[].transactions[].refnum |
| Type | accounts[].transactions[].trntype |
| Card last 4 | accounts[].transactions[].card_last4 || accounts[].account.card_last4 |
| Amount | accounts[].transactions[].trnamt |
| Output field | JSON source or export rule |
|---|---|
| Holder | accounts[].holder.name |
| Card last 4 | accounts[].account.card_last4 |
| Card network | accounts[].account.card_network |
| Card brand | accounts[].account.card_brand |
| Card product | accounts[].account.card_product |
| Card type | accounts[].account.card_type |
| Account number | accounts[].account.account_number_masked || accounts[].account.account_number |
| Currency | accounts[].account.currency |
| Output field | JSON source or export rule |
|---|---|
| Previous balance | accounts[].balances.previous_balance.amount |
| Previous balance as of | accounts[].balances.previous_balance.as_of |
| New balance | accounts[].balances.new_balance.amount |
| New balance as of | accounts[].balances.new_balance.as_of |
| Statement balance | accounts[].balances.statement_balance |
| Minimum payment | accounts[].balances.minimum_payment_due |
| Payment due date | accounts[].balances.payment_due_date |
| Past due | accounts[].balances.past_due_amount |
| Output field | JSON source or export rule |
|---|---|
| Credit limit | accounts[].credit_limits.credit_limit |
| Available credit | accounts[].credit_limits.available_credit |
| Cash advance limit | accounts[].credit_limits.cash_advance_limit |
| Available cash | accounts[].credit_limits.available_cash |
| Over limit | accounts[].credit_limits.over_limit_amount |
| Output field | JSON source or export rule |
|---|---|
| Previous balance | accounts[].summary.previous_balance |
| Payments | accounts[].summary.payments |
| Credits / returns | accounts[].summary.credits_returns |
| Purchases | accounts[].summary.purchases |
| Cash advances | accounts[].summary.cash_advances |
| Balance transfers | accounts[].summary.balance_transfers |
| Fees charged | accounts[].summary.fees_charged |
| Interest charged | accounts[].summary.interest_charged |
| Adjustments | accounts[].summary.adjustments |
| New balance | accounts[].summary.new_balance |
| Output field | JSON source or export rule |
|---|---|
| Doc ID | doc_id |
| Source | source_filename |
| Issuer | issuer.name |
| Statement date | statement.statement_date |
| Period start | statement.period_start |
| Period end | statement.period_end |
| Page count | statement.page_count |
| Output field | JSON source or export rule |
|---|---|
| # | index(reconciliation_warnings[]) + 1 |
| Warning | reconciliation_warnings[] |
Both exports combine transactions from all accounts. Xero skips null amounts; QuickBooks skips null and zero amounts. QuickBooks uses memo before name; a numeric-only description receives a trntype, name or “Txn” prefix. Credit-card amounts have their sign reversed. The files do not include a separate account-identity column.
Xero CSV
| Output field | JSON source or export rule |
|---|---|
| *Date | accounts[].transactions[].dtposted → DD/MM/YYYY |
| *Amount | −accounts[].transactions[].trnamt |
| Payee | accounts[].transactions[].name |
| Description | joinDistinct(accounts[].transactions[].name, accounts[].transactions[].memo, " - ") |
| Reference | accounts[].transactions[].refnum |
| Cheque Number | Left blank |
| Account code* | Left blank |
| Tax Rate (Display Name)* | Left blank |
| Tracking1 | Left blank |
| Tracking2 | Left blank |
| Transaction Type | accounts[].transactions[].trntype |
| Analysis code | Left blank |
QuickBooks CSV
| Output field | JSON source or export rule |
|---|---|
| Date | accounts[].transactions[].dtposted → DD/MM/YYYY |
| Description | accounts[].transactions[].memo || accounts[].transactions[].name || accounts[].transactions[].trntype || "Transaction" |
| Amount | −accounts[].transactions[].trnamt |
Paystub/Payslip
Pay period, employee and employer, rates, earnings, deductions, taxes, employer contributions and totals. current_amount refers to this period; ytd_amount is year to date.
JSON fields
Types describe serialized JSON. Parent objects and arrays are listed before their children; [] marks repeated entries. Defaulted fields need not be supplied by extraction. Decimal values serialize as strings. Downloads retain defaulted fields; a missing extracted value is not the same as an omitted JSON key.
| Field path | JSON type | Presence |
|---|---|---|
statement | object | Defaulted |
statement.issue_date | string | null | Defaulted |
statement.pay_date | string | null | Defaulted |
statement.period_start | string | null | Defaulted |
statement.period_end | string | null | Defaulted |
statement.period_type | string | null | Defaulted |
statement.tax_year | integer | null | Defaulted |
statement.currency | string | null | Defaulted |
statement.country | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
employee | object | Defaulted |
employee.name | string | null | Defaulted |
employee.pay_frequency | string | null | Defaulted |
employee.employment_type | string | null | Defaulted |
employee.employment_status | string | null | Defaulted |
employee.filing_status | string | null | Defaulted |
employee.tax_code | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
employer | object | Defaulted |
employer.name | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
rates | object | Defaulted |
rates.base_pay_rate | string | null | Defaulted |
rates.base_pay_unit | string | null | Defaulted |
rates.annual_salary | string | null | Defaulted |
rates.regular_hours_per_period | string | null | Defaulted |
rates.overtime_multiplier | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
earnings | array<object> | Defaulted |
earnings[].code | string | null | Defaulted |
earnings[].description | string | null | Defaulted |
earnings[].category | string | null | Defaulted |
earnings[].jurisdiction | string | null | Defaulted |
earnings[].hours | string | null | Defaulted |
earnings[].rate | string | null | Defaulted |
earnings[].current_amount | string | null | Defaulted |
earnings[].ytd_amount | string | null | Defaulted |
earnings[].employer_match | string | null | Defaulted |
earnings[].employer_match_ytd | string | null | Defaulted |
earnings[].is_taxable | boolean | null | Defaulted |
earnings[].is_imputed | boolean | null | Defaulted |
earnings[].memo | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
pre_tax_deductions | array<object> | Defaulted |
pre_tax_deductions[].code | string | null | Defaulted |
pre_tax_deductions[].description | string | null | Defaulted |
pre_tax_deductions[].category | string | null | Defaulted |
pre_tax_deductions[].jurisdiction | string | null | Defaulted |
pre_tax_deductions[].hours | string | null | Defaulted |
pre_tax_deductions[].rate | string | null | Defaulted |
pre_tax_deductions[].current_amount | string | null | Defaulted |
pre_tax_deductions[].ytd_amount | string | null | Defaulted |
pre_tax_deductions[].employer_match | string | null | Defaulted |
pre_tax_deductions[].employer_match_ytd | string | null | Defaulted |
pre_tax_deductions[].is_taxable | boolean | null | Defaulted |
pre_tax_deductions[].is_imputed | boolean | null | Defaulted |
pre_tax_deductions[].memo | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
taxes | array<object> | Defaulted |
taxes[].code | string | null | Defaulted |
taxes[].description | string | null | Defaulted |
taxes[].category | string | null | Defaulted |
taxes[].jurisdiction | string | null | Defaulted |
taxes[].hours | string | null | Defaulted |
taxes[].rate | string | null | Defaulted |
taxes[].current_amount | string | null | Defaulted |
taxes[].ytd_amount | string | null | Defaulted |
taxes[].employer_match | string | null | Defaulted |
taxes[].employer_match_ytd | string | null | Defaulted |
taxes[].is_taxable | boolean | null | Defaulted |
taxes[].is_imputed | boolean | null | Defaulted |
taxes[].memo | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
post_tax_deductions | array<object> | Defaulted |
post_tax_deductions[].code | string | null | Defaulted |
post_tax_deductions[].description | string | null | Defaulted |
post_tax_deductions[].category | string | null | Defaulted |
post_tax_deductions[].jurisdiction | string | null | Defaulted |
post_tax_deductions[].hours | string | null | Defaulted |
post_tax_deductions[].rate | string | null | Defaulted |
post_tax_deductions[].current_amount | string | null | Defaulted |
post_tax_deductions[].ytd_amount | string | null | Defaulted |
post_tax_deductions[].employer_match | string | null | Defaulted |
post_tax_deductions[].employer_match_ytd | string | null | Defaulted |
post_tax_deductions[].is_taxable | boolean | null | Defaulted |
post_tax_deductions[].is_imputed | boolean | null | Defaulted |
post_tax_deductions[].memo | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
employer_contributions | array<object> | Defaulted |
employer_contributions[].code | string | null | Defaulted |
employer_contributions[].description | string | null | Defaulted |
employer_contributions[].category | string | null | Defaulted |
employer_contributions[].jurisdiction | string | null | Defaulted |
employer_contributions[].hours | string | null | Defaulted |
employer_contributions[].rate | string | null | Defaulted |
employer_contributions[].current_amount | string | null | Defaulted |
employer_contributions[].ytd_amount | string | null | Defaulted |
employer_contributions[].employer_match | string | null | Defaulted |
employer_contributions[].employer_match_ytd | string | null | Defaulted |
employer_contributions[].is_taxable | boolean | null | Defaulted |
employer_contributions[].is_imputed | boolean | null | Defaulted |
employer_contributions[].memo | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
totals | object | Defaulted |
totals.gross_pay_current | string | null | Defaulted |
totals.gross_pay_ytd | string | null | Defaulted |
totals.taxable_gross_current | string | null | Defaulted |
totals.taxable_gross_ytd | string | null | Defaulted |
totals.total_pre_tax_deductions_current | string | null | Defaulted |
totals.total_pre_tax_deductions_ytd | string | null | Defaulted |
totals.total_taxes_current | string | null | Defaulted |
totals.total_taxes_ytd | string | null | Defaulted |
totals.total_post_tax_deductions_current | string | null | Defaulted |
totals.total_post_tax_deductions_ytd | string | null | Defaulted |
totals.total_deductions_current | string | null | Defaulted |
totals.total_deductions_ytd | string | null | Defaulted |
totals.total_employer_contributions_current | string | null | Defaulted |
totals.total_employer_contributions_ytd | string | null | Defaulted |
totals.net_pay_current | string | null | Defaulted |
totals.net_pay_ytd | string | null | Defaulted |
totals.hours_worked_current | string | null | Defaulted |
totals.hours_worked_ytd | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
reconciliation_warnings | array<string> | Defaulted |
The tables map output fields to JSON paths. || means the first nonempty value; ?? means a fallback for null. Numbering, combined descriptions and formatting are export rules. Missing values generally become blank cells.
There is no flat/non-flat choice. The Paystub sheet uses sections for statement, employee, employer, rates, earnings, deductions, taxes, contributions and totals. CSV is a sectioned grid; Word stacks sections vertically.
Dedicated layout
These are the sections of the Paystub layout, placed side by side in Excel and CSV and stacked in Word. Descriptions use description or code and append “imputed” when is_imputed is true and “non-taxable” when is_taxable is false. Rate columns use percentage formatting. Totals pair Current and YTD values for each Metric. Warnings appear only when present.
| Output field | JSON source or export rule |
|---|---|
| Gross pay / Current | totals.gross_pay_current |
| Gross pay / YTD | totals.gross_pay_ytd |
| Taxable gross / Current | totals.taxable_gross_current |
| Taxable gross / YTD | totals.taxable_gross_ytd |
| Pre-tax deductions / Current | totals.total_pre_tax_deductions_current |
| Pre-tax deductions / YTD | totals.total_pre_tax_deductions_ytd |
| Taxes / Current | totals.total_taxes_current |
| Taxes / YTD | totals.total_taxes_ytd |
| Post-tax deductions / Current | totals.total_post_tax_deductions_current |
| Post-tax deductions / YTD | totals.total_post_tax_deductions_ytd |
| Total deductions / Current | totals.total_deductions_current |
| Total deductions / YTD | totals.total_deductions_ytd |
| Employer contributions / Current | totals.total_employer_contributions_current |
| Employer contributions / YTD | totals.total_employer_contributions_ytd |
| Net pay / Current | totals.net_pay_current |
| Net pay / YTD | totals.net_pay_ytd |
| Hours worked / Current | totals.hours_worked_current |
| Hours worked / YTD | totals.hours_worked_ytd |
| Output field | JSON source or export rule |
|---|---|
| Doc ID | doc_id |
| Source | source_filename |
| Issue date | statement.issue_date |
| Pay date | statement.pay_date |
| Period start | statement.period_start |
| Period end | statement.period_end |
| Period type | statement.period_type |
| Tax year | statement.tax_year |
| Currency | statement.currency |
| Country | statement.country |
| Output field | JSON source or export rule |
|---|---|
| Name | employee.name |
| Pay frequency | employee.pay_frequency |
| Employment type | employee.employment_type |
| Employment status | employee.employment_status |
| Filing status | employee.filing_status |
| Tax code | employee.tax_code |
| Output field | JSON source or export rule |
|---|---|
| Name | employer.name |
| Output field | JSON source or export rule |
|---|---|
| Base pay rate | rates.base_pay_rate |
| Base pay unit | rates.base_pay_unit |
| Annual salary | rates.annual_salary |
| Regular hours/period | rates.regular_hours_per_period |
| Overtime multiplier | rates.overtime_multiplier |
| Output field | JSON source or export rule |
|---|---|
| # | index(earnings[]) + 1 |
| Description | earnings[].description || earnings[].code |
| Code | earnings[].code |
| Hours | earnings[].hours |
| Rate | earnings[].rate |
| Current | earnings[].current_amount |
| YTD | earnings[].ytd_amount |
| Memo | earnings[].memo |
| Output field | JSON source or export rule |
|---|---|
| # | index(pre_tax_deductions[]) + 1 |
| Description | pre_tax_deductions[].description || pre_tax_deductions[].code |
| Code | pre_tax_deductions[].code |
| Current | pre_tax_deductions[].current_amount |
| YTD | pre_tax_deductions[].ytd_amount |
| Memo | pre_tax_deductions[].memo |
| Output field | JSON source or export rule |
|---|---|
| # | index(taxes[]) + 1 |
| Description | taxes[].description || taxes[].code |
| Code | taxes[].code |
| Jurisdiction | taxes[].jurisdiction |
| Rate | taxes[].rate |
| Current | taxes[].current_amount |
| YTD | taxes[].ytd_amount |
| Output field | JSON source or export rule |
|---|---|
| # | index(post_tax_deductions[]) + 1 |
| Description | post_tax_deductions[].description || post_tax_deductions[].code |
| Code | post_tax_deductions[].code |
| Current | post_tax_deductions[].current_amount |
| YTD | post_tax_deductions[].ytd_amount |
| Memo | post_tax_deductions[].memo |
| Output field | JSON source or export rule |
|---|---|
| # | index(employer_contributions[]) + 1 |
| Description | employer_contributions[].description || employer_contributions[].code |
| Code | employer_contributions[].code |
| Current | employer_contributions[].current_amount |
| YTD | employer_contributions[].ytd_amount |
| Output field | JSON source or export rule |
|---|---|
| # | index(reconciliation_warnings[]) + 1 |
| Warning | reconciliation_warnings[] |
Xero CSV
No
QuickBooks CSV
No
Image of Table
The table’s title, header rows, body cells and notes. headers and rows[].cells follow the source columns; they are not a fixed financial schema. Row type identifies data, subtotal or other row roles.
JSON fields
Types describe serialized JSON. Parent objects and arrays are listed before their children; [] marks repeated entries. Defaulted fields need not be supplied by extraction. Decimal values serialize as strings. Downloads retain defaulted fields; a missing extracted value is not the same as an omitted JSON key.
| Field path | JSON type | Presence |
|---|---|---|
title | string | null | Defaulted |
caption | string | null | Defaulted |
source_type | string | null | Defaulted |
border_style | string | null | Defaulted |
language | string | null | Defaulted |
header_rows | integer | null | Defaulted |
notes | string | null | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
headers | array<array<any>> | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
rows | array<object> | Defaulted |
rows[].type | string | null | Defaulted |
rows[].cells | array<any> | Defaulted |
| Field path | JSON type | Presence |
|---|---|---|
reconciliation_warnings | array<string> | Defaulted |
The tables map output fields to JSON paths. || means the first nonempty value; ?? means a fallback for null. Numbering, combined descriptions and formatting are export rules. Missing values generally become blank cells.
There is no flat/non-flat choice. A single Table sheet uses the extracted headers and cells. The number of columns is dynamic; titles, notes and warnings can add rows. CSV cannot preserve Excel cell merging or styling.
Dedicated layout
Column names come from headers, not a fixed list. Body cells retain their order; short rows are padded and null cells become blank. title and caption appear above the grid, notes and warnings below. Repeated adjacent header values merge in Excel. rows[].type controls Excel/Word styling, not an extra output column. CSV has no styling. A warnings row can use two columns even when the data grid has only one.
| Output field | JSON source or export rule |
|---|---|
| title | title |
| caption | caption |
| headers[][] | headers[][] |
| rows[].cells[] | rows[].cells[] |
| Row formatting (Excel / Word) | rows[].type → DATA | HEADER | SECTION | SUBTOTAL | GRAND_TOTAL |
| Grid width | max(length(headers[]), length(rows[].cells)) || 1 |
| Notes | notes |
| # | index(reconciliation_warnings[]) + 1 |
| Reconciliation warnings | reconciliation_warnings[] |
Xero CSV
No
QuickBooks CSV
No
Missing values and reviewing results
Nullable fields can contain null; missing lists default to []. Nested objects can have their own default fields. Spreadsheet exporters commonly render missing values as blank cells. Dates and amounts may be normalized, and reconciliation can derive missing totals or add warnings. doc_id and source_filename are export metadata, not extracted financial fields.
Review the source and the exported values. An empty reconciliation_warnings list does not prove accuracy.