Preflight (dry run)
A dry run of validation via POST /v1/agent/peppol/preflight. It validates your UBL/CII XML against EN 16931 + Peppol BIS Billing 3.0 (and the SK FS overlay), and optionally looks up the recipient in the SMP, with no DB writes and no credit charge. Use it right before POST /v1/agent/peppol/send/{invoiceId}, to catch errors before you send the document to the network.
partnerId in the body), preflight is part of the Agent API: it authenticates with the X-API-Key andX-Organization-Id headers, scope invoice:read. It can additionally do an SMP lookup of the recipient and return normalized BIS 3.0 UBL.Endpoint
| Method | Path | Scope | Headers |
|---|---|---|---|
| POST | /v1/agent/peppol/preflight | invoice:read | X-API-Key, X-Organization-Id |
This endpoint doesn't write to the DB or charge credit, so it's safe to call repeatedly in a "fix → preflight → send" loop.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
receiverPeppolId | string | No | Peppol identifier of the recipient (e.g. 0245:DIČ). When provided, an SMP lookup also runs and fills in the recipient field. |
document | object | Yes | Source document: see below. |
document.format | ubl | cii | Yes | Format of the source XML. |
document.xmlBase64 | string (base64) | Yes | Base64-encoded UBL / CII XML. |
POST /v1/agent/peppol/preflight
X-API-Key: efk_pk_test_...
X-Organization-Id: 0a2c1f3e-…
Content-Type: application/json
{
"receiverPeppolId": "0245:2123456789",
"document": {
"format": "ubl",
"xmlBase64": "PD94bWwgdmVyc2lvbj0iMS4wIj8+..."
}
}Response
The response is 200 whenever the check could run. The actual result is in the send_readyfield. When the validation runtime wasn't available, send_ready: null and validator_unavailable: true (instead of a 5xx error).
{
"data": {
"send_ready": true,
"validator_unavailable": false,
"validation": {
"ran": true,
"valid": true,
"error_count": 0,
"warning_count": 1
},
"repair": [
{
"field": "cac:TaxTotal",
"code": "BR-CO-15",
"message": "Invoice total with VAT must equal total without VAT plus the VAT amount.",
"severity": "error"
}
],
"recipient": {
"peppol_id": "0245:2123456789",
"found": true,
"sml_state": "active"
},
"normalized_ubl_base64": "PD94bWwgdmVyc2lvbj0iMS4wIj8+..."
}
}| Field | Type | Description |
|---|---|---|
send_ready | boolean | null | true = the document is ready to send (valid, no errors). null when the validator wasn't available. |
validator_unavailable | boolean | true if the validation runtime wasn't available, so send_ready is then null. |
validation | object | Run summary: ran, valid, error_count, warning_count. |
repair | array of objects | Findings / suggested fixes: field, code, message, severity (error | warning). |
recipient | object | null | Result of the recipient SMP lookup, if receiverPeppolId was provided; otherwise null. See Recipient lookup. |
normalized_ubl_base64 | string | null | Base64 of the normalized BIS 3.0 UBL (converted from CII, defaults filled in). |
Errors
When the document is missing or can't be parsed, the endpoint returns 400 with VALIDATION_ERROR. Validation findings about the document itself are not a 4xxerror: they're always part of the 200 response, in the send_ready / repair fields.
| Code | Meaning |
|---|---|
400 | The document is missing or can't be parsed. |
401 | Invalid or missing API key. |
403 | Missing invoice:read scope or invalid organization. |
Recommended flow
Call preflight before every send; if send_ready: false, fix the items in the repair field (severity error blocks, warning doesn't) and try again. Only call POST /v1/agent/peppol/send/{invoiceId} once send_ready: true. You can also verify the recipient separately: see Recipient lookup.