Developers
API reference

Receipts

get/v1/receipts

List receipts

receipts.listread tokenidempotent

The ledger's receipts, newest first: the app's receipt inbox. Filter by status=parsed for the ones read but not yet on a transaction.

Parameters

limit
integer · query
Page size, 1–200.
cursor
string | null · query
The next_cursor of the previous page.
status
string | null · query
Only receipts in this state: pending, parsed, attached, failed.
transaction_id
integer | null · query
Only receipts attached to this transaction.
X-Organization-Id
string | null · header

Returns 200 · ReceiptList

data
array of Receipt · required
has_more
boolean · required
next_cursor
string | null · required
Example
curl -X GET "https://api.lumaledger.app/v1/receipts" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/receipts

Upload a receipt

receipts.createwrite tokenidempotent

Upload a receipt as multipart/form-data and have it read. The answer is the receipt as read (status attached, parsed or failed), which takes a few seconds. Given a transaction_id it is put on that transaction; otherwise it is attached only when one charge clearly matches. The same file uploaded twice is one receipt (already_here).

Parameters

Idempotency-Key
string | null · header
Any unique string (a UUID is ideal). A retry with the same key returns the first attempt's response instead of doing the work twice. Keys are kept for 24 hours.
X-Organization-Id
string | null · header

Body · multipart/form-data

file
file · required
The receipt: a JPEG, PNG, WebP, GIF, HEIC or PDF, at most 10 MB.
transaction_id
integer | null
Attach it to this transaction instead of letting the matcher find one.

Returns 201 · ReceiptUpload

already_here
boolean · required
True when these exact bytes were already a receipt in this ledger: that receipt is returned and nothing new was made.
amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.
Example
curl -X POST "https://api.lumaledger.app/v1/receipts" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F "file=@path/to/file"

Try it isn't available for file uploads — use the curl example above.

delete/v1/receipts/{receipt_id}

Delete a receipt

receipts.deletewrite tokendestructiveidempotent

Delete a receipt and its file. If it was on a transaction, the split it made comes off too.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Returns 204 with no body.

Example
curl -X DELETE "https://api.lumaledger.app/v1/receipts/{receipt_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
get/v1/receipts/{receipt_id}

Get a receipt

receipts.getread tokenidempotent

One receipt with its line items and the transaction it is on.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · Receipt

amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.
Example
curl -X GET "https://api.lumaledger.app/v1/receipts/{receipt_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/receipts/{receipt_id}/attach

Attach a receipt to a transaction

receipts.attachwrite tokenidempotent

Put a receipt on the transaction it paid for, replacing any transaction it was on. Its line items become the transaction's split, scaled to what the card was actually charged.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Body · AttachRequest

transaction_id
integer · required
The transaction the receipt paid for (see transactions.list). It must be an imported one: a bank or card charge.

Returns 200 · Receipt

amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.
Example
curl -X POST "https://api.lumaledger.app/v1/receipts/{receipt_id}/attach" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": 1
  }'
post/v1/receipts/{receipt_id}/detach

Detach a receipt from its transaction

receipts.detachwrite tokenidempotent

Take a receipt off its transaction, and its split with it. The receipt stays, parsed, ready to attach elsewhere.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · Receipt

amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.
Example
curl -X POST "https://api.lumaledger.app/v1/receipts/{receipt_id}/detach" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
get/v1/receipts/{receipt_id}/download

Download a receipt's file

receipts.downloadread tokenidempotent

A short-lived URL for the receipt's image or PDF. A forwarded email that carried no receipt has no file, and says so with a 422.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · Download

expires_at
datetime | null · required
When a signed url stops working. Null for a data: URL.
url
string · required
A signed HTTPS URL for the file, or a data: URL carrying the file itself when it is stored inline. Needs no credential.
Example
curl -X GET "https://api.lumaledger.app/v1/receipts/{receipt_id}/download" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/receipts/{receipt_id}/not-duplicate

Mark a receipt as not a duplicate

receipts.mark_not_duplicatewrite tokenidempotent

Two purchases, not one receipt sent twice: clear duplicate_of_id and let the receipt find its own transaction.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · Receipt

amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.
Example
curl -X POST "https://api.lumaledger.app/v1/receipts/{receipt_id}/not-duplicate" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/receipts/{receipt_id}/reprocess

Read a receipt again

receipts.reprocesswrite token

Read the file again from scratch, for a receipt that failed or was misread. It comes off its transaction first, and is placed again from the new reading.

Parameters

receipt_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · Receipt

amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.
Example
curl -X POST "https://api.lumaledger.app/v1/receipts/{receipt_id}/reprocess" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"

Objects

AttachRequest

Fields

transaction_id
integer · required
The transaction the receipt paid for (see transactions.list). It must be an imported one: a bank or card charge.

Download

Where to fetch a file. Fetch it promptly: the URL stops working at expires_at, and asking again gives a fresh one.

Fields

expires_at
datetime | null · required
When a signed url stops working. Null for a data: URL.
url
string · required
A signed HTTPS URL for the file, or a data: URL carrying the file itself when it is stored inline. Needs no credential.

Money

An amount and its currency. `amount` is a base-10 string with two decimal places and an optional leading minus sign. Parse it with a decimal type, not a float.

Fields

amount
string · required
Pattern: ^-?\d+\.\d{2}$.
currency
string · required
ISO 4217 code. Pattern: ^[A-Z]{3}$.

Receipt

A receipt and what was read from it. Amounts are in the currency the receipt was printed in (currency), which may not be the currency the card was charged in.

Fields

amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.

ReceiptEmail

Why a forwarded email yielded no receipt.

Fields

reason
string | null · required
Machine value, e.g. no_attachment.
snippet
string | null · required
subject
string | null · required

ReceiptItem

One printed line of the receipt.

Fields

amount
Money · required
category_id
integer | null · required
The expense account this line is filed under once the receipt is attached (see accounts.list).
description
string · required
As printed.
id
integer · required
item_category
string | null · required
A short label the reader gave the item, e.g. Produce.
line_no
integer · required
quantity
string | null · required
Decimal string, when printed.
unit_price
Money | null · required

ReceiptList

A page of receipts, newest first.

Fields

data
array of Receipt · required
has_more
boolean · required
next_cursor
string | null · required

ReceiptUpload

Fields

already_here
boolean · required
True when these exact bytes were already a receipt in this ledger: that receipt is returned and nothing new was made.
amount_before_tip
Money | null · required
What the card terminal authorized before a tip was written in.
attached_at
datetime | null · required
card_last4
string | null · required
category_id
integer | null · required
The expense account the reader suggested.
created_at
datetime · required
currency
string · required
ISO 4217. The ledger's base currency until the receipt is read.
duplicate_of_id
integer | null · required
An older receipt this one appears to repeat. Clear it with receipts.mark_not_duplicate.
email
ReceiptEmail | null · required
Set when the row stands for a forwarded email, not a file.
has_file
boolean · required
False for a forwarded email that carried no receipt: there is nothing to download or re-read.
id
integer · required
items
array of ReceiptItem · required
match_confidence
string | null · required
How sure the matcher was of the attachment, 0.00–1.00, as a decimal string.
merchant_name
string | null · required
mime_type
string · required
notes
string | null · required
original_name
string | null · required
parse_error
string | null · required
parsed_at
datetime | null · required
payment_method
string | null · required
receipt_date
date | null · required
sender
string | null · required
Who sent it in (an email address or phone number).
size_bytes
integer · required
source
string · required
How it arrived: upload, email, whatsapp or gmail.
stated_total
Money | null · required
The total as printed, when total was worked out another way.
status
string · required
pending (not read yet), parsed (read, not on a transaction), attached (on a transaction) or failed (could not be read; see parse_error).
subtotal
Money | null · required
tax
Money | null · required
tip
Money | null · required
total
Money | null · required
total_source
string | null · required
Where total came from.
transaction_id
integer | null · required
The transaction it is attached to (see transactions.get). Null until it is attached, or while that transaction is not yet posted.