Skip to main content

Invoice Responses

GoRoute does not currently offer an API for sending an Invoice Response. If you have received an invoice and want to tell the supplier that you have accepted it, rejected it, or have a question about it, there is no GoRoute endpoint that will send that message over the Peppol network for you today. This page explains what the Peppol Invoice Response is, what GoRoute does do, and what to do instead.

This page previously described a feature that does not exist

Earlier revisions of this page published a call for sending an Invoice Response, along with a request format and a set of status codes to send. None of it was ever built, and any integration written against it will fail. If you built against that page, nothing you can change in your request will make it work โ€” see What to do instead.

What a Peppol Invoice Response isโ€‹

Peppol defines an Invoice Response message (a UBL ApplicationResponse) that lets a buyer tell a supplier what has happened to an invoice โ€” that it has been received, accepted for payment, rejected, queried, or paid. It travels over the same network as the invoice, in the opposite direction, and it is a distinct Peppol business document with its own profile.

It is optional in most of the Peppol network. Where a country's rules require it, that requirement falls on the buyer, and it is not currently something GoRoute can carry out on your behalf.

What GoRoute does todayโ€‹

Message Level Status, in the Oman flow onlyโ€‹

The platform generates and exchanges a Message Level Status (MLS) automatically as part of the Oman tax-reporting flow. An MLS is also a UBL ApplicationResponse, but it is a different thing from an Invoice Response: it reports what happened to the message โ€” whether it was accepted or rejected in transit โ€” rather than a buyer's commercial decision about the invoice.

Three things follow from that, and they are worth being blunt about:

  • It is automatic. You do not trigger it, and there is no request body for you to fill in.
  • It is Oman only. It is produced by the Oman tax-reporting pipeline, which is enabled for Oman document exchanges. An invoice sent to a Belgian, Australian or Dutch buyer has no MLS.
  • The codes are AP (accepted) and RE (rejected). These are values you read off a transaction. There is no call that lets you choose one and send it.

Reading an MLSโ€‹

Where an MLS exists, you can retrieve it in its original, unaltered form. Which call you use depends on who wrote the MLS, and there are two:

The MLS you wantThe call
The one GoRoute sent on your behalf, acknowledging a document that arrived for youGET /api/v1/transactions/{transaction_id}/mls?leg=sent
The buyer's accept or reject of an invoice you sentGET /api/v1/oman/transactions/{transaction_id}/mls?leg=received
The Oman Tax Authority's answer on your invoice's Tax Data DocumentGET /api/v1/oman/transactions/{transaction_id}/mls?leg=authority

Both return the UBL ApplicationResponse XML and both need an API key with the transactions:read permission.

A 404 here does not mean nobody answered

GET /api/v1/transactions/{transaction_id}/mls?leg=received cannot return the buyer's answer. It searches your own organisation, and the answer is addressed to GoRoute's service-provider identity rather than to yours, so it is filed under GoRoute's organisation. The call answers 404 DOCUMENT_NOT_STORED whether the buyer has answered or not.

Earlier versions of this page said a 404 was the normal "no MLS yet" case. That is true for leg=sent, and for any transaction outside the Oman flow, which has no MLS at all. It is not true for the buyer's answer: use the Oman call for received and authority.

The full account of both calls โ€” the required leg, the three refusal codes, and how to tell whether a service has the Oman call at all โ€” is on one page, so that these two cannot drift apart: Fetching an MLS document in the Oman guide.

Ask GET /api/v1/transactions/{transaction_id}/reporting first to see which legs exist. Read the legs from mls.legs[], but do not follow the document_url it gives a received leg โ€” it names the call that cannot serve it.

import requests

API_BASE = "https://app.goroute.ai/peppol-api"


def get_sent_mls(transaction_id: str) -> str | None:
"""The MLS GoRoute sent on your behalf, as UBL XML, if there is one."""
response = requests.get(
f"{API_BASE}/api/v1/transactions/{transaction_id}/mls",
params={"leg": "sent"},
headers={"X-API-Key": "your_api_key"},
)

if response.status_code == 404:
return None # No MLS was sent for this transaction

response.raise_for_status()
return response.text


def get_received_mls(transaction_id: str, leg: str = "received") -> str | None:
"""The buyer's MLS (leg="received") or the Tax Authority's (leg="authority")
on an Omani invoice you sent. Needs a service with the Oman pack switched on."""
response = requests.get(
f"{API_BASE}/api/v1/oman/transactions/{transaction_id}/mls",
params={"leg": leg},
headers={"X-API-Key": "your_api_key"},
)

if response.status_code == 404:
return None # Not answered yet, or the Oman pack is not on this service

response.raise_for_status()
return response.text

Status events for invoices you sentโ€‹

If a status comes back about an invoice you sent, and it arrives through the Oman MLS flow, GoRoute raises a webhook event for it. The event name reflects the status: response.accepted when the message was accepted, response.rejected when it was rejected, and response.received when the status is anything else, with mls.received beside it. They go to the organisation that owns the invoice, even though the buyer's access point addresses its status message to GoRoute's Service Provider identity rather than to you; see Response Events for the payload. Subscribe to these the same way as any other event โ€” see Webhook Setup. They are things you are told about; they are not things you can send.

What to do insteadโ€‹

If you need to accept, reject or query an invoice you have received, handle it outside the Peppol network for now:

  1. Record the decision in your own system. Your accounts payable workflow is the source of truth for whether an invoice is approved, queried or paid. See Processing Documents for the pipeline.
  2. Contact the supplier directly โ€” email or your existing supplier portal โ€” when you need to reject an invoice or ask about it. Give the invoice number and the specific reason, so the supplier can issue a credit note or a corrected invoice.
  3. Ask the supplier for a credit note where an invoice is wrong. A credit note is a real Peppol document, it travels the network normally, and GoRoute both sends and receives it. That is the supported way to correct an invoice that has already been exchanged.

If you need thisโ€‹

Invoice Response support is not published on a roadmap, and this page does not promise it. If sending Invoice Responses over Peppol is a requirement for you โ€” particularly if it is a regulatory requirement in a market you operate in โ€” tell us, through Support, and say which market and which profile you need. That is the useful signal, and it is more use to us than a guess.

Next Stepsโ€‹