Skip to content

API Usage

There are two valid integration patterns. In practice, Option 1 is usually simpler: you validate and fix conversion issues before creating a document, and you only store UBL in the document repository.


General conditions

Item Value
Base URL https://xtool.invoice-portal.de/api
API v2 authentication Header x-api-key: <api_key>
XML requests Content-Type: application/xml
JSON requests Content-Type: application/json

Placeholders used below

Placeholder Meaning
idoc.xml Source SAP IDoc XML (logical format sap.invoice.idoc)
converted.xml Result of conversion to Peppol BIS Billing 3.0 UBL XML
DOCUMENT_ID Document id returned by POST /v2/documents/upload/xml

Format identifiers

  • IDoc input (for documentation / detection): sap.invoice.idoc
  • Target UBL (path segment target_format): peppol_bis_billing.invoice.3_0.xml_ubl

Check API access

Verify that the key is valid:

curl -X GET "https://xtool.invoice-portal.de/api/v2/auth/me" \
  -H "x-api-key: <api_key>"

Flow: IDoc → Peppol BIS UBL (standalone conversion), then upload the UBL, send with send.peppol, poll document status.

Step 1 — Convert IDoc to Peppol BIS Billing UBL

Endpoint: POST /v2/format/convert/xml/{target_format}

For Peppol BIS Billing Invoice 3.0 UBL, set target_format to peppol_bis_billing.invoice.3_0.xml_ubl. Send the raw IDoc XML as the request body. Optional query validate=true runs validation on the output.

1
2
3
4
5
curl -X POST "https://xtool.invoice-portal.de/api/v2/format/convert/xml/peppol_bis_billing.invoice.3_0.xml_ubl?validate=true" \
  -H "x-api-key: <api_key>" \
  -H "Content-Type: application/xml" \
  --data-binary "@idoc.xml" \
  -o converted.xml

Success: HTTP 200, response body is XML (application/xml) in the target format.

Step 2 — Upload the converted UBL as a document

Endpoint: POST /v2/documents/upload/xml?direction=outbound

1
2
3
4
curl -X POST "https://xtool.invoice-portal.de/api/v2/documents/upload/xml?direction=outbound" \
  -H "x-api-key: <api_key>" \
  -H "Content-Type: application/xml" \
  --data-binary "@converted.xml"

From the JSON response, save the document id as DOCUMENT_ID.

Step 3 — Send the document via Peppol

Endpoint: POST /v2/documents/{document_id}/send

Use transaction type send.peppol:

1
2
3
4
curl -X POST "https://xtool.invoice-portal.de/api/v2/documents/<DOCUMENT_ID>/send" \
  -H "x-api-key: <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"transaction_type": "send.peppol"}'

The response includes a transaction object (id, type, status, etc.).

Step 4 — Poll document status

Endpoint: GET /v2/documents/{document_id}?include=status_log

curl -X GET "https://xtool.invoice-portal.de/api/v2/documents/<DOCUMENT_ID>?include=status_log" \
  -H "x-api-key: <api_key>"

Repeat until the document reaches a final status (success or failure). Use status_log for troubleshooting.


Option 2: upload IDoc → convert → update document → send → poll

Use this when you want a document record first (e.g. audit trail with the original IDoc payload), then replace its XML with the converted UBL before sending.

Step 1 — Upload IDoc XML as a document

Endpoint: POST /v2/documents/upload/xml?direction=outbound

1
2
3
4
curl -X POST "https://xtool.invoice-portal.de/api/v2/documents/upload/xml?direction=outbound" \
  -H "x-api-key: <api_key>" \
  -H "Content-Type: application/xml" \
  --data-binary "@idoc.xml"

Save the returned id as DOCUMENT_ID.

Step 2 — Convert IDoc to Peppol BIS Billing UBL

Same conversion call as in Option 1, step 1:

1
2
3
4
5
curl -X POST "https://xtool.invoice-portal.de/api/v2/format/convert/xml/peppol_bis_billing.invoice.3_0.xml_ubl?validate=true" \
  -H "x-api-key: <api_key>" \
  -H "Content-Type: application/xml" \
  --data-binary "@idoc.xml" \
  -o converted.xml

Step 3 — Update the document with the converted XML

Endpoint: PUT /v2/documents/{document_id}/update/xml

1
2
3
4
curl -X PUT "https://xtool.invoice-portal.de/api/v2/documents/<DOCUMENT_ID>/update/xml" \
  -H "x-api-key: <api_key>" \
  -H "Content-Type: application/xml" \
  --data-binary "@converted.xml"

If the XML fails validation, the API may respond with 400 and a validation_error (or equivalent error payload).

Step 4 — Send via Peppol

Same as Option 1, step 3.

Step 5 — Poll status

Same as Option 1, step 4.


Choosing between Option 1 and Option 2

Approach When it fits
Option 1 You want the shortest path and to fail fast on bad IDoc→UBL conversion before a document exists. The stored document is already Peppol-ready UBL.
Option 2 You must retain the original IDoc as the first uploaded artifact, or your process creates the document before conversion is available.

For both options, monitor status_log on the document until sending and any Peppol delivery feedback are complete.