Get the FREE Ultimate OpenClaw Setup Guide →

data-schemas

npx machina-cli add skill peerjakobsen/smartspender/data-schemas --openclaw
Files (1)
SKILL.md
24.3 KB

Data Schemas

Purpose

Defines the local CSV file structure that stores all SmartSpender data. All read/write operations use the Filesystem tool to access CSV files in the working directory. Files are created automatically on first use if they don't exist — write the header row first, then append data rows.


1. Transaction Schema

Purpose

Defines the common data format for all transactions in SmartSpender. Every bank adapter normalizes its export into this schema before storing locally.

Schema

FieldTypeRequiredDescription
tx_idstringyesUnique transaction ID (auto-generated UUID)
tx_hashstringyesDeduplication hash
datedateyesTransaction date (YYYY-MM-DD)
amountnumberyesAmount with sign (negative = expense, positive = income)
currencystringyesISO currency code (default: DKK)
descriptionstringyesCleaned, human-readable description
raw_textstringyesOriginal text from bank export, unmodified
bankstringyesBank identifier (e.g., enable-banking)
accountstringyesAccount identifier from the bank
synced_atdatetimeyesWhen the transaction was imported (YYYY-MM-DD HH:MM:SS)

Hash Computation

The tx_hash prevents duplicate imports across multiple sync runs.

Primary formula (when bank provides running balance)

"{account}|{date}|{amount}|{saldo}"

Where:

  • account is the account identifier from the bank export (e.g., the Enable Banking account UID for API sync)
  • date is in YYYY-MM-DD format
  • amount is formatted to exactly 2 decimal places (e.g., -55.00)
  • saldo is the running balance after the transaction, formatted to exactly 2 decimal places (e.g., 927.83)

The running balance is a natural disambiguator — even two identical purchases at the same merchant on the same day produce different balances.

Fallback formula (when bank does not provide running balance)

"{account}|{date}|{amount}|{raw_text_normalized}"

Where:

  • raw_text_normalized is the raw_text trimmed of whitespace and lowercased

This fallback is used when:

  • Enable Banking API response lacks balance_after_transaction for a specific transaction

Before appending any row to transactions.csv, check whether a row with the same tx_hash already exists. If it does, skip the row.

Transformation Rules

Date Normalization

  • Enable Banking API provides YYYY-MM-DD (no conversion needed)
  • Always convert to: YYYY-MM-DD
  • Reject any date in the future — this likely indicates a parsing error

Amount Normalization

  • Danish number format uses period as thousands separator and comma as decimal: 1.234,56
  • Convert to standard decimal: 1234.56
  • Enable Banking API provides amounts as positive strings with a credit_debit_indicator — negate DBIT amounts
  • Expenses are negative, income is positive
  • Always store with exactly 2 decimal places
  • Currency defaults to DKK unless the transaction specifies otherwise

Description Cleaning

  • Trim leading and trailing whitespace
  • Collapse multiple consecutive spaces into one
  • Preserve bank-specific prefixes that indicate payment method (e.g., Debitcard DK indicates card payment)
  • For Enable Banking: use creditor.name (expenses) or debtor.name (income) as the description
  • Store the original unmodified text in raw_text
  • Store the cleaned version in description

Bank and Account Fields

  • bank uses the lowercase bank identifier: enable-banking
  • account uses the Enable Banking account UID

Validation Rules

Before storing a transaction, verify all of the following:

  • date is a valid date and not in the future
  • amount is a non-zero number
  • raw_text is not empty
  • tx_hash does not already exist in transactions.csv (deduplication)

If validation fails, log the issue but do not halt the entire sync — skip the invalid row and continue.

Transaction Examples

Enable Banking Card Payment (API Sync, with balance)

tx_id: "d4e5f6a7-b8c9-0123-defa-234567890123"
tx_hash: "eb-uid-abc123|2026-01-15|-847.50|12543.25"
date: 2026-01-15
amount: -847.50
currency: DKK
description: FOETEX
raw_text: "Dankort-koeb FOETEX 4123"
bank: enable-banking
account: "eb-uid-abc123"
synced_at: 2026-02-02 14:00:00

Enable Banking Salary (API Sync, with balance)

tx_id: "e5f6a7b8-c9d0-1234-efab-345678901234"
tx_hash: "eb-uid-abc123|2026-01-31|32500.00|45043.25"
date: 2026-01-31
amount: 32500.00
currency: DKK
description: Virksomhed A/S
raw_text: "Loen januar 2026"
bank: enable-banking
account: "eb-uid-abc123"
synced_at: 2026-02-02 14:00:00

Enable Banking Subscription (API Sync, no balance — fallback hash)

tx_id: "f6a7b8c9-d0e1-2345-fabc-456789012345"
tx_hash: "eb-uid-abc123|2026-01-15|-149.00|netflix.com"
date: 2026-01-15
amount: -149.00
currency: DKK
description: Netflix
raw_text: "NETFLIX.COM"
bank: enable-banking
account: "eb-uid-abc123"
synced_at: 2026-02-02 14:00:00

2. Receipt Schema

Purpose

Defines the CSV file structure for storing receipt metadata and line-item detail. Two files work together: receipts.csv holds one row per receipt with match status; receipt-items-YYYY-MM.csv files hold one row per line item with product-level categories, partitioned by month based on the receipt date.

receipts.csv (Receipt Metadata)

Stores one row per uploaded receipt with extraction results and transaction match status.

Header row:

receipt_id,transaction_id,date,merchant,total_amount,currency,source,file_reference,match_status,match_confidence,item_count,created_at
ColumnTypeDescription
receipt_idstringUnique receipt ID (rcpt- prefix + 8 hex chars, e.g. rcpt-a1b2c3d4)
transaction_idstringMatched tx_id from transactions.csv (empty if unmatched)
datedateReceipt date (YYYY-MM-DD)
merchantstringNormalized merchant name (e.g. Foetex, TDC)
total_amountnumberReceipt total as positive number (e.g. 347.50)
currencystringISO currency code (DKK)
sourcestringHow the receipt was obtained: upload, storebox, coop, eboks, email
file_referencestringLocal archive path (e.g. receipts/rcpt-a1b2c3d4.jpg)
match_statusstringmatched, unmatched, ambiguous
match_confidencenumberConfidence of the transaction match (0.0-1.0)
item_countnumberNumber of line items extracted
created_atdatetimeWhen the receipt was processed (YYYY-MM-DD HH:MM:SS)

File operations:

  • Append row: after receipt extraction and matching completes
  • Read all: for deduplication check before appending
  • Read filtered by transaction_id: to find receipts linked to a specific transaction
  • Update row: when user corrects a match (update transaction_id, match_status, match_confidence)

receipt-items-YYYY-MM.csv (Line Items, Monthly Files)

Stores individual line items from each receipt with product-level categorization. Items are partitioned into monthly files based on the receipt's date in receipts.csv. For example, a receipt dated 2026-01-28 has its items stored in receipt-items-2026-01.csv.

Header row:

item_id,receipt_id,item_name,quantity,unit_price,total_price,category,subcategory,discount,created_at
ColumnTypeDescription
item_idstringUnique item ID (ritm- prefix + 8 hex chars, e.g. ritm-e5f6g7h8)
receipt_idstringReference to receipts.csv
item_namestringProduct name as printed on receipt (e.g. Minimælk 1L)
quantitynumberQuantity purchased (default 1)
unit_pricenumberPrice per unit as positive number
total_pricenumberLine total as positive number (quantity x unit_price - discount)
categorystringDanish product category (e.g. Dagligvarer, Bolig, Abonnementer)
subcategorystringProduct-level subcategory (e.g. Mejeriprodukter, Koed, Alkohol)
discountnumberDiscount amount as positive number (0 if no discount)
created_atdatetimeWhen the item was extracted (YYYY-MM-DD HH:MM:SS)

File operations:

  • Append rows: determine the receipt date from receipts.csv, then write items to receipt-items-{YYYY-MM}.csv (create the file with header row if it doesn't exist)
  • Read filtered by receipt_id: get the receipt date from receipts.csv, open the corresponding monthly file, filter by receipt_id
  • Read filtered by date range: get receipt dates from receipts.csv, open only the relevant monthly files, filter by receipt_id

ID Generation

Receipt IDs

  • Format: rcpt- + 8 random hex characters
  • Example: rcpt-a1b2c3d4, rcpt-f9e8d7c6
  • Must be unique across all rows in receipts.csv

Item IDs

  • Format: ritm- + 8 random hex characters
  • Example: ritm-e5f6g7h8, ritm-1a2b3c4d
  • Must be unique across all monthly receipt-items files

Receipt Deduplication

Before appending a new receipt, check for duplicates using three fields:

  • date — same date
  • merchant — same normalized merchant name
  • total_amount — same total (exact match)

If all three match an existing receipt, warn the user: "Denne kvittering ligner en der allerede er registreret ({receipt_id} fra {date}). Vil du tilfoeje den alligevel?"

File Archiving

Receipt images and PDFs are saved to a local receipts/ directory in the working directory. The directory is created automatically on first use.

Naming Convention

  • Format: receipts/{receipt_id}.{ext}
  • Extension preserved from the original file (jpg, png, pdf, etc.)
  • Example: receipts/rcpt-a1b2c3d4.jpg, receipts/rcpt-b2c3d4e5.pdf

Archive Rules

  • Save the file immediately after generating the receipt_id, before writing CSV rows
  • If the file cannot be saved, log a warning but continue processing (the extracted data is still valuable)
  • The file_reference column in receipts.csv stores the relative path (e.g. receipts/rcpt-a1b2c3d4.jpg)

Receipt Examples

Foetex Grocery Receipt

receipts.csv row:

rcpt-a1b2c3d4,tx-uuid-001,2026-01-28,Foetex,347.50,DKK,upload,receipts/rcpt-a1b2c3d4.jpg,matched,0.95,8,2026-02-01 10:30:00

receipt-items-2026-01.csv rows (receipt date is 2026-01-28):

ritm-e5f6g7h8,rcpt-a1b2c3d4,Minimælk 1L,2,12.95,25.90,Dagligvarer,Mejeriprodukter,0,2026-02-01 10:30:00
ritm-f1g2h3i4,rcpt-a1b2c3d4,Hakket oksekød 500g,1,45.00,45.00,Dagligvarer,Kød,0,2026-02-01 10:30:00
ritm-a2b3c4d5,rcpt-a1b2c3d4,Øko bananer,1,22.95,22.95,Dagligvarer,Frugt og grønt,0,2026-02-01 10:30:00
ritm-b3c4d5e6,rcpt-a1b2c3d4,Coca-Cola 1.5L,2,22.00,44.00,Dagligvarer,Drikkevarer,0,2026-02-01 10:30:00
ritm-c4d5e6f7,rcpt-a1b2c3d4,Rødvin Chianti,1,79.95,79.95,Dagligvarer,Alkohol,0,2026-02-01 10:30:00
ritm-d5e6f7g8,rcpt-a1b2c3d4,Tandbørstehoveder,1,89.95,89.95,Sundhed,Personlig pleje,0,2026-02-01 10:30:00
ritm-e6f7g8h9,rcpt-a1b2c3d4,Rugbrød,1,24.95,24.95,Dagligvarer,Brød og bagværk,0,2026-02-01 10:30:00
ritm-f7g8h9i0,rcpt-a1b2c3d4,Pose 2 kr,1,2.00,2.00,Andet,Andet,0,2026-02-01 10:30:00

Note: Items sum to 334.70, but receipt total is 347.50. The difference (12.80) is likely pant (bottle deposit) or rounding — flag for user review if variance > 5%.

TDC Telecom Invoice

receipts.csv row:

rcpt-b2c3d4e5,tx-uuid-042,2026-01-15,TDC,299.00,DKK,upload,receipts/rcpt-b2c3d4e5.pdf,matched,1.00,3,2026-02-01 11:00:00

receipt-items-2026-01.csv rows (receipt date is 2026-01-15):

ritm-g8h9i0j1,rcpt-b2c3d4e5,Mobilabonnement Frihed+,1,199.00,199.00,Abonnementer,Mobilabonnement,0,2026-02-01 11:00:00
ritm-h9i0j1k2,rcpt-b2c3d4e5,Ekstra data 10GB,1,49.00,49.00,Abonnementer,Mobilabonnement,0,2026-02-01 11:00:00
ritm-i0j1k2l3,rcpt-b2c3d4e5,Forsikring Mobil+,1,51.00,51.00,Abonnementer,Forsikring,0,2026-02-01 11:00:00

3. CSV File Reference

All data is stored as CSV files in the working directory. Use comma as the delimiter. Enclose fields in double quotes if they contain commas.

transactions.csv

Stores raw imported transactions from all bank syncs.

Header row:

tx_id,tx_hash,date,amount,currency,description,raw_text,bank,account,synced_at
ColumnTypeDescription
tx_idstringUnique transaction ID (UUID)
tx_hashstringDeduplication hash ("{account}|{date}|{amount}|{saldo}")
datedateTransaction date (YYYY-MM-DD)
amountnumberAmount with sign (negative = expense)
currencystringISO currency code (DKK)
descriptionstringCleaned description
raw_textstringOriginal bank text
bankstringBank identifier
accountstringAccount identifier
synced_atdatetimeImport timestamp

File operations:

  • Append rows: after sync completes
  • Read all rows: before sync (for deduplication by tx_hash)
  • Read filtered: by date range for analysis

categorized.csv

Stores transactions with assigned categories and merchant info.

Header row:

tx_id,date,amount,description,category,subcategory,merchant,is_recurring,confidence,manual_override
ColumnTypeDescription
tx_idstringReference to transactions.csv
datedateTransaction date (YYYY-MM-DD)
amountnumberAmount
descriptionstringDescription
categorystringAssigned Danish category (e.g., Dagligvarer)
subcategorystringOptional subcategory (e.g., Supermarked)
merchantstringNormalized merchant name (e.g., Netto)
is_recurringbooleanTRUE if detected as recurring
confidencenumberCategorization confidence (0.0-1.0)
manual_overridebooleanTRUE if user corrected this category

File operations:

  • Append rows: after analyze command categorizes transactions
  • Read all: for spending analysis and reporting
  • Update row: when user manually corrects a category (set manual_override to TRUE)

subscriptions.csv

Detected recurring charges and their status.

Header row:

subscription_id,merchant,category,amount,frequency,annual_cost,first_seen,last_seen,status,cancelled_date,notes
ColumnTypeDescription
subscription_idstringUnique ID
merchantstringService name (e.g., Netflix)
categorystringSubscription category (e.g., Streaming)
amountnumberRecurring charge amount
frequencystringmonthly, yearly, weekly
annual_costnumberCalculated annual cost
first_seendateFirst transaction date
last_seendateMost recent transaction
statusstringactive, cancelled, paused
cancelled_datedateWhen cancelled (if applicable)
notesstringAny notes

File operations:

  • Append rows: after analyze detects new subscriptions
  • Read all: for subscriptions list and overview
  • Update row: when subscription is cancelled (set status, cancelled_date)

monthly-summary.csv

Aggregated spending by month and category.

Header row:

month,category,total,transaction_count,avg_transaction,vs_prev_month,vs_prev_month_pct
ColumnTypeDescription
monthstringYYYY-MM format
categorystringDanish category name
totalnumberTotal spent in this category
transaction_countnumberNumber of transactions
avg_transactionnumberAverage transaction size
vs_prev_monthnumberChange from previous month (absolute)
vs_prev_month_pctnumberPercentage change from previous month

File operations:

  • Write/overwrite rows: after analyze command completes
  • Read filtered by month: for overview and report commands

action-log.csv

Audit trail of all agent actions for transparency.

Header row:

timestamp,action_type,target,status,details,savings_amount,notes
ColumnTypeDescription
timestampdatetimeWhen action occurred (YYYY-MM-DD HH:MM:SS)
action_typestringsync, analyze, cancel, suggest, report
targetstringWhat the action targeted (e.g., "enable-banking", "netflix")
statusstringsuggested, in_progress, completed, failed
detailsstringAdditional details
savings_amountnumberEstimated or actual savings (kr/year)
notesstringAny notes

File operations:

  • Append row: after every command execution
  • Read filtered: for report command (actions in a given month)

accounts.csv

Configured bank accounts.

Header row:

account_id,bank,account_name,account_type,last_synced,is_active,eb_account_uid,eb_session_id,balance,balance_type,balance_date
ColumnTypeDescription
account_idstringUnique account identifier
bankstringBank identifier (e.g., enable-banking)
account_namestringUser-friendly name (e.g., Lonkonto)
account_typestringchecking, savings, credit
last_synceddatetimeLast successful sync timestamp
is_activebooleanTRUE if currently tracked
eb_account_uidstringEnable Banking account UID
eb_session_idstringEnable Banking session ID
balancenumberCurrent account balance
balance_typestringBalance type code (e.g., CLBD, ITAV)
balance_datedateWhen balance was last updated (YYYY-MM-DD)

Balance type codes:

  • CLBD: Closing booked balance (end of day settled) — preferred
  • ITAV: Intraday available (current available)
  • XPCD: Expected balance

File operations:

  • Append row: when user adds a new account
  • Update row: after each sync (update last_synced, balance, balance_type, balance_date)
  • Read all: to list configured accounts

settings.csv

Plugin configuration stored as key-value pairs.

Header row:

setting_key,setting_value,updated_at
ColumnTypeDescription
setting_keystringSetting name (snake_case)
setting_valuestringSetting value
updated_atdatetimeLast updated timestamp

Default settings:

KeyDefault ValueDescription
default_currencyDKKCurrency for all transactions
categorization_confidence_threshold0.7Minimum confidence to auto-assign category
subscription_detection_months3Minimum occurrences to detect subscription
preferred_languagedaLanguage for user-facing output

File operations:

  • Read all: at command startup to load configuration
  • Update row: when user changes a setting

merchant-overrides.csv

Learned merchant categorization rules from user corrections. When a user manually recategorizes a transaction, the correction is stored here as a reusable rule for future transactions from the same merchant.

Header row:

raw_pattern,merchant,category,subcategory,created_at
ColumnTypeDescription
raw_patternstringNormalized pattern from raw_text (uppercase, trimmed) e.g. NORMAL FREDERIK
merchantstringUser-corrected merchant name e.g. Normal
categorystringUser-corrected category e.g. Shopping
subcategorystringUser-corrected subcategory (can be empty)
created_atdatetimeWhen the override was created (YYYY-MM-DD HH:MM:SS)

File operations:

  • Read all: before categorization to apply learned rules first
  • Append row: when a manual correction in categorized.csv introduces a new merchant override
  • Check for duplicates: don't add a row if raw_pattern already exists

3. Payslip Schema

Purpose

Defines the CSV file structure for storing payslip data extracted from Danish lønsedler. Enables accurate pension tracking and income analysis based on actual gross salary rather than net deposits.

payslips.csv

Stores one row per uploaded payslip with extracted salary breakdown and pension data.

Header row:

payslip_id,pay_period,employer,employer_id,gross_salary,a_skat,am_bidrag,pension_employer,pension_employee,pension_total,pension_pct,atp,feriepenge,net_salary,benefits_json,transaction_id,file_reference,created_at
ColumnTypeDescription
payslip_idstringUnique payslip ID (ps- prefix + 8 hex chars, e.g. ps-a1b2c3d4)
pay_periodstringPay period in YYYY-MM format (e.g. 2026-01)
employerstringCompany name as shown on payslip
employer_idstringNormalized employer ID (lowercase, no spaces)
gross_salarynumberBruttoløn — total earnings before deductions
a_skatnumberIncome tax withheld
am_bidragnumberLabor market contribution (8% of gross)
pension_employernumberEmployer's pension contribution
pension_employeenumberEmployee's pension contribution
pension_totalnumberCombined pension (employer + employee)
pension_pctnumberPension as percentage of gross salary
atpnumberATP contribution
feriepengenumberHoliday pay accrued this period
net_salarynumberNettoløn — amount deposited to bank
benefits_jsonstringJSON string of additional benefits (sundhedsforsikring, fritvalgskonto, etc.)
transaction_idstringMatched tx_id from transactions.csv (empty if unmatched)
file_referencestringLocal archive path (e.g. payslips/ps-a1b2c3d4.pdf)
created_atdatetimeWhen the payslip was processed (YYYY-MM-DD HH:MM:SS)

File operations:

  • Append row: after payslip extraction and validation completes
  • Read all: for deduplication check before appending
  • Read filtered by pay_period: to analyze pension trends over time
  • Read filtered by transaction_id: to find payslip linked to a salary transaction
  • Update row: when user corrects extracted data

ID Generation

Payslip IDs

  • Format: ps- + 8 random hex characters
  • Example: ps-a1b2c3d4, ps-f9e8d7c6
  • Must be unique across all rows in payslips.csv

Payslip Deduplication

Before appending a new payslip, check for duplicates using two fields:

  • employer_id — same normalized employer
  • pay_period — same month

If both match an existing payslip, warn the user: "Denne lønseddel ligner en der allerede er registreret ({payslip_id} for {pay_period}). Vil du tilføje den alligevel?"

File Archiving

Payslip images and PDFs are saved to a local payslips/ directory in the working directory. The directory is created automatically on first use.

Naming Convention

  • Format: payslips/{payslip_id}.{ext}
  • Extension preserved from the original file (jpg, png, pdf)
  • Example: payslips/ps-a1b2c3d4.pdf

Archive Rules

  • Save the file immediately after generating the payslip_id, before writing CSV row
  • The file_reference column stores the relative path (e.g. payslips/ps-a1b2c3d4.pdf)
  • Privacy: Never store CPR numbers — mask any detected CPR in logs

Payslip Examples

Standard Monthly Payslip

payslips.csv row:

ps-a1b2c3d4,2026-01,Teknologi A/S,teknologi,42000.00,11200.00,3360.00,4200.00,2100.00,6300.00,15.00,94.65,5250.00,25245.35,"{""sundhedsforsikring"":150}",tx-uuid-045,payslips/ps-a1b2c3d4.pdf,2026-02-01 14:30:00

Payslip with Bonus

payslips.csv row:

ps-b2c3d4e5,2026-03,Startup ApS,startup,55000.00,16500.00,4400.00,5500.00,2750.00,8250.00,15.00,94.65,6875.00,31255.35,"{""bonus"":10000}",tx-uuid-089,payslips/ps-b2c3d4e5.pdf,2026-04-02 10:15:00

5. File Relationships

transactions.csv --[tx_id]--> categorized.csv
transactions.csv --[tx_id]--> receipts.csv (via transaction_id)
transactions.csv --[tx_id]--> payslips.csv (via transaction_id)
receipts.csv --[receipt_id + date]--> receipt-items-YYYY-MM.csv
categorized.csv --[merchant + is_recurring]--> subscriptions.csv
categorized.csv --[month + category]--> monthly-summary.csv
merchant-overrides.csv <-- learned from manual corrections in categorized.csv
payslips.csv --> advice command (pension_pct for Step 3 assessment)
All commands --> action-log.csv
accounts.csv <--> Sync commands (last_synced updated)

Related Skills

  • See skills/document-parsing/SKILL.md for extraction rules and product subcategories
  • See skills/payslip-parsing/SKILL.md for payslip extraction rules and validation
  • See skills/transaction-matching/SKILL.md for how receipts and payslips are matched to transactions
  • See skills/categorization/SKILL.md for merchant-level categories

Source

git clone https://github.com/peerjakobsen/smartspender/blob/main/skills/data-schemas/SKILL.mdView on GitHub

Overview

Defines the local CSV structures used by SmartSpender to store data. Read and write operations rely on the Filesystem tool to access CSVs in the working directory, creating headers on first use. The core is the Transaction Schema that standardizes all transactions before persistence.

How This Skill Works

The skill codifies a Transaction Schema for normalizing bank exports before local storage. Data is written to transactions.csv with a header row on first use; tx_hash is computed to prevent duplicates across sync runs, using either the primary running-balance formula or a fallback that uses raw_text when needed.

When to Use It

  • Importing bank transactions via Enable Banking and normalizing data
  • Deduplicating transactions across multiple sync runs
  • Normalizing date, amount, and description before storage
  • Reading or writing to the local CSV data store in the working directory
  • Validating transactions before appending to transactions.csv

Quick Start

  1. Step 1: Review the Transaction Schema fields and ensure your CSVs follow the defined headers
  2. Step 2: On first write, create headers in transactions.csv and append rows following the schema
  3. Step 3: Compute tx_hash using the primary formula (account|date|amount|saldo) or the fallback (account|date|amount|raw_text_normalized), then verify before append

Best Practices

  • Align all reads/writes to the Transaction Schema fields (tx_id, tx_hash, date, amount, currency, description, raw_text, bank, account, synced_at)
  • Always compute tx_hash and deduplicate before appending rows
  • Normalize date to YYYY-MM-DD and amount to exactly two decimals (default currency DKK)
  • Preserve raw_text in its original form and store a cleaned description separately
  • Use lowercase bank identifiers (e.g., enable-banking) and the correct bank account UID

Example Use Cases

  • Importing Enable Banking exports into transactions.csv while deduplicating by tx_hash
  • Converting Danish number formats (1.234,56) to standard decimals (1234.56) before storage
  • Using creditor.name for expenses or debtor.name for income to populate description
  • Storing the original bank text in raw_text while keeping a cleaned description for reporting
  • Ensuring no future dates pass validation during transaction ingestion

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers