Developer guide
Document extraction
Extract the fields you define in a JSON Schema from a PDF or an image.
Apart from POST /v1/systemone, you can use the extraction API, POST /v1/extract, which is built to extract structured data from PDFs and images. You don’t write the questions yourself: you describe the fields you want, and the API finds each one in the document and returns it in the type you asked for.
Extracting fields from a document
Send a PDF or an image together with a JSON Schema that lists the fields you want. For each field, Strom finds the line in the document that contains it. Scanned pages and images are converted to text using OCR automatically.
curl https://api.uprelic.com/v1/extract \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "strom-1.0.7",
"schema": {
"properties": {
"invoice_number": {"type": "string"},
"invoice_date": {"type": "string", "format": "date"},
"total": {"type": "number", "format": "amount", "description": "The total including tax"},
"paid": {"type": "boolean"}
}
},
"document": {"url": "data:application/pdf;base64,JVBERi0xLjQK..."}
}'document.url can be a public URL or a base64 data: URL. PDFs can have at most 8 pages. model can be strom-fast or strom-base (beta), or their versioned names; strom-base is much slower and costs more.
Each field can have a description. Use it to tell the model what to look for when the name alone is ambiguous, for example whether total includes tax.
API Response
For each field, the response contains:
text: the line of the document the field was found on, exactly as it appears.value: that line converted to the field’s type, for example a date as1988-12-16or an amount as14982.0. See the table below.confidence: how sure the model is that it picked the right line, from 0 to 1.pageandbox: where the line is.boxis[left, top, right, bottom]as fractions of the page’s width and height.
If the document doesn’t contain a field, that field is null.
{
"model": "strom-1.0.7",
"fields": {
"invoice_number": {
"text": "17795", "value": "17795", "confidence": 0.98,
"page": 1, "box": [0.7731, 0.1286, 0.8225, 0.1424]
},
"invoice_date": {
"text": "12/16/88", "value": "1988-12-16", "confidence": 0.94,
"page": 1, "box": [0.7731, 0.1552, 0.85, 0.1705]
},
"total": {
"text": "$14,982.00", "value": 14982.0, "confidence": 0.55,
"page": 1, "box": [0.8306, 0.3529, 0.9256, 0.3662]
},
"paid": {"text": null, "value": false, "confidence": 0.58, "page": null, "box": null}
},
"usage": {
"input_tokens": 20060, "output_tokens": 5, "cached_input_tokens": 25344,
"cost": 0.00084252, "currency": "usd"
},
"metadata": {"server_processing_time_ms": 3405}
}Field types
The field’s type in the schema decides how text is converted into value:
| Type in the schema | Line in the document | value |
|---|---|---|
{"type": "string"} |
Invoice no. 17795 | "Invoice no. 17795" |
{"type": "string", "format": "date"} |
Date: 12/16/88 | "1988-12-16" |
{"type": "number"} |
Quantity 12 | 12 |
{"type": "number", "format": "amount"} |
Total EUR 1.234,50 | 1234.5 |
{"type": "number", "format": "percent"} |
VAT 19% | 19 |
{"type": "boolean"} |
(answered without a line) | true or false |
{"enum": ["EUR", "USD"]} |
(answered without a line) | "EUR" |
If the line contains more than one date, number or percentage, we don’t guess which one you meant: value is then the whole line, the same as text.
Cost and errors
- You pay for input tokens at the same price as
POST /v1/systemone. The cost of each extraction is inusage.cost. For example, a 2-page PDF invoice with a 10-field schema used about 28,000 input tokens. - The “Improve document extraction” switch under Billing comes with the paid plans. Each run that improves your extraction is charged to your balance for the AI processing it uses, at twice our provider's price, about €2 to €3 a run.
- Documents that can’t be read are not charged. You get a
422with the reason indetail, for example when the file isn’t a PDF or image, has no text, or has more than 8 pages.