Business Gateway
For platforms

Receiving

Take delivery of documents addressed to the companies under your account.

Inbound documents arrive from the network, are validated, and are then held for you. Nothing expires because you were slow to collect it, and nothing is handed over twice unless you ask for it again.

You find out that something arrived in one of three ways: a webhook, the event stream, or polling. Webhooks are what most integrations use.

Webhooks

Create one endpoint for the whole account, or one per company. An endpoint without companyId receives events for every company under your account; with it, only that company's.

curl -sS -X POST https://api.businessgateway.se/v1/webhooks \
  -H "X-API-Key: $KEY" -H 'Content-Type: application/json' \
  -d '{
    "endpoint": "https://hooks.example.com/peppol",
    "secret": "…",
    "timeoutMs": 10000
  }'

The endpoint must be https:// and publicly resolvable. Timeout is between 1 and 30 seconds.

A payload looks like this, and always names the account and company it belongs to:

{
  "id": "evt_…",
  "type": "message.inbound.received",
  "accountId": "…",
  "companyId": "…",
  "documentId": "…",
  "status": "CUSTOMER_DELIVERY_QUEUED",
  "unvalidated": false
}
typeWhen
message.inbound.receivedA document is ready for you
message.inbound.validation_failedAn inbound document failed validation
message.outbound.as4_acceptedThe recipient's access point took your document
message.outbound.failedTerminal send failure
message.mlsA Message Level Status came back from the recipient

Verifying the signature

Every request carries X-Peppol-Signature: sha256= followed by the hex HMAC-SHA256 of timestamp + "." + body, keyed with your secret. The timestamp is in X-Peppol-Timestamp.

Compute it over the raw body as received, not over JSON you parsed and re-serialised — re-serialising changes bytes and the signature will not match. Reject timestamps far from now, so an old request cannot be replayed at you.

Also present: X-Peppol-Event-ID and X-Peppol-Event-Type.

Delivery and failure

Deliveries go PENDINGRETRYDELIVERED, DEAD_LETTER or CANCELLED. Your endpoint returning a non-2xx, or timing out, causes a retry; enough failures and the delivery is set aside as a dead letter, which we have to release for you. Ask, if an outage has left a backlog of them.

Treat the webhook as a nudge, not as the document. It tells you a documentId exists and is ready — fetch the document itself over the API. That way a webhook you missed costs you nothing: the document is still there.

Taking the document

# what is waiting
curl -sS -H "X-API-Key: $KEY" \
  "https://api.businessgateway.se/v1/messages?direction=INBOUND&status=CUSTOMER_DELIVERY_QUEUED"

# the XML itself
curl -sS -H "X-API-Key: $KEY" \
  "https://api.businessgateway.se/v1/messages/$ID/payload"

# tell us you have it
curl -sS -X POST -H "X-API-Key: $KEY" \
  "https://api.businessgateway.se/v1/messages/$ID/ack"

Acknowledging is what closes the loop. It marks the document delivered to you and cancels any webhook attempt still queued for it. Until you ack, the document keeps showing as waiting — which is exactly what you want if your own system crashed halfway through processing it.

Ack is safe to repeat; acking something already delivered changes nothing.

StatusMeaning
AS4_RECEIVEDTaken off the network, not yet checked
BUSINESS_VALIDATINGBeing validated
BUSINESS_INVALIDFailed validation
UNVALIDATEDAccepted without validation, because the document type has no rules to check
CUSTOMER_DELIVERY_QUEUEDReady for you
CUSTOMER_DELIVERY_RETRY / CUSTOMER_DELIVERY_FAILEDWe are trying, or have given up, delivering it onward
CUSTOMER_DELIVEREDYou acknowledged it

The event stream

GET /v1/stream is a WebSocket carrying the same events as they happen, plus participant status changes. It is useful for a live dashboard; it is not a substitute for webhooks, because a socket that was not connected missed what happened while it was gone. Get a ticket from POST /v1/stream-tickets first.

If a document cannot be delivered

A document addressed to a participant that is not registered here, or not capable of the document type, is refused at the edge — the sending access point learns it failed, and your customer never sees it. That is the network working as designed, but it does mean a missing RECEIVE capability looks, from the outside, like the business not existing. Check capabilities first when a customer says an expected invoice never arrived.

On this page