Send invoices (end-to-end)
Ce contenu n’est pas encore disponible dans votre langue.
This guide shows a clean API flow to send invoices: create or reuse a contact, create or import an invoice, send it, and retrieve the final files.
Prerequisites
Section titled “Prerequisites”- API Key:
X-B2B-API-Key - API Version:
X-B2B-API-Version ACCOUNT_ID: the account that issues the invoice.
Important IDs:
ACCOUNT_ID: owner account (path param in/accounts/{ACCOUNT_ID}/...).CONTACT_ID: recipient contact (stored inside the account).INVOICE_ID: invoice identifier (used in/invoices/{INVOICE_ID}...endpoints).
1 Get or create the recipient contact
Section titled “1 Get or create the recipient contact”1.1 Lookup contacts (optional)
Section titled “1.1 Lookup contacts (optional)”curl --request GET \ --url 'https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/contacts?offset=0&limit=25&name=Example%20Customer' \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json'1.2 Lookup in the directory (optional)
Section titled “1.2 Lookup in the directory (optional)”If you know the recipient’s identifier and country, you can retrieve public information from the directory and use it to build the contact.
curl --request GET \ --url https://api-staging.b2brouter.net/directory/es/ESB63276174 \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json'1.3 Create a contact (if you don’t have one)
Section titled “1.3 Create a contact (if you don’t have one)”curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/contacts \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{ "contact": { "name": "Example Customer", "country": "es", "is_client": true, "email": "billing@example.com", "tin_scheme": "9920", "tin_value": "ESB00000000", "transport_type_code": "b2brouter", "document_type_code": "json" } }'Note: CONTACT_ID is returned in the response. Do not confuse it with ACCOUNT_ID.
2 Create (JSON) or import (XML) the invoice
Section titled “2 Create (JSON) or import (XML) the invoice”2.1 Create invoice using JSON
Section titled “2.1 Create invoice using JSON”curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{ "send_after_import": false, "invoice": { "type": "IssuedInvoice", "contact_id": {CONTACT_ID}, "number": "INV-0001", "date": "2026-01-21", "terms": "custom", "due_date": "2026-02-21", "currency": "EUR", "invoice_lines_attributes": [ { "quantity": 1, "price": 10, "description": "Example service", "taxes_attributes": [ { "name": "VAT", "category": "S", "percent": 21 } ] } ] } }'2.2 Import invoice from a file (when you already generate XML)
Section titled “2.2 Import invoice from a file (when you already generate XML)”curl --request POST \ --url 'https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices/import?send_after_import=false' \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'content-type: application/octet-stream' \ --data 'data:text/xml;name=invoice.xml;base64,PD94bWw+Li4u'2.3 What the import does with the contact data on the invoice (update_contact)
Section titled “2.3 What the import does with the contact data on the invoice (update_contact)”When you import a file, or create an invoice with a contact block instead of contact_id, B2Brouter looks up the buyer among the contacts of the account by its identifiers and uses the contact it finds. By default, an import never modifies an existing contact:
- If some data on the file (address, routing codes, sending method) does not match the contact, the invoice is assigned to an organizational unit of that contact carrying the file’s data. The contact does not change.
- If only the name differs, nothing happens: no organizational unit is created, no field is written, and the invoice goes out with the name stored on the contact.
The update_contact parameter is optional, off by default, and exists on every API version. Send update_contact=true (as a query parameter on the import call, or as a top-level field of the JSON body on the create call, like send_after_import) so that the import updates the contact instead of creating an organizational unit. If an organizational unit with that data already exists, it is used.
- The descriptive data on the file (the name included, the address and the other non-identifier fields) replaces the contact’s.
- Identifiers (tax identifier, company identifier, Peppol identifier and routing codes) are only filled when they were blank on the contact. An identifier that already has a value is never overwritten, even if the file carries a different one.
- A blank value on the file never clears a stored value.
- On received invoices the parameter is ignored: a received document never updates the supplier’s contact.
- The bulk import endpoint
/invoices/importsdoes not accept this parameter.
Decide which side owns the contact data. With update_contact=true on every call, the invoice you send is the reference: any change in the file propagates to the contact record and to later invoices. Without the parameter, the contact record in B2Brouter is the reference, and you correct it through the contacts API or from the web application.
3 Send the invoice
Section titled “3 Send the invoice”curl --request POST \ --url https://api-staging.b2brouter.net/invoices/send_invoice/{INVOICE_ID} \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}'4 Retrieve the invoice and download final files
Section titled “4 Retrieve the invoice and download final files”4.1 Get the invoice payload
Section titled “4.1 Get the invoice payload”curl --request GET \ --url 'https://api-staging.b2brouter.net/invoices/{INVOICE_ID}?include=lines' \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json'4.2 Download legal/original invoice files
Section titled “4.2 Download legal/original invoice files”See the Download invoices guide.