Validation API Reference

POST /v1/invoices/validate: XML preflight scope, request format, real response fields, and a synthetic example.

POST /v1/invoices/validate runs Postscale's built-in preflight checks on UBL and CII invoice XML, including XRechnung-specific required fields. The free validator uses the same validation code.

This is not a complete XSD/Schematron validation service, certification, or a guarantee of acceptance by a buyer or portal. For standards conformance, use the KoSIT validator with the appropriate XRechnung configuration and follow your recipient's requirements. PDF detection does not validate the embedded XML in ZUGFeRD/Factur-X; submit XML for this workflow.

Request

Use a server-side API key, Content-Type: application/xml (or text/xml), and the raw XML body. The maximum request size is 10 MiB. There is no supported profile query parameter: the implementation detects the format from the body. A sending domain is not needed to validate XML. Sending invoices is a separate operation with its own requirements.

curl --fail-with-body https://api.postscale.io/v1/invoices/validate \
  -H "Authorization: Bearer $POSTSCALE_API_KEY" \
  -H "Content-Type: application/xml" \
  --data-binary @invoice.xml

Keep the key on your server; never embed it in a public webpage. Test keys can exercise validation without sending mail. A successful validation does not send or store an invoice as a delivery operation.

Try a synthetic sample

Download the minimal preflight sample and save it as invoice.xml, then run the request above. It contains fictional data and exercises the fields this implementation checks. It is not a production invoice or an example of full EN 16931 conformance.

Expected response:

{
  "valid": true,
  "format": "xrechnung-ubl",
  "standard": "EN 16931",
  "errors": [],
  "warnings": []
}

Delete the sample's <cbc:BuyerReference> element and run the check again. The response remains HTTP 200, but valid becomes false and the errors include:

{
  "code": "BT-10",
  "message": "Buyer reference (cbc:BuyerReference) is required for XRechnung",
  "location": "/Invoice/cbc:BuyerReference",
  "severity": "error"
}

Handle the result

HTTP 200 means a result is available, not that the invoice passed. Read valid, display errors, and review warnings before continuing your workflow. Each finding contains code, message, severity, and an optional location. There is no profile_version or profile field in this response.

The format is one of xrechnung-ubl, xrechnung-cii, ubl, cii, zugferd, or unknown. The standard label is EN 16931; it describes the rule family, not a certificate. Unknown formats and malformed invoice XML return findings with valid: false rather than an HTTP transport error.

HTTP statusMeaning
200Result available; inspect valid, errors, and warnings
400Empty body or unsupported/missing Content-Type
401Missing or invalid authentication
413Body exceeds 10 MiB
429Request rate limit reached; check the response before trying again
500Request body could not be read

Validation does not share the live-send side effects of /v1/send. Do not reuse validation retry behavior for sending: sending endpoints do not currently support Idempotency-Key.

For the broader workflow, see the XRechnung API and sending invoices.