Skip to content

Bulk upload transactions to new source account

POST/api/v1/transactions/bulk-upload

Upload historical transactions from a CSV/Excel file to a new source account.

Workflow (via Temporal for durability):

  1. Gets/creates ledger
  2. Reads transactions from the CSV/Excel file in S3
  3. Creates Transaction + Journal Entry rows with categorization
  4. Runs AI categorization pass for uncategorized transactions

Supported File Formats: .csv, .xlsx, .xls

CSV/Excel Columns (flexible naming):

  • date/datetime/transaction_date: Transaction date (YYYY-MM-DD or ISO format)
  • amount/transaction_amount/value: Amount in dollars (positive or negative)
  • description/memo/name: Transaction description
  • category/ledger/account (optional): the ledger to book each row to. A name that matches no ledger refuses the file (400 VALIDATION_570, nothing imported) unless allow_unmatched_categories is true, which imports those rows to Uncategorized. Rows are never dropped.

Returns: Workflow ID and status. The upload runs in the background via Temporal. If interrupted, the workflow will resume from where it left off.

Operation ID: bulk_upload_transactions·View as markdown·OpenAPI slice

Authentication

Bearer token authentication. Pass your DayZero API token in the Authorization header and the target business UUID in x-business-id.

Request body

ledger_idstring

Optional: UUID of existing ledger to use. If provided, ledger creation is skipped and ledger_name/ledger fields are ignored.

ledger_namestring

Display name for the new ledger (required if ledger_id not provided, e.g., 'My Old Credit Card XXXX')

source_account_namestring

Optional: Display name for the source account. Defaults to ledger name if not provided.

business_personalstring

Whether the source account is a business or personal account. 'business' (default) for company transactions, 'personal' for owner draws/contributions.

invert_transaction_amountsboolean

If true, transaction amounts are inverted during import. Useful when CSV has opposite sign convention.

s3_keystringrequired

S3 key of the CSV file containing transactions

start_datestring · date

Optional: Only upload transactions on or after this date (YYYY-MM-DD). Filters transactions before upload.

end_datestring · date

Optional: Only upload transactions on or before this date (YYYY-MM-DD). Filters transactions before upload.

check_duplicatesboolean

If true, checks for duplicate transactions before uploading. Duplicates are skipped.

duplicate_match_fieldsarray · string

Fields to use for duplicate detection: 'amount', 'date', 'description'. Defaults to all three.

skip_categorizationboolean

If true, skip post-upload bank rules and AI categorization. Journal entries still post during import — to the mapped category column when provided, otherwise to Uncategorized Expense/Income. Only honored on the local accounting engine.

generate_bank_rulesboolean

If true (default), learn bank rules from the categorized transactions so future transactions auto-categorize. Ignored when skip_categorization is true.

currencystring

Currency for this account (USD, CAD, AUD, EUR, or GBP). Defaults to business default.

editableboolean

If true, journal entries can be manually posted to this account.

typestring

Account type: asset, liability, equity, revenue, expense. Required in Custom Mode.

descriptionstring

Optional description of the account's purpose.

statusstring

Account status: 'active' or 'inactive'. Inactive accounts hidden from dropdowns.

debit_creditstring

Normal balance: 'debit' (assets/expenses) or 'credit' (liabilities/equity/revenue). Required in Custom Mode.

sort_codestring

Sort code for chart ordering (e.g., '1000' for assets, '4000' for revenue). Required in Custom Mode.

sub_typestring

Sub-classification (current_assets, operating_expenses, etc.). Required in Custom Mode.

report_cash_flowboolean

Include in cash flow statement. Required in Custom Mode.

financial_account_typestring

Templated Mode: bank_account, credit_card, payments, payroll, loan, prepaid_card, accounts_receivable, accounts_payable.

parent_idstring

UUID of parent ledger for sub-accounts (e.g., 'Operating Expenses' → 'Office Supplies').

column_mappingobject

User-supplied mapping from DayZero field names to CSV column names. Keys: 'date', 'amount', 'description', and optional 'category' (aliases: ledger, ledger_name, account, account_name, category_name). Values: the CSV header to use. When provided, auto-detection is skipped.

only_missing_from_diffboolean

If true, compare the file with ledger_id first (the same diff as POST /transactions/bulk-upload/diff, re-run now) and import only the rows missing from the ledger. Ambiguous rows (same amount, nothing else agrees) are NOT imported — list them in include_row_numbers instead. Requires ledger_id; the exact-match duplicate check is skipped because the diff already did it.

include_row_numbersarray · integer

Import only these spreadsheet rows (header = row 1, first data row = 2), e.g. the diff's missing_row_numbers plus any ambiguous rows you checked. The exact-match duplicate check is skipped.

date_tolerance_daysinteger

only_missing_from_diff: days a ledger date may differ from the file's (default 3).

status_columnstring

only_missing_from_diff: header of the file's settled/pending status column (auto-detected from status/transaction_status/state when omitted).

exclude_statusesarray · string

Skip file rows whose status is one of these, case-insensitive (e.g. ['Pending']). Applies to only_missing_from_diff.

allow_unmatched_categoriesboolean

Rows whose category names no ledger are refused by default (400 VALIDATION_570, nothing imported, every row listed with the nearest ledger names). Set true to import them to Uncategorized instead. A blank category is not affected.

Responses

201Successful Response

successboolean
messagestring
codestring
dataBulkTransactionUploadResponse

400Bad Request - Invalid input

errorstringrequired

Error category: validation_error, unauthorized, forbidden, not_found, conflict, rate_limited, server_error, or service_unavailable.

messagestringrequired

Human-readable explanation, safe to show to end users.

codestringrequired

Stable machine-readable code in CATEGORY_NNN form (e.g. NOT_FOUND_006, AUTH_010, GEN_002).

request_idstring

Correlation id for support requests. Echoes the x-request-id request header when one was supplied.

errorsobject

Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

401Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

errorstringrequired

Error category: validation_error, unauthorized, forbidden, not_found, conflict, rate_limited, server_error, or service_unavailable.

messagestringrequired

Human-readable explanation, safe to show to end users.

codestringrequired

Stable machine-readable code in CATEGORY_NNN form (e.g. NOT_FOUND_006, AUTH_010, GEN_002).

request_idstring

Correlation id for support requests. Echoes the x-request-id request header when one was supplied.

errorsobject

Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

403Forbidden - Insufficient permissions

errorstringrequired

Error category: validation_error, unauthorized, forbidden, not_found, conflict, rate_limited, server_error, or service_unavailable.

messagestringrequired

Human-readable explanation, safe to show to end users.

codestringrequired

Stable machine-readable code in CATEGORY_NNN form (e.g. NOT_FOUND_006, AUTH_010, GEN_002).

request_idstring

Correlation id for support requests. Echoes the x-request-id request header when one was supplied.

errorsobject

Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

422Validation Error

errorstringrequired

Error category: validation_error, unauthorized, forbidden, not_found, conflict, rate_limited, server_error, or service_unavailable.

messagestringrequired

Human-readable explanation, safe to show to end users.

codestringrequired

Stable machine-readable code in CATEGORY_NNN form (e.g. NOT_FOUND_006, AUTH_010, GEN_002).

request_idstring

Correlation id for support requests. Echoes the x-request-id request header when one was supplied.

errorsobject

Field-level validation messages keyed by field name. Present on 400/422 validation failures only.