When employees use a corporate credit card, Bezala helps reconcile the card statement against the receipts those employees uploaded. The reconciliation has three resources working together.
The three resources
A bill (/api/bills) is the credit card statement itself. One bill per cycle, per card or card group.
A bill line (/api/bill_lines) is one transaction on that statement. A €42 lunch becomes one bill line; the statement's monthly fee becomes another. A bill has many bill lines.
A missing receipt is a bill line that hasn't been matched to a receipt yet. Same data, different perspective: the user's missing-receipts list is the set of card transactions where they still owe a paper trail.
The reconciliation goal is simple: for every bill line, either attach a receipt (bill_line.receipt_id points at a receipt the user has uploaded) or mark it as not requiring one (a recurring SaaS subscription where the receipt lives in email).
Importing a bill
Two ways the bill gets in.
Bulk import. Upload an XML, CSV, or TXT file in one of Bezala's supported card-statement formats:
This is how most customers handle Nordea, OP, Handelsbanken, and similar banks. The file gets parsed, a bill is created, and bill lines are created from each statement entry.
Real-time push. Some card providers push transactions as they happen via POST /api/:provider/bill_lines. This is the integration pattern for partners — the provider posts each transaction within minutes of the swipe, and the employee sees it on their dashboard immediately. Useful when the goal is to have a receipt attached before the employee has even gotten back to the office.
The reconciliation workflow
Once bill lines exist, the user opens the missing-receipts view and starts matching:
Each entry is a bill line presented as a partial receipt — date, vendor name, amount, currency. The user picks one and either:
Attaches an existing receipt. They've already uploaded the proof; they just connect the dots. Set bill_line.receipt_id to the receipt's ID.
Creates a new receipt for it. The receipt is created fresh, with bill_line_id set on the new transaction.
Marks the line as "no receipt needed". Documented reason that the line stands on its own — typically a subscription where the receipt is somewhere else.
The third option, in bulk:
This sets receipt_id: 0 on each line — Bezala's sentinel for "no receipt required". The line is reconciled but no receipt was attached.
Manually editing bill lines
You can add and edit bill lines directly when needed — Bezala's parser doesn't always have everything right, and occasionally a transaction needs to be restated:
The bill-line endpoints are accountant-only. Regular users go through the missing-receipts list.
Listing bills
GET /api/bills supports the standard filters plus a few specific to bills:
GET /api/bills/:id returns the bill with its lines embedded and a list of receipts that could potentially be matched to one of those lines (based on the asset account and credit card). This shape is what the Bezala UI uses for the reconciliation screen — for an integration, you can use it as a one-call data load instead of stitching multiple endpoints together.
updated_after accepts the date format YYYYMMDD for bill listing — a slightly different convention from the Unix-timestamp updated_after on most other endpoints. Worth a note in your client.
Bill state and the connection to accounting
Bills have a state field — typically processed once the file has been parsed. The state isn't part of the same lifecycle as expenses; bills aren't approved or accounted in the way receipts are. The receipts attached to bill lines flow through the regular lifecycle, while the bill itself is just a reconciliation artifact.
When the accounting batch runs, the journal entries it generates depend on which receipts are linked to which bill lines. A clean bill (every line matched to a receipt or marked "no receipt needed") produces clean accounting; a bill with unmatched lines creates noise that the accountant has to clean up.
Common integration patterns
Daily statement push. A scheduled job at the customer's bank pushes the previous day's statement file to Bezala via POST /api/bills/import. Works for any bank that can export to a Bezala-compatible format on a schedule.
Real-time card feed. A card provider integrates as a partner using POST /api/:provider/bill_lines. Each swipe creates a bill line within seconds. Combined with email forwarding for receipts, this gets reconciliation as close to real-time as the medium allows.
Auto-attach by amount and vendor. A custom integration reads GET /api/missing_receipts and GET /api/transactions?state=draft and matches them by amount and vendor name. When the match is high-confidence, it sets bill_line_id on the receipt and reduces the user's manual work to a confirmation tap.
Subscription auto-coding. Periodic SaaS charges are predictable. A simple rule-based job marks recurring lines (matching a known vendor pattern) as "no receipt needed" automatically — saving the user from chasing receipts that aren't going to arrive.





