POST /v1/send
Managed delivery (preview). One call generates, validates, and delivers an e-invoice over the right national network, tracked with a conservative status contract and billed per delivered invoice. In development, not yet callable.
When managed delivery ships, POST /v1/send will take your invoice data, generate and validate the compliant document, and durably queue it for delivery over the network you name. It is the composite entry point: one call for build, check, and deliver.
Delivery is asynchronous. The call returns 202 Accepted once the document is safely queued; the document then moves through the network on its own, and you follow its progress by webhook or by polling the transmission.
Two ways to send
| Endpoint | Use when |
|---|---|
POST /v1/send |
You have invoice data. Beliq will generate the compliant XML, validate it, and deliver it in one call. |
POST /v1/transmissions |
You already have a validated XML document and only need delivery. |
Both accept the same delivery fields and return the same transmission resource.
Networks
Name the network the document travels on:
network |
Channel |
|---|---|
peppol |
The Peppol network, via a certified Access Point |
ksef |
Poland KSeF — Beliq’s Poland delivery lane targets the current FA(3) schema (mandatory since 2026-02-01). Timeline subject to the FA(3) implementation milestone. |
sdi |
Italy SDI (Sistema di Interscambio) |
ppf_pdp |
France, a certified Plateforme de Dématérialisation Partenaire (PDP) |
choruspro |
France Chorus Pro (public procurement) |
Headers
| Header | Required | Description |
|---|---|---|
Authorization |
required | Bearer <api-key> or use X-API-Key. A test key never reaches a real network. |
Content-Type |
required | application/json |
Idempotency-Key |
optional | A key you choose to make the send safe to retry. See Idempotency. |
Request body
The invoice payload is the same as POST /v1/generate, plus the delivery envelope: network, sender, and recipient.
| Field | Type | Required | Description |
|---|---|---|---|
standard |
string | required | Target format, for example peppol-bis, facturx, xrechnung. |
invoice |
object | required | The EN 16931 invoice data, as in generate. |
network |
string | required | One of the networks above. |
sender |
object | required | { scheme, id } identifying you on the network. |
recipient |
object | required | { scheme, id } identifying the buyer on the network. |
documentTypeId |
string | optional | The network document-type identifier, where the network needs one. |
deadlineAt |
string | optional | ISO 8601 instant by which delivery must succeed. Drives at-risk escalation. |
curl -X POST https://api.beliq.eu/v1/send \
-H "Authorization: Bearer blq_live_abc123..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5f3c-2026-04-13-invoice-123" \
-d '{
"standard": "peppol-bis",
"network": "peppol",
"sender": { "scheme": "0208", "id": "0123456789" },
"recipient": { "scheme": "0208", "id": "9876543210" },
"invoice": {
"number": "INV-2026-0123",
"issueDate": "2026-04-13",
"currencyCode": "EUR",
"seller": { "name": "Acme AG", "vatId": "BE0123456789" },
"buyer": { "name": "Client BV", "vatId": "BE9876543210" },
"lines": [ { "description": "Consulting", "quantity": 1, "unitCode": "DAY", "unitPrice": 800.00, "lineTotal": 800.00, "vatRate": 21, "vatCategoryCode": "S" } ],
"totalNetAmount": 800.00, "totalTaxAmount": 168.00, "totalGrossAmount": 968.00
}
}'{
"success": true,
"data": {
"id": "txn_9f3c2a1b8e",
"status": "queued",
"direction": "outbound",
"network": "peppol",
"deduplicated": false,
"verdict": { "valid": true, "format": "ubl", "profileDetected": "peppol", "errors": [], "warnings": [] }
}
}If the invoice fails validation, nothing is queued: the call returns 422 INVALID_INVOICE with the full verdict in details, exactly as generate does. You fix the data and send again.
POST /v1/transmissions
When you already hold a validated document, deliver it directly. The payload carries the document instead of invoice data:
| Field | Type | Required | Description |
|---|---|---|---|
network |
string | required | One of the networks. |
sender |
object | required | { scheme, id }. |
recipient |
object | required | { scheme, id }. |
format |
string | required | ubl or cii. |
xml |
string | required | The UTF-8 XML document. |
documentTypeId |
string | optional | Network document-type identifier. |
deadlineAt |
string | optional | Delivery deadline. |
The response is the same transmission resource as POST /v1/send.
Idempotency
Delivery must never fire twice for one invoice, so sends are safe to retry. Set an Idempotency-Key header with a value you derive from the invoice (its number is a good seed):
- Same key, same body returns the existing transmission with
deduplicated: trueand200 OK. No second delivery is queued. - Same key, different body returns
409 IDEMPOTENCY_KEY_REUSED. Beliq refuses to guess which one you meant rather than risk sending the wrong document.
Retrying a send after a timeout is therefore safe: either the first attempt registered and you get it back, or it did not and the retry queues it.
Delivery status
A transmission moves forward through a conservative set of statuses. The contract is deliberate: a provider returning HTTP 200 is not the same as the document reaching the network, which is not the same as it being delivered. Beliq only reports the stronger status once it has the proof.
| Status | Meaning | Terminal |
|---|---|---|
queued |
Validated and durably held. Beliq owns delivery from here. Not yet on any network. | |
submitting |
An attempt is in flight to a provider. No network confirmation yet. | |
submitted |
A provider acknowledged the submission. In the provider’s pipeline, not yet network-confirmed. | |
cleared |
The network confirmed technical acceptance (Peppol transport receipt, KSeF UPO, SDI ricevuta). Legal proof captured. | KSeF only |
delivered |
Confirmed delivery to the recipient (Peppol MLR, SDI delivery receipt, PDP approval). | yes |
rejected |
The network or recipient refused on validation or business grounds. Fix and send again as a new transmission. | yes |
failed |
Permanent transport failure after the deadline and grace window, or an unroutable recipient. Escalated, never silently retried forever. | yes |
cleared is terminal only for KSeF, where the UPO is the final proof. On Peppol, SDI, and French PDP the network emits a further delivery signal, so cleared is a step on the way to delivered.
At risk. When a deadlineAt is set and the deadline is threatened or breached, the transmission carries atRisk: true alongside its current status and fires a transmission.at_risk webhook. It is a flag, not a status: the transmission keeps progressing.
Never abandoned. A transport or provider outage does not drop a document. Beliq holds it in a durable outbox, retries with backoff, and escalates for human attention rather than giving up. It never blindly re-sends when the first attempt’s outcome is unknown; it reconciles the real status first, so a document is never delivered twice.
Billing
Delivery is billed per delivered invoice, and only on success: a transmission that reaches delivered (or a terminal cleared, for KSeF) is billed once. A rejected or failed transmission is never billed. Compute (the generate and validate folded into POST /v1/send) uses your plan quota as usual. See pricing.
Track a transmission
Poll a transmission, or list your recent ones. These reads are available to any authenticated caller in your organisation.
GET /v1/transmissions
List transmissions, most recent first, with optional filters.
| Query parameter | Description |
|---|---|
direction |
outbound or inbound |
status |
Any status value from the table above (or the inbound statuses) |
network |
One of the networks |
limit |
Page size, 1 to 100 |
cursor |
The nextCursor from the previous page |
{
"success": true,
"data": {
"items": [ { "id": "txn_9f3c2a1b8e", "direction": "outbound", "network": "peppol", "status": "delivered", "atRisk": false } ],
"nextCursor": null
}
}GET /v1/transmissions/:id
The full transmission resource: its status, the counterparty, the deadline and at-risk flag, and timestamps.
{
"success": true,
"data": {
"id": "txn_9f3c2a1b8e",
"direction": "outbound",
"network": "peppol",
"status": "delivered",
"counterparty": { "scheme": "0208", "id": "9876543210" },
"deadlineAt": "2026-04-20T00:00:00.000Z",
"atRisk": false,
"livemode": true,
"createdAt": "2026-04-13T09:00:00.000Z",
"updatedAt": "2026-04-13T09:04:12.000Z"
}
}The audit sub-resources
| Path | Returns |
|---|---|
GET /v1/transmissions/:id/attempts |
Every delivery attempt: the provider, the outcome, and the retry history. |
GET /v1/transmissions/:id/events |
A hash-chained audit trail of every status change, with a chainOk flag so you can confirm the log has not been tampered with. |
GET /v1/transmissions/:id/receipts |
The legal proofs captured from the network (Peppol AS4 receipt and MLR, KSeF UPO, SDI ricevuta, PDP lifecycle), each with its SHA-256 hash. |
GET /v1/transmissions/:id/document |
The stored document bytes. Returns 410 Gone once the payload is purged under the retention policy; the hash and proofs are kept. |
Webhooks
Rather than poll, subscribe to the transmission events and react as the status advances: transmission.queued, transmission.submitted, transmission.cleared, transmission.delivered, transmission.rejected, transmission.failed, and transmission.at_risk. See Webhooks.
Related
- Test mode: rehearse against provider sandboxes with a
blq_test_key. - POST /v1/receive: the inbound side, for documents that arrive over the network.
- Do I need a Peppol Access Point?: what to use until managed delivery ships.