Extract invoice data
Accounts payable teams still spend hours a week keying in vendor invoices that arrive as PDFs or scans in a different layout every time. This endpoint reads an invoice and returns vendor details, line items, subtotal, tax and grand total as structured JSON, ready to post directly into a ledger.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The layout problem invoices create
No two vendors format an invoice the same way — one puts the tax breakdown in a footer table, another buries it in a paragraph, a third splits shipping and handling into separate lines while a fourth folds them into the subtotal. A finance team receiving invoices from dozens of suppliers is really receiving dozens of different documents that happen to share a name, and someone has to normalize all of it before it can be paid or booked. That normalization work rarely scales with headcount, which is why it's usually the first thing an automation project targets.
Who this replaces manual entry for
Accounts payable clerks keying vendor bills into an ERP, procurement teams matching invoices against purchase orders, bookkeeping services processing client invoices at volume, and SaaS products that let a business upload a vendor bill and expect usable data back rather than a flat scan. Small finance teams especially feel the pinch, since a single person may be responsible for invoices from every supplier the company works with.
The shape of the result
Submit the invoice, receive a task_id right away, and the completed job returns vendor name and address, invoice number and date, due date, individual line items with description, quantity and unit price, plus subtotal, tax and grand total — the fields an accounting system actually posts, not a transcript of the page.
Where it sits in the payables pipeline
Because the endpoint is asynchronous and priced per page rather than per invoice regardless of length, a multi-page invoice with dozens of line items is billed proportionally: an inbox-monitoring service pulls incoming invoice PDFs, submits each one on arrival, and the webhook delivers structured data straight into the three-way match against the purchase order and receiving record.
A format shaped by decades of paper
The modern commercial invoice traces its structure back to paper ledgers — a header of who's billing whom, a body of itemized charges, a footer of totals — a layout that has survived the move to PDF mostly unchanged, which is exactly why automated reading of it still requires understanding invoice structure specifically rather than treating it as generic text.
What you can do with it
Accounts payable automation
An AP team forwards incoming vendor PDFs to the API and posts the parsed line items and totals directly into the ERP.
Three-way matching
Procurement compares extracted invoice line items against the original purchase order and goods-received note before approving payment.
Bookkeeping services at scale
A bookkeeping firm processes client invoices from dozens of vendors without training staff on each vendor's layout.
Expense platform ingestion
A spend-management product lets customers upload vendor invoices and returns categorized, structured spend data automatically.
FAQ
How does the Invoice OCR API work?
Send the invoice file to POST /ocr/invoice, get a task_id immediately, and receive the structured JSON by webhook or a signed link once processing finishes.
Is it free to try?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
What does it cost?
$0.009 per request plus $0.0571 per page, published and flat, so a longer invoice costs proportionally more, not per line item.
What file formats are supported?
PDF invoices and clear image scans both work; a legible source page gives the most complete extraction.
Does it handle multi-page invoices?
Yes, and pricing scales per page, so a two-page invoice with a long itemized list is billed accordingly.
Can it match different vendor layouts automatically?
Yes, it's built to read invoice structure generally rather than a fixed template, so it adapts across vendors without per-vendor configuration.
Is it accurate enough to skip manual review?
It's accurate on standard invoice layouts, but as with any automated extraction, high-value or unusual invoices are worth a quick human check before posting.
Am I billed for a failed extraction?
No. A failed task retries automatically up to three times and is never charged; you get a clear error instead.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/ocr/invoice \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/factura.jpg"}'const res = await fetch("https://api.kit.forhosting.com/ocr/invoice", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/factura.jpg"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/ocr/invoice",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/factura.jpg"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/ocr/invoice", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/factura.jpg"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/factura.jpg"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/ocr/invoice", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"image": "https://ejemplo.com/factura.jpg"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "ocr.invoice",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 10 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
413 | input_too_large | The file exceeds the size limit. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |