Usage

Basic usage — process PDF files and write the result to CSV:

invoice2data invoice.pdf
invoice2data invoice.txt
invoice2data *.pdf

The full list of options is in the command-line reference at the bottom of this page (or run invoice2data --help).

Input readers

invoice2data picks a backend automatically (a cascade — see How It Works), or you can force one with --input-reader:

invoice2data --input-reader pdfium invoice.pdf       # default, no system deps
invoice2data --input-reader pdftotext invoice.pdf    # layout-preserving (poppler)
invoice2data --input-reader text invoice.txt
invoice2data --input-reader pdfminer invoice.pdf
invoice2data --input-reader pdfplumber invoice.pdf
invoice2data --input-reader tesseract invoice.pdf    # OCR
invoice2data --input-reader ocrmypdf invoice.pdf     # OCR
invoice2data --input-reader doctr invoice.pdf        # local deep-learning OCR
invoice2data --input-reader paddleocr invoice.pdf    # local deep-learning OCR
invoice2data --input-reader gvision invoice.pdf      # Google Cloud Vision

See Installation for the extras each backend needs.

  • gvision needs the GOOGLE_APPLICATION_CREDENTIALS env var and a Google Cloud bucket name (the GOOGLE_CLOUD_BUCKET_NAME env var, or the to_text argument).

  • ocrmypdf can clean noisy scans: any OCRmyPDF option (deskew, clean, rotate_pages, optimize, …) is forwarded to ocrmypdf.ocr. As a library, invoice2data.input.ocrmypdf.pre_process_pdf(path, pre_conf=...) returns the path to the cleaned, OCR-layered (usually smaller) PDF.

Output

invoice2data --output-format csv invoice.pdf
invoice2data --output-format json invoice.pdf
invoice2data --output-format xml invoice.pdf

Write to a custom name or folder (you must set --output-format to create an --output-name):

invoice2data --output-format csv --output-name myinvoices/invoices.csv invoice.pdf

Stream to a standard stream instead of a file with --output-name - (or /dev/stdout, /dev/stderr) — logs go to stderr, so stdout stays clean for piping:

invoice2data --output-format json --output-name - invoice.pdf | jq .

Templates

invoice2data --template-folder ACME-templates invoice.pdf                          # add your own
invoice2data --exclude-built-in-templates --template-folder ACME-templates *.pdf   # only yours

See Tutorial for Template Creation for writing templates.

Renaming / sorting files

Process a folder of invoices and copy renamed invoices to a new folder:

invoice2data --copy new_folder folder_with_invoices/*.pdf

Debugging templates

invoice2data --debug my_invoice.pdf                 # dump the full debug output
invoice2data --debug-optimized-str my_invoice.pdf   # just the matched text
invoice2data --no-color my_invoice.pdf              # disable colored logs (or NO_COLOR=1)

For automation pipelines, emit machine-readable JSON logs (one object per line, on stderr) and combine with --output-name -:

invoice2data --in-automation --output-format json --output-name - my_invoice.pdf

Generating templates & AI

Draft a new template from a sample document. The builder suggests fields/regexes from detected dates, amounts and IBAN/VAT/BIC, and from common labels — it recognises label: value pairs with multilingual synonyms (e.g. BTW/VAT, KvK/CoC/Chamber of Commerce, Invoice No/Factuurnummer), which lets it identify label-only fields like the Chamber-of-Commerce number (just digits) and anchor each regex on its label. It previews what each field captures, then writes a .yml after you confirm:

invoice2data --new-template sample.pdf
invoice2data --new-template sample.pdf --ai            # draft with a configured LLM instead
invoice2data --new-template sample.pdf --interactive   # review/edit each field via prompts

With --interactive, the builder walks you through each drafted field — showing what it captures (after cleanup) and letting you keep, edit the regex, or skip it — then offers to add fields it didn’t detect. Captured values are cleaned up automatically where useful: a VAT id keeps its dots in the capture but strips them on output (NL12.34.56.789.B01NL123456789B01), and a Chamber-of-Commerce number drops an appended place name (12345678 Amsterdam12345678).

As a last resort, let an LLM extract fields when no template matches:

invoice2data --ai-fallback invoice.pdf

Both AI paths are opt-in and configured via INVOICE2DATA_AI_* — see AI features.

Use as a Python library

from invoice2data import extract_data

result = extract_data("path/to/my/file.pdf")

With your own templates:

from invoice2data import extract_data
from invoice2data.extract.loader import read_templates

templates = read_templates("/path/to/your/templates/")
result = extract_data(filename, templates=templates)

Loading templates from a string (e.g. a database column or an API response) instead of from disk, with ordered_load:

import yaml
from invoice2data import extract_data
from invoice2data.extract.loader import ordered_load

templates = ordered_load(db_json_string)                          # JSON (default)
templates = ordered_load(db_yaml_string, loader=yaml.safe_load)   # or YAML
result = extract_data(filename, templates=templates)

By default extract_data returns {} when nothing matches. Pass raise_on_error=True to get a typed InvoiceProcessingError (RequiredFieldsMissingError / NoTemplateFoundError) instead — see the Reference for the full library API.

Authoring camelot templates with Excalibur (or a notebook)

Excalibur is Camelot’s visual web UI for picking table regions on a PDF. Once you have saved a rule there, export its rule_options JSON and turn it into a ready-to-paste template stanza:

from invoice2data.extract.excalibur import excalibur_to_camelot_yaml

with open("excalibur_rule.json") as fh:
    rule_options = fh.read()

print(excalibur_to_camelot_yaml(rule_options, field="lines"))

The output is a camelot: block (one entry per page) that drops straight into your template — pairs with the invoice2data[camelot] plugin.

Note

Excalibur is slow-cadence (v1.0.1 in January 2025, nothing since). A Jupyter notebook is a faster-iterating alternative for picking table_areas / columns: load the PDF with camelot.read_pdf(...), plot detected tables with camelot.plot(table, kind='contour') until the regions look right, then hand-build the rule and convert it the same way:

​ rule = {“flavor”: “stream”, “pages”: {“1”: {“table_areas”: […], “columns”: […]}}} ​ print(excalibur_to_camelot_yaml(rule))

excalibur_to_camelot_yaml accepts any dict in the same shape, so you do not need Excalibur installed to use it.

Command-line reference

invoice2data

Extract data from PDF files and output it in a structured format.

Usage

invoice2data [OPTIONS] [INPUT_FILES]...

Options

-i, --input-reader <input_reader>

Choose text extraction function. Default: auto-detect between text & pdftotext

Options:

pdftotext | pdfium | pdfoxide | tesseract | pdfminer | pdfplumber | hotpdf | gvision | doctr | paddleocr | text | ocrmypdf

-f, --output-format <output_format>

Choose output format. Default: none

Options:

csv | json | xml | none

-d, --output-date-format <output_date_format>

Choose output date format. Default: %%Y-%%m-%%d (ISO 8601 Date)

-o, --output-name <output_name>

Custom name for output file. Extension is added based on chosen format.

--csv-lines <csv_lines>

How the CSV output renders line arrays: ‘json’ (default) JSON-encodes them; ‘explode’ writes one row per line item.

Options:

json | explode

--debug

Enable debug information.

--debug-optimized-str

Print the optimized_str each template is matched against (for template debugging), without the full –debug noise.

--no-color

Disable colored log output (also honored via the NO_COLOR env var).

--in-automation

Emit logs as machine-readable JSON (one object per line) for automation.

-c, --copy <copy>

Copy and rename processed PDFs to specified folder.

-m, --move <move>

Move and rename processed PDFs to specified folder.

--filename-format <filename_format>

Filename format to use when moving or copying processed PDFs.Default: “{date} {invoice_number} {desc}.pdf”

-t, --template-folder <template_folder>

Folder containing invoice templates in yml file. Always adds built-in templates.

--exclude-built-in-templates

Ignore built-in templates.

--new-template <new_template>

Draft a new template from a sample document, then exit.

--ai

Draft the new template with the configured AI provider (see INVOICE2DATA_AI_* env vars). Default: deterministic heuristics.

--template-out <template_out>

Path to write the drafted template (default: <issuer>.yml).

--interactive

With –new-template, review/edit each drafted field via prompts.

--ai-fallback

If no template matches, extract fields with the configured AI provider (opt-in; see INVOICE2DATA_AI_* env vars).

--version

Show the version and exit.

Arguments

INPUT_FILES

Optional argument(s)