Recued
Menu
← Back to recipes

Import expenses (CSV)

by recued-core v1 8 views

Use “Import expenses (CSV)” in Recued. Reads a card or expense export you downloaded yourself, maps its columns the way you named them, and records every line as an expense. Re-importing an overlapping export adds only what is new.

Complete workflow

Expense Ledger 6 pinned recipes

Use Expense Ledger in Recued for expenses, receipts, bookkeeping, and ocr. It includes 7 built-in actions and 5 ready-to-run workflows. Actions that change data use Recued's approval controls.

You are viewing one recipe in this workflow. Installing it opens the complete pack so its other recipes and background automations arrive together.

Import expenses (CSV)
This recipe

Use “Import expenses (CSV)” in Recued. Reads a card or expense export you downloaded yourself, maps its columns the way you named them, and records every line as an expense. Re-importing an overlapping export adds only what is new.

pack:expense-ledgerexpensescsvimport
by recued-core pinned v1

Use “Capture a receipt” in Recued. Read one receipt locally — OCR for a photograph, text extraction for a PDF — pull out the merchant, date, total, VAT and payment method, and keep it as an expense.

pack:expense-ledgerexpensesreceiptsocr
by recued-core pinned v2

Use “Review an expense” in Recued. Confirm or correct one captured expense. Whatever you leave blank keeps what was extracted; whatever you fill in replaces it.

pack:expense-ledgerexpensesreviewrecords
by recued-core pinned v3

Use “Show the expenses” in Recued. List captured expenses for a period with a running total, and count what still needs review. Read-only — it re-reads no receipt and re-runs no extraction.

pack:expense-ledgerexpensesboardrecords
by recued-core pinned v2

Use “Export a period” in Recued. Produce the CSV for one month — every reviewed expense, with totals. Only rows you have reviewed are included, so the export is what you stand behind rather than what the model read.

pack:expense-ledgerexpensesexportcsv
by recued-core pinned v2
View pack details, dependencies, and permissions →

What this is for

Capture receipt handles the paper — a photo, OCR, a total read off the picture. This handles the other half: the card export, where four hundred lines arrive at once and none of them has an image. Both write the same ledger, so a period ends up with the receipts you kept AND the charges you did not.

Setting it up once

Open your export and read the header row. Put those exact column names into the settings below. date, merchant and total are required — they are what tells one charge from another. The rest are optional; leave a box empty and the column is simply not mapped.

Give each card its own label. Every row's id is scoped to it, so the same amount on the same day at the same merchant stays two separate expenses across two cards, which is what they are.

Re-running is safe

Card exports overlap by design — the last statement period, every time. Each row's id is derived from its own date, merchant and total plus the card label, so importing the same export twice reproduces the same ids and adds nothing. The summary says how many you already had. Two identical charges on one day are still two rows: they are told apart by their position in the file, and a re-import walks the file the same way.

Check first

Turn on Check first and Recued reads the whole file, puts every row through exactly the checks a real import would, then throws the result away and tells you what would have happened. Nothing is recorded.

Do this the first time you map a card. A column pointed at the wrong field imports perfectly — every row lands, nothing is refused — and the only sign is that the numbers are wrong.

What it does NOT do

An imported row is not checked against receipts you photographed. The importer cannot see them. Buy lunch on the card, photograph the receipt, then import the statement, and the ledger holds both — one from the picture, one from the card. duplicate_suspect is set by Capture receipt when it finds a match among captured receipts, and an import leaves it alone rather than guessing across two different kinds of record.

Everything lands as needs_review. An imported line has no receipt, no OCR and no category unless your export carried one, so it goes into the same queue a low-confidence capture goes into and Review expense clears it. Nothing is marked captured on the strength of a CSV.

Dates are stored exactly as your export writes them. 03/08/2026 stays 03/08/2026; reading it would mean guessing whether that is March or August, and a guess about dates silently reorders a year. List expenses orders by when Recued last touched the row and says so.

When a number will not read

A cell that cannot be parsed is stored EMPTY, never as zero, and the row still lands. The summary counts them and shows the first few with their line numbers. Set the thousands separator your export uses — "1,240.50" reads as nothing without it, and a period that quietly drops its largest charges still looks like a clean import.

How it works 24 steps

Inspect the data fetches, transforms, gates, and output this recipe runs.

Process (24 steps)
file_id trim
Trim whitespace from setting file
has_file compare
Check if file id has data
file_guard guard
Stop if has file equals
card trim
Trim whitespace from setting card label
has_card compare
Check if card has data
card_guard guard
Stop if has card equals
identifying_mapped all
Check if all conditions are true
identifying_guard guard
Stop if identifying mapped equals
file_read ?
csv_text decode_base64
Apply decode_base64
columns_all default
Apply default
columns filter
Filter by condition
numeric_all default
Apply default
numeric_present filter
Filter by condition
numeric_fields pluck
Extract field from each item
imported ?
any_unreadable compare
Check if imported unparsed is greater than 0
any_refused compare
Check if imported failed is greater than 0
stopped default
Apply default
was_check compare
Check if imported dry run equals
mode ternary
Apply ternary
unreadable to_table
Format results as a data table
skip: step.any_unreadable equal false
refused to_table
Format results as a data table
skip: step.any_refused equal false
card_summary to_summary
Format results as a summary card
Settings 13 configurable

Configurable at install. Defaults shown — change them anytime in Recued.

file setting = [object Object]
period setting =
currency setting = GBP
delimiter setting = ,
card label setting =
column tax setting =
check first setting = false
column date setting = Date
column note setting =
column total setting = Amount
column category setting =
column merchant setting = Description
thousands separator setting = ,

About

Tags

pack:expense-ledgerexpensescsvimportbookkeepingbatch

Details

24 steps 13 configurable settings recipe_id: import-expenses