Skip to main content

Routing

"Routing" in GoRoute means one decision: does this document go over the Peppol network, or is it built and handed back to you to email? There are two channels and no others. GoRoute makes the choice for you by default, you can override it per document, and there is nothing to configure in advance.

This page is the short version, with a pointer to the page that owns each detail. If you are looking for routing rules, per-country routing, a pre-flight call or a third delivery network, read What GoRoute does not have at the bottom โ€” an earlier version of this page described features that do not exist, and that section says so plainly.

The two channelsโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ POST /api/v1/ โ”‚
โ”‚ invoices โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Is the buyer โ”‚
โ”‚ reachable on โ”‚
โ”‚ Peppol? โ”‚
โ”‚ (SMP lookup) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โ”‚
โ–ผ โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Peppol AS4 โ”‚ โ”‚ Issued for email โ”‚
โ”‚ status: โ”‚ โ”‚ status: issued โ”‚
โ”‚ queued โ†’ โ”‚ โ”‚ you send the PDF โ”‚
โ”‚ delivered โ”‚ โ”‚ GoRoute never sends โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The left branch is a transmission GoRoute performs and tracks to delivered or failed. The right branch is finished the moment it is created: the document is built, stored and auditable, the transaction status is issued, and nothing further happens to it. Code that waits for delivered or failed must treat issued as a third ending or it will wait forever.

How the channel is chosenโ€‹

Two fields on POST /api/v1/invoices control it, and both default to auto:

{
"invoice": { "...": "your canonical invoice" },
"document_format": "auto",
"delivery_channel": "auto"
}

delivery_channel takes auto, peppol or email. The response carries a delivery object saying which channel was used and why.

The rule that decides auto is written out, in the order it is applied, on Delivery and Formats. It is stated once, there, so that there is one place to correct if it changes. The headline is that a buyer registered for this document type on Peppol gets it over the network, and anyone else gets an emailable document โ€” except where the seller's country forbids email delivery, which is also listed on that page.

Checking the buyer before you sendโ€‹

If you want to know which way a document will go before you send it, look the buyer up:

curl "https://app.goroute.ai/peppol-api/api/v1/participants/lookup?peppol_id=0106:12345678" \
-H "X-API-Key: your_api_key"

The answer is 200 whether or not the participant is on the network: read found, and read capabilities to see whether they accept the document type you are about to send. A buyer who is registered but does not accept your document type is the case that surprises people โ€” the document goes by email, not over Peppol.

Full response fields, the scheme:value form the parameter requires, caching, the batch form and the "can this recipient receive an invoice" helper are on Participant Lookup.

When a send failsโ€‹

A Peppol send that does not succeed lands on one of two statuses, and the difference matters:

StatusWhat it meansWho acts
retryingA transport problem that may clear on its own. The send is retried up to three more times; after that the transaction becomes failed.Nobody โ€” wait
failedThe send did not succeed and will not be retried automatically. error_code, error_message and failed_at are set.You

You can ask for a failed or retrying transaction to be delivered again:

curl -X POST \
https://app.goroute.ai/peppol-api/api/v1/transactions/{transaction_id}/retry \
-H "X-API-Key: your_api_key"

The transaction goes back to queued with the same transaction and message identifier. A transaction that is delivered, queued or issued cannot be retried, and there is no force option. The full status list, the retry refusals, proof of delivery and the difference between a retry and a resend are on Tracking Delivery.

Follow status with webhooks rather than polling. The events that exist for this are transaction.queued, transaction.delivered, transaction.failed, transaction.retrying and transaction.received โ€” see Webhooks.

What GoRoute does not haveโ€‹

An earlier version of this page described a routing engine that was never built. If you planned an integration around any of the following, none of it exists and no call on this list has ever worked. The replacement, where there is one, is named beside it.

Described beforeReality
Configurable routing_rules โ€” priority, per-country and per-document-typeNo such configuration exists. The channel rule is fixed, and the only per-document control is the delivery_channel field
An organisation routing policy (default_fallback, require_delivery_receipt, max_retry_attempts, retry_timeout_hours)No such settings exist, at organisation level or anywhere else. Retries are not configurable
A pre-flight routing callUse the participant lookup
A route-trace call, and routing analyticsNot available. Transaction history and status are on Tracking Delivery
A POST /documents/send endpoint taking a routing objectDocuments are sent with POST /api/v1/invoices โ€” see Sending an Invoice
Delivery over the Italian SDI networkGoRoute does not deliver through SDI. For an Italian seller, GoRoute refuses email delivery, which is a different thing โ€” see where email delivery is refused
Delivery by physical post, and a print or print_mail channelGoRoute does not post anything. There are two channels: Peppol and email
A UBL routing-hint extension (goroute:RoutingHint, PreferredNetwork, FallbackEmail)GoRoute reads no such extension. Put it in a document and it is ignored
A circuit breaker that routes around a failing access pointThere is no circuit breaker. A failing access point produces retrying and then failed
The webhook events document.fallback and routing.circuit_openNeither event is dispatched. The real events are listed above
A five-attempt backoff schedule (immediate, 5 min, 15 min, 1 hour, 4 hours)The real behaviour is up to three more attempts after the first failure, then failed

Nothing above is labelled "planned", because nobody has said it is planned. If you need one of these, raise it with support so it is counted as a request rather than assumed to be coming.

Practical advice that does holdโ€‹

  1. Use webhooks for status, do not poll. Subscribe to the delivery events rather than asking repeatedly โ€” see Webhooks.
  2. Handle issued as an ending. It is the most common cause of a stuck integration here: the document is finished and GoRoute will never transmit it.
  3. Look the buyer up before a bulk send. It tells you which of your invoices will need an email, so you find out before you have five hundred of them.
  4. Keep the buyer's participant identifier on the invoice when you want Peppol delivery. With delivery_channel: peppol, or any named document_format, there is no lookup and a missing identifier is refused with BUYER_IDENTIFIER_REQUIRED.

Next Stepsโ€‹