API reference
Three endpoints. Post a fixed-width document, get JSON back.
Base URL https://reamline.com. Authenticate with an API key in the
x-api-key header, or a session token as Authorization: Bearer.
Requests and responses are JSON throughout. Every request sends the document
either as text (a plain string) or textB64 (base64 of the original bytes).
Prefer textB64, for the reasons in encoding.
POST /v1/extract
Turn a document into JSON.
curl -s -X POST https://reamline.com/v1/extract \
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
-d '{"templateId":"tpl_...","textB64":"..."}'
| Field | |
|---|---|
textB64 or text | The document. Required. |
templateId | Which document type to use. Omit it and the service works it out from your recognition rules. |
revision | Pin to a specific published version. Defaults to the live one. |
template | An inline template object, instead of a stored one. Useful for testing without publishing. |
The response carries one entry per document found:
{
"template": "Austen Statement@3",
"summary": { "documents": 63, "ok": 62, "warned": 1, "failed": 0 },
"routed": "tpl_...",
"documents": [
{
"index": 0,
"status": "ok",
"data": { "accountNumber": "A2R755", "totalOutstanding": "5059.68",
"transactions": [ { "date": "14/04/2026", "outstandingValue": "2071.30" } ] },
"issues": [],
"diagnostics": { "pages": 1, "coverage": 0.97 }
}
],
"usage": { "transforms": 78, "limit": 100, "remaining": 22 }
}
routed appears only when the template was chosen rather than named.
| Status | |
|---|---|
200 | Processed. Check summary, because a partly-bad batch still returns the good documents. |
401 | Missing or rejected credentials. |
404 | No published revision for that templateId. |
422 | NO_TEMPLATE_MATCH. No recognition rule claimed the file; the body lists what was tried. |
429 | LIMIT_REACHED. Monthly allowance used up. |
Per-document status
ok, warned or failed, with issues explaining any that are not ok. A
warning means the data is there but something did not add up; a failure means a
declared check could not be evaluated at all.
This is why the response is a 200 with per-document status rather than an
error for the whole batch: fifty-four good statements should not be held back by
one bad page.
POST /v1/route
Ask which document type a file is, without processing it. Not charged.
curl -f -s -X POST https://reamline.com/v1/route \
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
-d @payload.json
{
"template": { "id": "tpl_...", "name": "Austen Statement", "revision": 3 },
"priority": 100,
"candidates": [
{ "template": "tpl_...", "name": "Austen Statement", "matched": true, "priority": 100 },
{ "template": "tpl_...", "name": "Austen Invoice", "matched": false, "priority": 100 }
]
}
A file nothing recognises is a 422, not a 200 with an empty answer. That way
curl -f fails and a script working through a folder can set the file aside
rather than silently doing nothing.
candidates lists every rule that was tried and whether it matched, which is
what makes “no template matched” actionable rather than infuriating.
If two document types match at the same priority, the response includes
ambiguous naming both. The winner in that case is not meaningful, so give the
more specific rule a higher priority.
GET /v1/health
No authentication. Useful for a monitor.
{ "ok": true, "engine": { "version": "0.1.0", "schemaVersion": "1.0" } }
GET /v1/usage
Your allowance this month.
{ "period": "2026-08", "transforms": 78, "requests": 80,
"limit": 100, "remaining": 22, "plan": "free" }
Values in the output
| Declared as | You get |
|---|---|
string | Trimmed text. |
money | A decimal string such as "5059.68", never a JSON number. |
decimal | The same, without currency conventions. |
date | The raw text by default; a normalised form if the template asks. |
Money is a JSON string on purpose. The JSON spec does not fix a precision for numbers, and in practice almost every parser reads them into IEEE-754 doubles, so summing two hundred line values accumulates error. That is not acceptable in accounting data. Sent as a string, every figure survives the round trip exactly as printed, and the service does its own arithmetic in decimal.
##### where a number overflowed its column, you
get the raw characters plus a warning, never a silent null. Losing
data quietly is worse than handing back something you can see is wrong.