space ocr
GuidesArticlesPricingDocs
Invoice OCR

Invoice OCR that turns supplier bills into data you can trust

Invoice OCR that reads supplier, invoice number, dates, totals and every line item into the fields you declare — each value with its box and quad coordinates, a verified verdict, and a review list of what to check.

Every invoice that lands in your inbox is a small data-entry tax. Someone opens the PDF, finds the supplier, the invoice number, the dates, the tax line, the total, then retypes it all into the accounting system — and copies the line items by hand if anyone needs them. It's slow, it's where the typos live, and a single fat-fingered total can hold up a payment run.

Invoice OCR is supposed to take that off your plate: read the bill, get the fields back. The problem with most tools is they hand you a number and ask you to trust it. space-ocr reads the invoice into the fields you declare and returns each value with the region of the page it was read from, together with a review list naming the values that did not check out. Before you approve a payment you look at those few figures instead of re-reading the whole page.

See a real invoice you can check

Hover any field below — the box on the invoice is where that value was read. The supplier, the issue date, the billing period, the due date, the billed amount, the running total, and each line item are all read straight from a real parsed result, not a mockup.

Invoice with extracted-field bounding boxes
Verified fields
Invoice

Each value with a box carries a verified on-page location — in data.cells[path], that is box + 4-point quad + evidence.match_ratio — on a 0–1000 normalized grid (0,0 top-left → 1000,1000 bottom-right), the same shape the live API returns. Hover a field to trace it back to the pixels it came from.

Three shapes, one contract
Take the page as declared fields (POST /ocr/fields), as layout-preserving Markdown (POST /ocr/markdown), or as plain text in reading order (POST /ocr/text). All three answer with the same envelope — data.values, data.cells keyed by path, data.review and data.image — so the checking code you write once keeps working.
Every value addressable
Supplier, invoice number, issue and due dates and every amount get an entry in data.cells[path]: box as axis-aligned xmin/ymin/xmax/ymax on a 0–1000 normalized grid, and quad as four points that follow the tilt of the page. data.image gives the width and height those coordinates are measured against.
Line items, not just totals
Declare items as an array field whose children describe one row — description, quantity, unit price, amount. Each cell keeps its own coordinates under a path like items[0].amount and the row itself is the union box at items[0], so a wrapped or merged line stays traceable.
Declare the rules, get the exceptions
There is no template to pick; you name the fields. Attach required to the invoice number, type date to the dates, type number with min to the amounts, and not_near to the supplier so a name lifted out of the recipient block raises near_conflict instead of passing quietly.
Tax and totals
Subtotal, tax lines and the grand total are ordinary number fields. data.values keeps the reading as it came back; declare a scalar type and data.normalized carries the parsed figure beside it, with type_mismatch when it will not parse and out_of_range when a min or max is broken.
Clean exports
CSV with a UTF-8 BOM (Excel- and CJK-safe, line items unfolded into sub-rows) and JSON over a REST API — drop straight into your spreadsheet or accounting import.
AP automation
Post invoices to /upload as async jobs and take the HMAC-signed ocr.completed webhook when each one is read, so new supplier bills flow into a sheet without anyone watching the queue.

How invoice OCR works in space-ocr

Drop an invoice into the app and it's read into a row: supplier, dates, amounts, and the line items as a sub-table you can sort, filter and export. A PDF invoice is rendered to an image per page first, then read. If you're calling the API directly, send the page image (the public API takes raster images — JPEG, PNG, GIF, BMP, TIFF, WebP) and you get the same structured result back.

You don't describe an invoice from scratch, and there is no template to choose. Send fields — the names your ledger already uses, each with the checks that fit an invoice — or send autoFields on an unfamiliar layout and keep the names that come back as your declaration. Line items are a single array field whose children describe one row.

What comes back for each invoice:

  • data.values — the business data, in exactly the shape you declared.
  • data.cells[path] — box and quad for that value, plus verified, review and evidence (the character cross-check detail, including text_match, printed_text and match_ratio).
  • data.review.flagged — the work list: each entry is a path and its reasons, ranked, with index 0 as the primary one.
  • data.normalized — the parsed number or ISO date for every field you gave a scalar type.
  • data.image — the width and height every coordinate is measured against.
declare invoice fields and read one page image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
curl -s https://api.space-ocr.com/ocr/fields \
  -H "Authorization: Bearer $SPACE_OCR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/invoice-page-1.png",
    "imageType": "url",
    "fields": [
      { "name": "supplier", "type": "string", "required": true, "not_near": ["Bill To", "御中"] },
      { "name": "bill_to", "type": "string", "near": ["Bill To", "御中"] },
      { "name": "invoice_no", "type": "string", "required": true, "pattern": "^[A-Za-z0-9-]{4,}$" },
      { "name": "issue_date", "type": "date", "required": true },
      { "name": "due_date", "type": "date" },
      { "name": "subtotal", "type": "number", "min": 0 },
      { "name": "tax", "type": "number", "min": 0 },
      { "name": "total", "type": "number", "required": true, "min": 0 },
      {
        "name": "items", "type": "array",
        "children": [
          { "name": "description", "type": "string" },
          { "name": "quantity", "type": "number" },
          { "name": "unit_price", "type": "number" },
          { "name": "amount", "type": "number" }
        ]
      }
    ]
  }'

How to OCR an invoice

  1. Add the invoice
    In the app, drop the invoice (PDF or image) — each page is rendered to an image and queued for OCR. For AP automation, post it to /upload and get a webhook when it's read.
  2. Declare the fields
    Send fields with the names your ledger uses and the checks that fit an invoice — required on the invoice number, type date on the dates, type number with min on the amounts — or send autoFields on an unfamiliar layout and keep the names that come back. Line items are one array field with children.
  3. Read the structured result
    Business data is in data.values. Coordinates and the per-value verdict are in data.cells[path] — box, quad, verified, review, evidence — and data.image gives the frame those coordinates are measured in.
  4. Verify before you post
    Iterate data.review.flagged instead of thresholding a score. Each entry names a path and its reasons; jump to data.cells[path], highlight the box or quad on the page and correct the value. Edits are stored beside the original OCR value.
  5. Export or query
    Download CSV (UTF-8 BOM, line items unfolded) for your accounting import, or query a stored sheet with GET /view using where, sort and select — no re-OCR, no extra charge.

Simple, predictable pricing

One page read is one credit — $0.05, tax included, the same price in the app or over the API. Every account gets 100 credits a month with no card, and failed scans are never charged. Flat plans add monthly credits, more sheets and storage.

Free
$0
  • 100 credits / month
  • 3 sheets
  • 1 GB storage
Free — no card
Starter
$19/mo
  • 500 credits / month
  • 15 sheets
  • 10 GB storage
Start free
Most popular
Pro
$39/mo
  • 1,100 credits / month
  • Unlimited sheets
  • 100 GB storage
Start free
What does invoice OCR pull off an invoice?
Whatever you declare. Supplier, invoice number, issue and due dates, billing period, subtotal, tax and grand total are ordinary string, date and number fields, and the line items are one array field whose children describe a row. Every value gets an entry in data.cells[path] with the box and quad it was read from.
Can it read the line items, not just the total?
Yes. Declare items with type 'array' and children for one row (description, quantity, unit price, amount). Each cell keeps its own coordinates under a path like items[0].amount, the row itself is the union box at items[0], and the sheet export unfolds the rows into sub-rows.
How do I know the total it read is right?
You work the review list rather than tune a score. data.review.flagged names the paths that were flagged, each with ranked reasons such as text_mismatch, missing, type_mismatch or out_of_range; verified is true where a check ran and nothing was raised, false where something was, and null where there was nothing to compare. Open data.cells[path], draw its box or quad over the page and read the printed region yourself. Coordinates are evidence of where a value came from, not proof that it is right — two readers can agree on the same misread — so keep your own business checks in place.
Can I export invoices to CSV or feed them into accounting?
Yes. Download CSV with a UTF-8 BOM so Excel opens Japanese, Korean and Chinese text correctly, with line items unfolded into sub-rows, or take JSON over the REST API. Push invoices to /upload as async jobs and a signed webhook fires when each is read.
Does it handle PDF invoices?
The web app accepts PDF invoices directly — it renders each page to an image and runs OCR. The public API takes raster images (JPEG, PNG, GIF, BMP, TIFF, WebP), so when calling the API you send the page image.
How much does invoice OCR cost?
One credit per page — $0.05, tax included — with 100 credits a month free and no credit card. Failed scans are never charged. Flat plans (Starter and Pro) add monthly credits, more sheets and storage — see the table above.

Turn your supplier invoices into checkable data

Free tier — 100 credits a month, no credit card. Every value comes back with its on-page location.

Related