Attach a proof of performance to the invoice
Your customer wants the timesheet with the invoice — in the same file, not in a second email.
Steps
- 1
Take the carrier PDF: the ZUGFeRD or Factur-X file a generate or convert call returned. Only a PDF/A-3 carrier keeps its conformance.
- 2
Base64-encode the proof and put it into attachments[] as contentBase64, together with filename, mimeType, description and relationship: Supplement (the default on this route anyway).
- 3
The key needs the pdf:invoice:attach entitlement. It is granted per API key; without it the service answers 403 and "Missing entitlement: pdf:invoice:attach" — measured on 2026-09-15. If your key does not have it, ask us for it; the plans are on the pricing page.
- 4
The response carries the finished PDF in data (base64), plus pdfA3Conformant and attachmentCount. Decode it, store it, send it.
The call
POST /api/v1/invoice/attachments
1curl -X POST https://service.invoice-api.xhub.io/api/v1/invoice/attachments \2 -H "Authorization: Bearer $INVOICE_API_KEY" \3 -H "Content-Type: application/json" \4 -d '{5 "pdf": "JVBERi0xLjcKJYGBgYEKCjUgMCBvYmoKPDwKL0xlbmd0aCAxODk0Ci9G…",6 "attachments": [7 {8 "filename": "leistungsnachweis.pdf",9 "mimeType": "application/pdf",10 "contentBase64": "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMg…",11 "description": "Leistungsnachweis März 2026",12 "relationship": "Supplement"13 }14 ]15}'Long base64 values are cut short here (…). Put your own files in their place — the carrier PDF and the attachment.
Where this goes wrong
Two places. The carrier must be PDF/A-3 — otherwise the answer says pdfA3Conformant: false: the attachments are in the file, but the file is no longer a conformant archival document. And attaching does not turn an arbitrary PDF into a ZUGFeRD invoice: no fx XMP metadata is written, and the attachment is not marked as the invoice XML. If you need an e-invoice, generate or convert one.