Zenvoices logo
Zenvoices logo

Public API documentation


This document describes the public REST API of Zenvoices.

Refer to chapter Available APIs for an overview of supported featrues.

Getting started

Register for API access

If you don’t have access to a Zenvoices user/tenant yet, start your free trial here.

Grant API access to a user

The Zenvoices public API uses bearer tokens for authentication. A bearer token can be retrieved by passing user login credentials to POST /api/Account/Authenticate. API requests are executed with the permissions of the user used for authentication. Users don’t have API access by default, therefore we first need to grant API access to a user of your tenant.

Go to Manage / Organisation / Users in the Zenvoices portal. Create a new user which is only used for API access (recommended) or use an existing user. Edit the permissions of the user and grant the API permissions you’d like to use.

Note: users with only API access are not billed.

Get a bearer token

Call POST /api/Account/Authenticate with your user credentials to get a bearer token. Bearer tokens are valid for 2 hours and are used to authenticate API requests.

Example cURL command:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json'  -d '{ \ 
   "tenancyName": "your-tenant-name", \ 
   "usernameOrEmailAddress": "your-api-username", \ 
   "password": "your-password" \ 
 }' 'https://app.zenvoices.com/api/Account/Authenticate'

Example response:

{ "result": "xl18nS1QZuh05KFLqMsNisezQCVwnseT2Rj6U9spPFd2RPb_e-4FzVxoZ4-wst-ug5ji7ztvNBtw-wMhqQ71qEZeVqP7qoVlLI9z9EUMgGVrv56oZQS5jELRp1C20IIgnYJWCA30IE8L_45WzZohduV2MAwRerCOXuoCogFuIpw3xYk4wp4AQQ2N69tUUd8oIh6ehbFQqmJ3bkUKP36U8LJWUUXMikFLRIdyoBYpKEEapBrny1Ln25BEb7ibDtBKUjwAeeqV7ZuF6geGx0dEx1OHW_x1IPzPESDm-xxoq4DqYy3WdeWZEH2cxOkWwBUlBXLcenZQhis8Ht3I0vUfBotyPNZpirDqfXNAyDnnxTMONVUEHnmVhud6oWB79_1xTd5aa5ai1rTNpClV6Cz_abdYfcIgzho02RrD1moP72Nix6Cajgw2FjMXSdEOydNChnkgecbV4F3_w_2EuWHNEAwu8JpMFat_jZGWYsCCF04azZIyQrg3NjUANbhiSks4vJy628UP40GqFqxfKSViQaWeUdIRkqykEx1zCp7xPMmhDZuJtViw_yDslmrNjnlW", "targetUrl": null, "success": true, "error": null, "unAuthorizedRequest": false, "__abp": true }

In the response above the result property contains the bearer token. In subsequent requests you must include this bearer token in the Authorization header with value “Bearer <bearer-token>”

Make your first API call

For example call POST /public-api/v1/air/processDocument using the following cURL command:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer <your-bearer-token>' -d '{ \ 
   "url": "https://your-domain/document.pdf", \ 
   "fileName": "document.pdf", \ 
   "legislation": "nl",   \ 
 }' 'https://app.zenvoices.com/public-api/v1/air/processDocument'

Go to our Swagger UI to discover all available operations and parameters.


API calls are authenticated by providing an Authorization header using the Bearer scheme. A bearer token can be retrieved by passing user login credentials to POST /api/Account/Authenticate. API requests are executed with the permissions of the user used for authentication. We recommend using a separate user for API access.

Example Authorization header:

Authorization: Bearer <your-bearer-token>

Example cURL request to retrieve a bearer token:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json'  -d '{ \ 
   "tenancyName": "your-tenant-name", \ 
   "usernameOrEmailAddress": "your-api-username", \ 
   "password": "your-password" \ 
 }' 'https://app.zenvoices.com/api/Account/Authenticate'

Example of an authenticated cURL request with a bearer token:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer <your-bearer-token>' -d '{ \ 
   "url": "https://your-domain/document.pdf", \ 
   "fileName": "document.pdf", \ 
   "legislation": "nl",   \ 
 }' 'https://app.zenvoices.com/public-api/v1/air/processDocument'

Error handling

Error kindHTTP response codeDescription
Invalid input400 This error is returned when invalid input is provided. error.validationErrors of the response body contains a list of invalid fields with related errors.
Unauthorized403This error is returned when you’re not authorized to access the request resource.
Entity not found404This error is returned when a requested entity doesn’t exist.
General error500This error is returned when an error occured during request processing. Refer to error.message in the response body for details about the error.

Limits and quotas

Max. requests per second*10

* HTTP response code 429 is returned when the request limit is reached.

Data privacy and security

  • Zenvoices is governed by strict standards regarding the privacy and protection of customer data. We take strong measures to protect your data from unauthorized persons or improper access.
  • Zenvoices is ISO 27001:2017 and 9001:2015 certified and uses ISO 27001 certified infrastructure for hosting and data storage.
  • More information about data privacy can be found in our privacy statement and data processing agreement.
  • More information about security can be found here.

Client libraries

Currently no pre-built client libraries are available, but you can easily create your own client by leveraging our OpenAPI 2.0 specification, which is available on https://app.zenvoices.com/swagger/docs/public-v1. For example, you can use Swagger Codegen to generate client libraries for languages such as C#, Java, PHP, Python, Perl, etc.

Swagger UI

Swagger UI is available on https://app.zenvoices.com/swagger/.

If you’re logged in to the Zenvoices portal (https://app.zenvoices.com), try out requests are authenticated as the user you’re currently logged in as.

If you’d like to authenticate try out requests as another user, login as this user in the Zenvoices portal or ensure you’re logged out in the Zenvoices portal (!) and enter a bearer token in the Swagger UI header’s api_key field. Note the latter only works when you’re not already logged in to the Zenvoices portal.

Available APIs


This API is used to list administrations (companies) and get administration details. Only administrations that are granted for the authenticated user are accessible.

Automatic invoice recognition (AIR)

This API allows the use of Zenvoices automatic invoice recognition (AIR) machine learning technology to extract key-value pairs from invoice and receipt documents. It outputs structured data with details of the extracted values. You can train your own machine learning models to improve accuracy by providing feedback on recognition results.

Supported fields

Field nameData typeExtracts single or multiple values?Has confidence?Supports training?Description
InvoiceNumberStringSingleYesYesInvoice number.
InvoiceDateDateSingleYesYesDate the invoice was issued.
DueDateDateSingleYesYesDate invoice payment is due.
CurrencyStringSingleYesYesISO 4217 currency code.
TotalAmountInclTaxNumberSingleYesYesTotal amount including VAT (TotalAmountExclTax + sum of tax line amounts)
TotalAmountExclTaxNumberSingleYesYesTotal amount excluding VAT
TaxLineStringMultipleFalseYesTax amount, tax rate and base amount separated by a semicolon (;). Up to three tax line fields can be extracted. Only tax lines with rates of the given legislation are extracted.
InvoiceCocNumberStringSingleNoNoChamber of commerce number.
InvoiceCustomerIdentifierStringSingleNoNoCustomer identifier.
AccountEmailStringSingleNoNoE-mail address.
InvoiceIBANStringSingleNoNoIBAN (bank account number).
AccountPostalCodeStringMultipleNoNoPostal code.
InvoiceVatNumberStringSingleNoNoVAT number.
YourReferenceStringMultipleNoNoReference numbers of purchase orders, receipts, etc.
StructuredPaymentReferenceStringSingleNoNoStructured payment reference. Supported formats: ISO 11649 Creditor Reference, Belgian OGM (gestructureerde medeling).
TaxReverseChargedKeywordBooleanSingleNoNoBool indicating if tax is reverse charged.
InvoiceKeywordBooleanSingleNoNoBool indicating if the document is an invoice. If false, the document is a receipt.
CreditKeywordBooleanSingleNoNoBool indicating if the document is a credit note. If True and extracted amounts are positive, you should change their sign to make them negative.

Excluding values from extraction

Using the “excludedValues” parameter of POST /public-api/v1/air/processDocument you can specify which field values should be excluded from extraction. For instance, if you’d like to extract data from purchase invoices you can exclude known customer account identifiers (such as VAT number and IBAN) to allow AIR to extract supplier account identifiers.

Custom models


You can train custom machine learning models to improve recognition accuracy. Custom models can be created using the endpoint POST /public-api/v1/air/model/createOrUpdate.

In the request body of the POST /public-api/v1/air/processDocument endpoint you can specify which model must be used for recognition using the modelId parameter. Our AI engine combines our pretrained models with your custom model to ensure optimal recognition accuracy on all features, even if the training data amount is small.

With the endpoint POST /public-api/v1/air/validateOperationResult you can provide feedback on process document operation results. This feedback is used to generate training data for your model.

After validating operation results, use the endpoint POST /public-api/v1/air/model/train to train your model.

Providing feedback

By providing feedback on process document operation results you can improve recognition accuracy and increase confidence values.

Use the POST /public-api/v1/air/validateOperationResult endpoint to provide feedback on a operation. You can only provide feedback on operations that used a custom model.

Example request body:

  "operationId": "37bc8616-ce2f-40e6-ad72-896dcfa7787e",
  "correctValues": [
      "fieldName": "InvoiceNumber",
      "correctValue": "20150122"
      "fieldName": "InvoiceDate",
      "correctValue": "2019-01-02T00:00:00.0000000"
      "fieldName": "TotalAmountInclTax",
      "correctValue": "121.00"
      "fieldName": "TotalAmountExclTax",
      "correctValue": "100"
      "fieldName": "TaxLine1",
      "correctValue": "21.00;0.21;100.00"


  • We recommend providing as many validated (correct) values as possible.
  • Providing no correct value means the predicted value is incorrect.
  • Field names are case sensitive and may only occur once in the CorrectValues collection.
  • CorrectValue values are formatted as strings using the following formats:
    • Date: ISO 8601 format, e.g. “2019-01-02T00:00:00.0000000”
    • Number: “.” is used as decimal separator, no thousand separator
    • TaxLine’s: “{tax amount};{tax rate};{base amount}”, e.g. “21.00;0.21;100.00”
  • After providing feedback, a model must be retrained to let the model take advantage of the new training data.
Training a model

You can train a model using POST /public-api/v1/air/model/train. Training is performed asynchronously and the training time depends on the amount of training data. A minimum of ~25 validated operation results is required before training is possible.

Using POST /public-api/v1/air/model/list (and checking the fields lastTrainingTime and isTrainingScheduled) you can verify if training is finished and has succeeded.

Data type value formatting

Extracted values are encoded as strings using the formats described in the table below.

Data typeFormatExample value
DateISO 8601 format“2019-01-02T00:00:00.0000000”
Number“.” is used as decimal separator, not as thousands separator“12345.12”
Boolean“True” or “False”“True”

Limits and quotas

Supported document types.pdf, .docx, .doc, .xlsx, .xls, .eml, .jpg, .jpeg, .png, .bmp
Supported legislations*nl, gb, de, be, pl, fr, es, usa
Supported document culturesnl, en, es, fr, de, pl
Max. document file size10 MB (after base64 encoding) and 4 MB for images (before base64 encoding)
Max. document dimensions3200 x 3200 pixels
Max. document pagesNo limit, but at most 50 pages are processed
Operation result lifetime48 hours
Max. number of excluded feature values50
Max. number of ML models50**
Minimum time between model training operations2 * average training time from the last 10 training operations

* Legislations are used for tax amount extraction only.

** Support can increase this limit on request.

Data storage

  • Raw input documents are deleted when a process document operation finishes.
  • If no custom model is used, operation results are deleted ~48 hours after the operation was finished.
  • If a custom model is used, operation results and training data are stored until manual deletion of the model.


  • The AIR API is available in all Zenvoices subscriptions (including Lite).
  • One transaction is charged per five pages, with a maximum of ten transactions per document.
  • Purchasing transaction bundles allows you to save up to 73% on transaction costs.
  • See our terms of use and pricing page for transaction pricing and more information.

Financial transactions

This API allows you to list financial transactions and get financial transaction details.


This API allows you to upload documents to the inbox of an administration.

Support & SLA


  • 4-5-2021: changed AIR date formatting to ISO 8601
  • 29-4-2021: initial version