API integration: environments, required fields and field mappings
Test and production environment, required fields for POST /invoices, data structure for incoming and outgoing invoices, field mappings and systems already integrated.
This article answers the most common questions about connecting your own systems to the faktoora API. Error messages and HTTP status codes are described separately in the article API error handling, the complete list of BT fields in the article Which BT fields does the faktoora API support? and the required fields for XRechnung in the article What information does an XRechnung need at a minimum?.
Test and production environment
The faktoora API is available under two separate base URLs:
- Production environment:
https://api.faktoora.com/api/v1 - Demo/test environment:
https://api.demo.faktoora.com/api/v1
Both environments are independent instances with their own accounts and data. The API key is generated in the account settings of the respective environment and sent in the X-API-KEY header (see Why are my API calls rejected with 401?). To move from testing to production, switch the base URL to https://api.faktoora.com/api/v1 and use the key generated in your production account.
Creating an invoice: POST /invoices
For the Invoice object itself, only the following fields are generally required according to the schema:
format: output format, e.g.simple,zf:1,zf:2,xrechnung,peppolissueDate: invoice date (BT-2)invoiceNumber: invoice number (BT-1)invoiceTypeCode: invoice type, e.g.380for a commercial invoice (BT-3)invoiceItems: at least one invoice line itembuyer: the buyer
Within buyer and seller, the name and complete address (street, postcode, city, country) are required as soon as you send the respective block. Each line item in invoiceItems needs an id and a product object with name, quantity, unitCode, price and taxes. The complete, format-dependent list of required fields for format: xrechnung is in the article What information does an XRechnung need at a minimum?.
Retrieving an invoice: the process
Invoice creation via POST /invoices is asynchronous: the response is 202 Accepted with a faktooraId, and the invoice itself is generated in the background. A direct GET /invoices/{faktooraId} immediately afterwards can fail with 404 because processing is still running.
The correct process:
- Send
POST /invoicesand store thefaktooraIdfrom the202response. - Check the processing status via
GET /invoices/{faktooraId}/statusor wait for the registered webhook (see Webhook). - Only then call
GET /invoices/{faktooraId}. The endpoint returns the finished file directly asapplication/pdforapplication/xml(not a JSON metadata object).
Details on the possible status codes are in the article API error handling.
Field mappings
Order reference
At invoice level there are two different reference fields:
orderNumberon theInvoiceobject: reference to the associated order (BT-14).invoiceItems[].product.orderNumber: order reference at the level of the individual line item; according to the API description, not permitted forformat: xrechnung.
In addition, there is buyerReference.IssuerAssignedID as the buyer's order reference (BT-13). Do not confuse it with buyerReference.buyerReferenceId, which is the buyer reference or, for public-sector clients, the Leitweg-ID (BT-10).
When you retrieve invoice data via the import endpoints (see below), the corresponding field is called references.orderReferenceId (BT-13), or references.orderNumber for the buyer's order number. The field names therefore differ between creation (POST /invoices) and retrieval of imported invoices.
Order number: header or line item level?
Both are possible and independent of each other: orderNumber on the Invoice object references the order at header level (BT-14), invoiceItems[].product.orderNumber references an order at the level of the individual line item. For xrechnung, only the header level is permitted.
Buyer contact person
The contact person at the buyer is maintained via buyer.definedTradeContact:
firstName/lastName: name of the contact person (BT-56)departmentName: department (BT-56-0)phone: phone number (BT-57-00)email: email address (BT-58-00)
This is separate from buyer.phone/buyer.email (BT-57/BT-58), which represent the general contact of the buyer's company.
DirectDebitMandateID
directDebitMandateID (SEPA direct debit mandate, BG-19/BT-89) belongs to the specifiedTradePaymentTerms object, not to specifiedTradeSettlementPaymentMeans. If the field is accidentally passed in the payment means block instead of the payment terms block, it is not included in the XML because it is not a defined schema field there. If DirectDebitMandateID is missing from the generated XML, first check whether the field is in the specifiedTradePaymentTerms array.
Payment means codes for PayPal and credit card
The field specifiedTradeSettlementPaymentMeans[].typeCode (BT-81) uses the UNTDID 4461 code list. Available codes include 10 (cash), 20 (cheque), 30 (credit transfer), 42 (payment to bank account), 48 (card payment), 49 (direct debit), 57 (standing order), 58 (SEPA credit transfer), 59 (SEPA direct debit), 97 (report) and the string code ZZZ (mutually defined). There is no separate code for PayPal.
- Credit card:
typeCode: 48. For this code,cardNumber(required) and optionallyholderNameare also permitted; both fields are only allowed withtypeCode: 48. - PayPal: Since UNTDID 4461 has no PayPal-specific code, use
typeCode: "ZZZ"(mutually defined) and describe the payment method in the free text fieldinformation, e.g. "Payment via PayPal".
Interface data structure for incoming and outgoing invoices
For imported invoices, both incoming (/import/incoming) and outgoing (/import/outgoing), the API returns the same basic structure, divided into sub-resources that can be retrieved individually:
content/summary: overview (status, amounts, format)content/seller/content/buyer: seller and buyer datacontent/lineitems: invoice line itemscontent/taxes: tax data per tax category (taxable,rate,amount,category)content/paymentterms: payment terms, includingdirectDebitMandateIDanddueDateTimecontent/paymentmeans: payment means (typeCode,information,paymentReference)content/delivery: delivery datacontent: all of the above sub-resources combined in one responseattachments/attachment/{attachmentId}/file: attachments of the importstatus: processing status of the importvalidation/validation/pdf: validation result
The import itself runs asynchronously: a POST /import/incoming returns 202 Accepted with an importId before parsing and validation are complete. Call GET /import/incoming/{importId}/status until overallStatus is no longer pending before evaluating the content endpoints.
For outgoing imported invoices (/import/outgoing), content also contains a references block with the document-level reference numbers: orderNumber (the buyer's order number), orderReferenceId (BT-13), buyerReferenceId (BT-10), shippingOrderNumber, supplierNumber, contractNumber, assignmentNumber and mandateReference (SEPA mandate reference).
Recurring invoices
Recurring invoices are set up in the faktoora user interface; the step-by-step guide is in the article Recurring invoices. The API provides the read endpoint GET /recurring-invoices for this: it returns the schedules that have been created (name, frequency, start/end date, status, nextExecutionDate, linked invoice template). An endpoint for creating or changing a schedule via the API is not documented in the API reference.
File exchange: SFTP, FTP and WebDAV
To exchange invoice files via a directory, you can set up a file connection in the workflows. The available protocols are FTP, SFTP and WebDAV. This is set up in the user interface, not via the API; the API reference contains no endpoints for it.
There are also two other ways to connect an upstream system:
- Programmatically via the API: create invoice data in a structured way with
POST /invoices, or upload e-invoice files that have already been generated withPOST /import/incoming(or the corresponding endpoint for outgoing invoices). - By email: see Receiving invoices via your own mail server.
DATEV integration: handling differences in amounts
In the DATEV export, faktoora automatically balances rounding differences between the sum of the individual invoice line items and the consolidated invoice amount: if the sum of the line item amounts differs from the consolidated amount, the difference is added to the amount of the first line item in the DATEV ledger export, so that the sum of the exported line items exactly matches the invoice total.
Systems already integrated
Integrations with the following systems are documented in the code and in existing knowledge base articles: DATEV, Xero, weclapp, HubSpot, Monday, PipeDrive and Bexio. There is also a Stripe integration that synchronizes Stripe invoices and customers as invoices in faktoora; automatic generation in XRechnung format is not documented for it. You still determine the output format of an invoice yourself via the format field or the account settings.
Was this helpful?