Tabula API

Uploading documents

Invoices and bank statements into Tabula

Send one document to POST /v1/uploads, or a ZIP archive of documents to POST /v1/uploads/batches. Tabula reads documents after the request returns: the response is 202 Accepted with an upload to poll until it is completed or failed.

curl https://api.tabula.de/v1/uploads \
  -H "Authorization: Bearer tab_live_…" \
  -F file=@Rechnung-2026-0042.pdf \
  -F documentType=supplier_invoice \
  -F externalId=ERP-2026-0042
{
  "id": "0b7f6f0e-4b8e-5c1d-9f0a-6a2e3d4c5b61",
  "batchId": null,
  "externalId": "ERP-2026-0042",
  "fileName": "Rechnung-2026-0042.pdf",
  "documentType": "supplier_invoice",
  "status": "queued",
  "result": null,
  "error": null,
  "createdAt": "2026-10-12T09:15:02.118Z"
}

Document types

documentTypeFilesWhat Tabula does
auto (default)PDF, XMLTells supplier invoices, customer invoices and other documents apart. Bank statements are not detected: send them as bank_statement.
supplier_invoicePDF, XMLProcesses the file as an invoice the company received from a supplier (Ausgabe). A file that is no invoice ends up in other documents.
customer_invoicePDF, XMLProcesses the file as an invoice the company issued to a customer (Einnahme). A file that is no invoice ends up in other documents.
bank_statementPDFReads the transactions of the bank statement. They are confirmed in Tabula.
other_documentPDF, XMLFiles the document in other documents, without booking it.

XML files are e-invoices such as XRechnung. A PDF with an embedded e-invoice, such as ZUGFeRD or Factur-X, is read from its structured data. DATEV ledger and document archive XML files are refused.

A file may be up to 50 MB. A ZIP archive may hold up to 100 files and unpack to 200 MB; every file in it becomes an upload with the batch's documentType.

Repeated requests

externalId is your ID for the file. A request with an externalId that was already used returns the original upload, so a timed-out request can be sent again safely; the file name may differ. The same externalId with a different file or document type is refused with 409 external_id_conflict.

Without an externalId, the same file with the same document type returns the original upload.

Status

Poll GET /v1/uploads/{uploadId}. While the upload is queued or processing, the Retry-After header suggests when to poll again.

statusMeaning
queuedWaiting to be read.
processingBeing read.
completedThe result is in Tabula; result links to it.
failedTabula could not process the file; error says why.
deletedThe result was deleted in Tabula.

A completed upload's result says what Tabula made of the file:

result.typeMeaning
invoiceA supplier or customer invoice.
other_documentA document that is no invoice.
bank_statementA bank statement import. Its transactions are confirmed in Tabula.
payment_fileA SEPA payment file.

result.url opens the result in Tabula.

Batches

Poll GET /v1/uploads/batches/{batchId}. The batch lists every upload in it and counts them by status. Files of an unsupported type are listed as failed uploads.

statusMeaning
processingAt least one upload is queued or processing.
completedEvery upload completed.
completed_with_errorsSome uploads failed.
failedEvery upload failed.

Failures

error.codeMessageWhat to do
unsupported_file_typeThe file type is not supported for this document type.Send a PDF or XML invoice or other document, or a PDF bank statement.
file_too_largeThe file exceeds the 50 MB limit.Split the document.
invalid_e_invoiceThe e-invoice failed validation.Ask the sender for a valid e-invoice.
password_protectedThe PDF is password-protected.Remove the password and upload again.
not_a_bank_statementThe file is not a bank statement.Upload it with another document type.
no_transactions_foundThe bank statement contains no transactions.Check the file.
unreadable_documentThe scan is not legible.Upload a better scan.
processing_failedTabula could not process the file. It can be retried in Tabula.Retry the upload in Tabula.

Sending the same request again retries an upload that failed before Tabula started reading it, and uploads a file again whose result was deleted in Tabula. An upload that Tabula could not process is retried in Tabula.

On this page