Receipts (OCR)
Upload photos; Kiravy AI extracts; review and save as transactions.
The Receipts flow turns photos and PDFs into ledger entries with minimal typing. Upload, Kiravy AI extracts vendor / date / total / SST / line items, you review the highlighted fields, save β it lands as a transaction with the receipt photo attached for audit.
Open it from any client β Receipts.
When to use it
- Bills, invoices, and till receipts that aren't already in SQL Account
- Expense claims from staff who hand you paper or phone photos
- Anything where retyping the data is slower than reviewing AI output
If your client's books are entirely in SQL Account and synced cleanly, you'll mostly use the AR/AP tabs instead. Receipts is for things outside the accounting software.
Uploading
On desktop
- Drag a file into the drop zone, or click Choose file
- Supported: PNG, JPEG, HEIC, HEIF, PDF
- Max 10 MB per file
On mobile
- Tap π· Take photo β opens the device camera straight away (good for the firm staffer who just got handed a receipt)
- Or tap Pick from library for a file already on the phone
One receipt at a time. Multi-upload is on the roadmap. For now, drop one file, wait a second, drop the next. The upload itself is non-blocking β extraction runs in the background, so you can immediately upload the next one.
What happens after upload
| Stage | What it means | Roughly how long |
|---|---|---|
| Pending | File is in storage, extraction hasn't started yet | < 1s |
| Reviewing | Kiravy AI finished extracting and is waiting for you | 3β6s after upload |
| Failed | Extraction errored out (blurry image, unsupported format, etc.) | Same window |
| Saved | You reviewed it and saved as a transaction | After your action |
| Discarded | You rejected it β not usable for whatever reason | After your action |
You don't have to wait on the upload screen β the list page updates automatically as receipts move from Pending to Reviewing.
What Kiravy AI extracts
The AI returns these fields with a per-field confidence score (0 to 1):
- Vendor / merchant name
- Transaction date (ISO
YYYY-MM-DD) - Total (gross)
- Tax / SST
- Currency (MYR / USD / SGD detected)
- Payment method (e.g. Cash, Card)
- Line items β product name, quantity, unit price, line total
Kiravy AI handles English, Bahasa Malaysia, and Chinese receipts including hand-written totals. Quality drops on receipts that are skewed, partially shadowed, or printed in receipts where amounts have run off the edge β that's where the low confidence flag comes in.
The review screen
Click any Reviewing receipt β side-by-side view:
| Left | Right |
|---|---|
| Receipt image (click to enlarge in a modal). PDFs show a link to open. | Editable form with all the AI's extractions |
Fields with confidence below 70% are surrounded by an amber ring and called out in a banner at the top: "Please double-check the highlighted fields."
Before you can save, you have to either touch each amber field (to confirm or correct it) or click Looks correct β Kiravy refuses to save while there are unconfirmed low-confidence fields. This isn't friction for friction's sake β it's the difference between "AI guessed and you trusted it blindly" and "AI guessed and you signed off".
Side actions
- Re-extract β runs the OCR again. Useful if you cropped/rotated the image before re-uploading, or if a model improvement landed since the first try. Counts as 1 AI usage unit.
- Discard β soft-delete; see Discarding below.
- Save as transaction β green button at the bottom of the form.
Saving as a transaction
Click Save as transaction:
- Form validates (date, type, subtotal, currency required)
- All low-confidence fields must be confirmed
- A new transaction is created with:
source = 'receipt'source_refpointing back to this receipt's id- all the form data you signed off on
- The receipt's status becomes Saved
- You land on the transaction detail page
The receipt photo and the transaction stay linked β open either side, click through to see the other. The saved transaction becomes a normal entry in Kiravy and posts a balanced journal entry to the ledger like any other; nothing is pushed to an outside system.
Discarding
Sometimes the receipt isn't usable β duplicate, wrong client, blurry beyond saving. Click Discard:
- Confirmation: "The receipt won't become a transaction. The original file is removed from view; this can't be undone from the UI."
- Optionally add a short reason
- Receipt status becomes Discarded (soft-delete β the row stays for audit, but it's hidden from default lists)
You can't discard a receipt that already has a saved transaction linked to it. Delete the transaction first if you really need to remove the receipt β but think twice: tax audit requires keeping the receipt for 7 years either way.
The list page
Receipts are grouped into three sections, in order:
- Needs review β Reviewing and Failed receipts. This is your work queue.
- Saved β already booked. Click a row to jump to its transaction (not the receipt review screen).
- Discarded β rejected, low-opacity.
Each row shows a thumbnail (or PDF icon), the extracted vendor (or upload date if nothing was extracted yet), an uploader badge (Firm or Client portal β see below), file size or extracted date, the total, and a status badge.
Receipts uploaded by clients (portal)
If your client uses the Client portal, they can upload receipts themselves. Those land in the same list with an Uploader: Client portal badge so you can tell at a glance. You review them exactly the same way β the portal is just an additional way receipts arrive.
When you Discard a portal-uploaded receipt, the portal user sees a "your accountant couldn't use this one" badge with your optional reason β encourages them to re-upload a clearer photo.
Storage and privacy
- Receipt files live in a private Supabase Storage bucket, gated by RLS
- Only firm staff assigned to the client (plus the client portal user) can view them
- Image URLs are signed with a 1-hour expiry β they aren't browsable from a guess-the-URL attack
- Files stay in storage after the receipt is saved as a transaction β for audit, you need the photo to defend the entry years later
- Hard delete from storage is a service-level operation (for PDPA / GDPR cleanup) and isn't user-facing
What can fail (and what to do)
| Symptom | Likely cause | Fix |
|---|---|---|
| Receipt stuck in Pending for > 30s | Extraction worker is busy or failed silently | Refresh the list β if still pending, open the receipt to trigger a retry |
| Failed status | Image too blurry, no text detected, unsupported language | Re-upload a clearer photo, or click Re-extract with a better-cropped version |
| Amber rings on every field | AI is uncertain about the whole receipt | Compare side-by-side carefully; mostly happens on hand-written receipts. After 3 failed attempts the row is locked. |
| Vendor field is gibberish | AI hallucinated from a low-contrast logo | Just type the correct name β confirming the field unlocks Save |
| Total doesn't match SST + subtotal | AI extracted them inconsistently | Fix one or both β Kiravy shows the computed total live so you can sanity-check |
What's next
- Transactions β where saved receipts end up
- Client portal β let your clients upload directly
- Month-end close β review-queue pass over the saved transactions