Skip to content

Transaction Imports & Matching

Zenvilope supports importing transactions from your bank via OFX/QFX files. This guide explains how the import, matching, approval, and rejection workflows operate.

Import Overview

When you import transactions from your bank:

  1. Parse - The OFX file is parsed to extract transaction data
  2. Match - Each transaction is checked for duplicates and potential matches
  3. Preview - You see what will be imported before confirming
  4. Import - Transactions are created or linked to existing entries
  5. Approve - You review and approve imported transactions

Transaction States

After import, transactions can be in several states:

StateisApprovedisMatchedDescription
Pending ImportfalsefalseNew import, needs review
Pending MatchfalsetrueLinked to manual entry, needs review
Approved ImporttruefalseReviewed and accepted
Approved MatchtruetrueLinked transaction, reviewed
Manual EntrytruefalseUser-created, no import data

Matching Behaviour

Duplicate Detection

During import preview, transactions are checked against existing imports:

  • Duplicates: Same imported_id already exists in the account → Skipped
  • Rejected: Previously rejected import with same imported_id → Skipped

Payee Fuzzy Matching

Import files contain raw payee strings (e.g., "AMAZON.COM*1A2B3C SEATTLE"). Zenvilope fuzzy-matches these against your existing payees:

  1. Normalize the imported payee string (lowercase, strip punctuation)
  2. Compare against existing payee names
  3. If match found → Link to existing payee
  4. If no match → Create new payee from import string

Manual Transaction Matching

When importing, the system looks for existing manual entries that might match:

Match criteria:

  • Same account
  • Exact same amount
  • Date within ±3 days of import date
  • Not already matched or reconciled

When matched:

  • Import metadata is "dumped" onto the manual transaction
  • Manual transaction's date is preserved (user's date takes priority)
  • OFX date stored in importedDate for reference
  • Transaction marked as isMatched=true, isApproved=false

Approval Workflow

All imported transactions require approval. This ensures you review bank data before it affects your budget.

Approving a Transaction

  1. Find transactions with the warning indicator (needs attention)
  2. Open the transaction for editing
  3. Review/adjust: payee, category, date, amount
  4. Click "Approve" (replaces "Save" button for unapproved transactions)

TIP

Unapproved transactions still affect your budget calculations - approval is about verification, not activation.

Bulk Approval

Select multiple transactions and use bulk actions to approve them all at once.

Rejection Workflow

Reject an import when the bank data shouldn't create a transaction.

What Rejection Does

For pure imports (not matched):

  • Deletes the imported transaction
  • Creates a "tombstone" record to prevent re-import

For matched transactions:

  • Removes import metadata from the manual transaction
  • Reverts the manual entry to approved status
  • Creates a tombstone to prevent re-import

When to Reject

  • Duplicate charge that will be refunded
  • Bank error that will be corrected
  • Transaction you don't want to track
  • Incorrect match to manual entry

Tombstones

When you reject an import, a RejectedImport record is created. This prevents the same imported_id from being re-imported in future imports.

Unmatch Workflow

Use unmatch when an import was incorrectly linked to the wrong manual transaction.

What Unmatch Does

  1. Reverts the manual transaction:

    • Clears all import metadata (importedId, importedPayee, etc.)
    • Sets isMatched=false, isApproved=true
    • Manual entry returns to its original state
  2. Creates a new import transaction:

    • New transaction from the original import data
    • Fuzzy-matches payee (creates new if needed)
    • Uses payee's default category if available
    • Sets isMatched=false, isApproved=false
    • Marked as cleared (bank exports only cleared transactions)

When to Unmatch

  • Import was matched to wrong manual transaction
  • You want to keep both entries separate
  • Manual entry was for something different

INFO

After unmatching, you'll have:

  • Your original manual entry (restored, approved)
  • A new pending import transaction (needs approval)

Visual Indicators

The transaction list shows status with icons:

IconMeaning
⚠️ Yellow triangleNeeds attention (unapproved)
🔗 Blue linkMatched with bank import (approved)
⬇️ Grey downloadImported transaction (approved, not matched)

Import Data Fields

When a transaction has import data, these fields are populated:

FieldDescription
importedIdBank's unique transaction ID (prevents duplicates)
importedPayeeRaw payee string from bank
importedTransactionTypeOFX transaction type (DEBIT, CREDIT, etc.)
importedDateDate from bank (may differ from transaction date)

Best Practices

Import Regularly

Import weekly or after each bank statement to catch transactions early.

Review Matches Carefully

When a match is found, verify it's correct:

  • Check the amounts match exactly
  • Verify the dates are reasonable
  • Confirm payees align

Categorize During Approval

Use the approval step to assign categories to imported transactions.

Don't Fear Rejection

If an import is wrong, reject it. The tombstone prevents re-import headaches.

Unmatch When Needed

If you matched to the wrong transaction, unmatch rather than trying to fix it manually.

API Endpoints

For developers, the key endpoints are:

POST /api/budgets/{id}/accounts/{id}/import-ofx-preview  # Preview import
POST /api/budgets/{id}/accounts/{id}/import-ofx-confirm  # Confirm import
POST /api/budgets/{id}/transactions/{id}/approve         # Approve transaction
POST /api/budgets/{id}/transactions/{id}/reject          # Reject import
POST /api/budgets/{id}/transactions/{id}/unmatch         # Unmatch transaction
POST /api/budgets/{id}/transactions/bulk-approve         # Bulk approve

Next Steps

Envelope budgeting made simple