Integrate Robodam Scan into your own process: send an invoice PDF and get structured data (JSON) and, when needed, an accounting import file (Rivilė .eip or Centas XML). Works with Power Automate, cron, Postman and scripts.
below {BASE} — the API address https://scan-api.robodam.com (NE the app/login address is scan.robodam.com — it serves only the browser interface). For monitoring: GET {BASE}/health (a root path, not under /api/v1) returns {"status":"healthy"}.
Every request must carry your personal Bearer key in the header. For automation (Power Automate, cron, scripts) create a permanent API key: Settings → Account → API keys — raktas (rbs_…) is shown once and stays valid until you revoke it. For quick manual tests the “Test key” above also works, but it is temporary (a session key) — do not use it for automated flows.
Authorization: Bearer <your-key>Synchronous reading: you send the PDF and get the data in the same response (no extra requests or polling).
{BASE}/api/v1/invoices/extract-directmultipart/form-data, the document is passed in the field file. Accepted formats: PDF and photos (JPG / PNG / HEIC) — photos are converted to PDF on the server automatically. Optional parameters:
| Parametras | Numatyta | Value |
|---|---|---|
| save_to_profile | true | Whether to save the reading in your history. |
| allow_duplicate | false | Jei false — sending the same file again returns the previous result free of charge (see section 5). |
| include_export | — | rivile, centas arba finvalda — also return the accounting file (see section 6). |
Limits: PDF only; up to 10 MB; up to 20 pages (an administrator can raise it for a specific customer; /extract-direct keeps its own lower cap); 30 requests/min. A PDF with multiple invoices is treated here as a single document (splitting only happens via /upload).
curl -X POST "{BASE}/api/v1/invoices/extract-direct" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@saskaita.pdf"{
"success": true,
"filename": "saskaita.pdf",
"confidence_score": 100, // 0–100, AI confidence
"auto_validated": true, // true kai confidence_score >= 85
"validation_warnings": [], // text for a human
"validation_issues": [], // the same for a machine — with a code (see below)
"risk_flags": [], // worth checking before booking
"document_type": "invoice", // invoice / credit_note / receipt / unknown / ...
"from_cache": false,
"duplicate_of": null,
"extracted_data": { ... }, // invoice fields (see section 3)
"export": null // filled in only with include_export
}extracted_data)All fields are optional — if a field is not on the invoice, it is null or omitted.
{
"invoice_number": "SF Nr. 70",
"invoice_date": "2026-05-29", // YYYY-MM-DD
"due_date": "2026-06-12",
"currency": "EUR",
"subtotal": 1100.0, // suma be PVM
"tax_amount": 231.0, // VAT amount (absent when 0% / no VAT)
"tax_rate": 21, // dokumento PVM %, sveikas sk.
"total_amount": 1331.0, // suma su PVM
"bank_account": "LT74...",
"document_type": "invoice",
"vendor": { // vendor (seller)
"name": "MB Decentrum",
"company_code": "306265414", // company code
"tax_id": "306265414", // VAT code (LT… if a VAT payer)
"address": "Ceikiniu g. 3, Lietuva"
},
"customer": { // buyer
"name": "UAB Robodam",
"company_code": "...",
"tax_id": "LT100017242115",
"address": "Kaunas, Vytauto pr. 27"
},
"line_items": [
{
"description": "Programavimo paslaugos",
"quantity": 1.0,
"unit": "vnt",
"unit_price": 1100.0, // vieneto kaina be PVM
"total": 1100.0, // line total excluding VAT
"tax_rate": 21, // line VAT % (if absent — the document tax_rate)
"item_number": "..." // the vendor\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s item code, if any
}
],
"notes": "..."
}The response may also contain _validation bei _recovery blokai — tai vidiniai diagnostikos duomenys, juos galite ignoruoti.
confidence_score pasako, kiek we are. These two fields tell you kas negerai — and are meant for a program, not a human. Both are always in the response; for a clean document they are empty lists.
validation_issues — what we checked{
"code": "total_mismatch", // stable — safe to branch on
"field": "total_amount",
"message": "Total amount (100.0) does not match calculated total (121.00)",
"severity": "warning", // warning | error
"kind": "semantic" // format | semantic | extraction
}kind skiria our check (format — format, semantic — amounts and dates) from the model\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s own note about its reading (extraction). The latter are free text and carry no code — inventing one would promise a contract we would not keep. The most common codes: total_mismatch, line_sum_mismatch, tax_amount_mismatch,date_format, due_before_invoice, iban_checksum.The textual validation_warnings stays — it is meant to be shown to a person.
risk_flags — what is worth checkingTai faktai, o ne verdiktai. You make the decision, because you know the direction:
own_company_in_vendor_slot — your client\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s company is in the seller\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s lauke. On a purchase invoice that means the parties are swapped; on a sales invoice this is normal.same_party_both_sides — the same company on both sides. There is no case where this is correct.duplicate_invoice_number — the same supplier has already sent an invoice with this number. The field duplicate_of_invoice_number gives the previous invoice\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s id, amount and date — the difference in amounts is exactly what tells you whether the supplier rewrote the document or simply resent it. File-level duplicate checking cannot see this: a rewritten document is different bytes.credit_note_signs_applied — the document was recognised as a credit note, so total_amount,subtotal and the line totals forced negative. The numbers in the response may not match the signs printed in the PDF.The list of codes keeps growing. An unfamiliar code should be ignore themrather than treated as an error — that way your integration will not break when we add a new one.
If you resend the same file (the same bytes, the same account), then allow_duplicate yra false (default) — returns the earlier extraction, free of charge(from_cache: true, duplicate_of points to the earlier ID; the AI is not run again). This way a Power Automate flow that reads the same folder every day is not billed again. To force a fresh extraction, pass allow_duplicate=true.
You can get the file in two ways. Both return the file base64 format inside the JSON (content_base64) — decode it and save it.
Add the parameter to the section 2 request include_export (rivile, centas arba finvalda) — atsakyme atsiras export field with that invoice\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s file:
{BASE}/api/v1/invoices/extract-direct?include_export=rivile{BASE}/api/v1/invoices/extract-direct?include_export=centasexport field has the same structure as the batch response (see below).
{BASE}/api/v1/invoices/export/{format}{format} = rivile, centas or finvalda. The request body is either specific ids or filters (as in the invoice list, up to 1000):
{ "invoice_ids": ["<id1>", "<id2>"] }
// arba
{ "start_date": "2026-05-01", "end_date": "2026-05-31" }Response — Rivilė (.zip containing .eip files):
{
"format": "rivile",
"filename": "Rivile_eksportas-20260612-061255.zip",
"content_type": "application/zip",
"content_base64": "UEsDBB...", // base64 → bytes → save as .xml
"problems": [], // warnings for the bookkeeper (see below)
"skipped_count": 0,
"purchase_count": 1,
"sale_count": 0
}Response — Centas (.xml, or .zip when there are both purchases and sales):)
{
"format": "centas",
"filename": "Centas_eksportas-20260612-061255.xml",
"content_type": "application/xml", // or application/zip
"content_base64": "PD94bWw...", // base64 → bytes → save as .xml
"problems": [],
"skipped_count": 0,
"purchase_count": 1,
"sale_count": 0
}| Format | File | Contents |
|---|---|---|
| rivile | .zip | Klientai / Prekes / Pirkimai / Pardavimai .eip (ISO-8859-13) |
| centas | .xml or .zip | Pirkimai.xml / Pardavimai.xml (UTF-8) |
| finvalda | .xml or .zip | Pirkimai.xml / Pardavimai.xml (UTF-8) |
problems — warnings meant for a person (skipped invoices, a 0%/reverse-charge class that needs confirming) — show them before importing.
Some values are not on the invoice — your company code (to tell purchases from sales), VAT class codes. Save them once and every export will use them:
{BASE}/api/v1/export-config?format={format}{BASE}/api/v1/export-config?format={format}{format} = rivile or centas. PUT body (send only what you want to set; the rest stay at their defaults). The fields differ per format:
Rivilė:
{ "config": {
"own_company_code": "304827491",
"own_vat_code": "LT100001738313",
"vat_class_map": { "21": "PVM1", "0": "PVM5" },
"partner_group": "PT001",
"product_group": "PR001",
"op_tip_purchase": 1,
"op_tip_sale": 51
} }Centas:
{ "config": {
"own_company_code": "304827491",
"own_vat_code": "LT100001738313",
"vat_class_map": { "21": "PVM1", "0": "PVM5" },
"account_purchase": "SANAUDOS",
"account_sale": "PAJAMOS"
} }Finvalda:
{ "config": {
"own_company_code": "304827491",
"own_vat_code": "LT100001738313",
"op_type_purchase": "1",
"op_type_sale": "51",
"journal_purchase": "PIRK",
"journal_sale": "PARD",
"import_param": "IMP1",
"default_client_code": "KL001",
"account_purchase": "6001",
"account_sale": "5001"
} }Finvalda PVM klasės lauko neturi — klasę parenka imp_param, tad vat_class_map šiam formatui netaikomas.
Use snake_case keys (an unknown key returns 422). Important: the 0% / reverse-charge VAT class ("0") defaults to PVM5 — confirm the correct code with your accountant (a wrong but valid code silently distorts VAT accounting). Set abu — own_company_code ir own_vat_code: purchase/sale is recognised when either one matches (the AI sometimes fails to read the company code, especially on foreign invoices).
| Code | Value |
|---|---|
| 401 / 403 | The key is missing or invalid. |
| 400 / 413 / 422 | Invalid file (not a PDF, > 10 MB, over the page cap) or invalid parameters. |
| 404 | No invoices were found for the export with the given ids/filter. |
| 422 (export) | All selected invoices were skipped (reasons are in the error text) — no file was created. Also: unknown format or an invalid config. |
| 429 | Rate limit exceeded (30/min) — wait and try again. |
Questions about the integration? Get in touch — kontaktai.