Skip to main content

IngestionLoad

Push invoices INTO Nuntiq from a connector. Two flows:

  1. Drop a file into the standard pipeline — same path as email intake. Nuntiq runs OCR, picks a template, extracts fields.
  2. Build a structured invoice with fields + lines + addresses, then attach the original PDF, then submit. Skips OCR entirely.

For the worked-example tutorial, see Patterns → Invoice ingestion.

Import

from lib.objects.ingestion import IngestionLoad

ingest_pdf / ingest_files — Pattern 1

load = IngestionLoad(context)

result = load.ingest_pdf(
filename='invoice.pdf',
content=pdf_bytes,
receiving_inbox='invoices@acme.apreceiving.com', # all kwargs optional
supplier_code='SUP-100',
company_code='EMEA',
)

print(result.source_document_id) # int
print(result.files_uploaded) # int (>=1; ZIPs expand)

For multiple files in one call:

result = load.ingest_files(
files=[
('invoice.pdf', pdf_bytes, None),
('attachment.docx', docx_bytes, None),
],
receiving_inbox='invoices@acme.apreceiving.com',
)
ArgRequiredNotes
filename / files[*][0]yesUsed by Nuntiq for display + MIME inference
content / files[*][1]yesRaw bytes
content_typenoInferred from filename when omitted
receiving_inboxnoControls which template Nuntiq picks
supplier_codenoRouting hint; skips supplier AI match
company_codenoRouting hint; skips company AI match

Max 20 files per request. Max 50MB per file. ZIP files are unzipped server-side.

SourceDocumentResult

FieldTypeNotes
source_document_idintThe new source document's id
files_uploadedintNumber of files accepted (>=1; ZIPs expand)
pdf_files_queuedintNumber of PDFs queued for processing
upload_session_idstr (UUID)Groups this upload — useful for log searches

new_invoice() — Pattern 2 (structured + PDF)

load = IngestionLoad(context)

inv = load.new_invoice(
workflow='payment_portal', # default
receiving_inbox='invoices@acme.apreceiving.com',
)

# Header — set whatever you have. All fields optional, all template-driven.
inv.header.invoice_number = 'INV-2026-0042'
inv.header.invoice_date = '2026-05-17' # ISO date
inv.header.due_date = '2026-06-16'
inv.header.gross_amount = 1815.00
inv.header.tax_amount = 315.00
inv.header.net_amount = 1500.00
inv.header.currency_code = 'EUR'
inv.header.supplier_name = 'Acme Corp'
inv.header.order_number_1 = 'PO-2026-0042'
inv.header.custom_text_1 = 'cost-center-42'

# Lines
line = inv.new_line()
line.product_code_1 = 'WIDGET-A'
line.product_name = 'Office Widget'
line.quantity = 100
line.unit_price = 12.50
line.unit_of_measure = 'EA'
line.net_amount = 1250.00
line.tax_amount = 262.50
line.gross_amount = 1512.50

# Addresses — type must be REMITTO | SUPPLIER | SHIPTO | BILLTO
addr = inv.new_address('SUPPLIER')
addr.street = 'Herengracht 500'
addr.city = 'Amsterdam'
addr.country = 'NL'

# Optional: taxes / charges / discounts
tax = inv.new_tax()
tax.tax_name = 'VAT'
tax.tax_rate = 21
tax.tax_amount = 315.00

# Attachments
inv.attach_image(filename='invoice.pdf', content=pdf_bytes) # exactly one
inv.attach_file(filename='delivery_note.pdf', content=dn_bytes) # 0..N

# Send
result = inv.submit()
print(result.invoice_token, result.invoice_status)

Workflow choice

workflowResulting statusUse when
payment_portal (default)100 (Processed)Upstream data is fully verified — skip enrichment
basic_enrichment10Run light enrichment, no AI
full_enrichment1Run the full AI-match + validation pipeline

Attachment rules

  • attach_image() — at most one per invoice. Calling it twice raises ValueError. This is the PDF the AP team will view; multiple "primary" PDFs would confuse the viewer.
  • attach_file() — 0..N supporting documents (delivery notes, supporting POs, etc.). Visible to the AP team but not the primary view.
  • If you don't pass any IMAGE, the invoice has no viewable PDF — AP team sees structured fields only. Usually a poor UX.

InvoiceImportResult

FieldTypeNotes
invoice_tokenstr (UUID)Pass to InvoiceLoad.get_by_token()
invoice_idintInternal numeric id
source_document_idintUnderlying source document
workflowstrWorkflow used
invoice_statusintFinal numeric status (e.g. 100 = Processed)
source_document_statusintFinal source-document status
template_idintTemplate Nuntiq used
template_typestr'global' or 'customer'
attachments_linkedintCount of attachments tied to the invoice
receiving_inboxstrInbox used for template lookup

Error handling

ingest_pdf / ingest_files and submit() raise ApiError on transport or HTTP failure. See ApiClient → Error handling.

Local validation (workflow value, address_type value, max-1-image) raises ValueError before the HTTP call — so you find out at code-write time, not after a network round trip.

Idempotency

Neither endpoint has an idempotency-key concept today. If you call ingest_pdf or inv.submit() twice with the same data, Nuntiq creates two records. Track which upstream records you've already submitted in your own state (typically via delta_run) and don't re-submit.

What's next