Migrating Access Points
Moving a participant from another Access Point to GoRoute is a change of directory entry, not a transfer of data. A participant can be published in the Peppol directory by only one Access Point at a time, so the order never varies: your current provider removes the entry, then GoRoute publishes a new one pointing at GoRoute's endpoint.
Earlier revisions of this page described a set of endpoints for requesting a transfer, moving participants in bulk, watching progress, forcing a re-check and retrying a failure. None of them has ever existed, and code written against that page failed on its first request.
Every call below is in the running API today, named with its method and full path.
What actually happensβ
Your current Access Point GoRoute
β β
β 1. You create the β
β participant record βββββΆβ (no directory change yet)
β β
2. You ask them to βββΆ directory β
deregister entry removed β
β β
β 3. You confirm the entry β
β is gone (lookup) β
β β
β 4. You register βββββββββββΆβ directory entry
β β recreated for GoRoute
β β
β 5. You verify (smp-status) β
The one step GoRoute cannot do for you is step 2. Your current provider controls the directory entry until they remove it.
Step 1 β Create the participant record in GoRouteβ
POST /api/v1/participants β returns 201 Created and requires the participants:manage
permission.
This creates a record inside GoRoute. It changes nothing on the Peppol network. What you need
from it is the participant's id, a UUID that every later call in this sequence uses.
import requests
BASE_URL = "https://app.goroute.ai/peppol-api"
response = requests.post(
f"{BASE_URL}/api/v1/participants",
headers={"X-API-Key": "your_api_key", "Content-Type": "application/json"},
json={
"scheme": "0106",
"identifier": "12345678",
"display_name": "My Company BV",
"country": "NL",
"contact_email": "invoices@mycompany.nl",
},
)
response.raise_for_status()
participant_id = response.json()["id"] # UUID β not the Peppol identifier
A rejected create returns HTTP 400 with an error_code of either DUPLICATE_PARTICIPANT
(you already hold this participant) or PARTICIPANT_IDENTITY_INVALID (the identifier does not
satisfy the rules for its country, for example a Belgian enterprise number failing its check
digit). The two mean different things: retry with a corrected identifier only for the second.
See Registration for the rest of the fields the create call accepts.
Step 2 β Ask your current provider to deregisterβ
Providers handle this differently, and most treat it as a support request rather than a self-service action. Ask them in writing and keep the reply.
Subject: Peppol participant deregistration request
Dear Support,
We are moving our Peppol registration to a new Access Point.
Participant:
- Peppol ID: [scheme]:[identifier]
- Company name: [your company name]
Please deregister this participant from your SMP and confirm when it is done.
Our new Access Point is GoRoute (Peppol seat POP000991), which will publish the
participant once your deregistration is confirmed.
Thank you,
[your name]
Step 3 β Confirm the entry has goneβ
GET /api/v1/participants/lookup β requires the participants:read permission. It takes a
single peppol_id in scheme:value form and queries the live Peppol directory, so it is the
honest check on whether your old provider has actually removed the entry.
response = requests.get(
f"{BASE_URL}/api/v1/participants/lookup",
params={"peppol_id": "0106:12345678"},
headers={"X-API-Key": "your_api_key"},
)
result = response.json()
print(result["found"]) # False once the old entry is gone
found: false is not proof on its ownThe endpoint also answers found: false when the directory query itself fails, so a single
negative answer can mean "removed" or "could not tell". Check twice, a few minutes apart,
before moving on. A confirmation email from the old provider is better evidence than either
answer.
Step 4 β Register the participant to GoRouteβ
POST /api/v1/participants/{participant_id}/register β requires the participants:manage
permission. {participant_id} is the UUID from step 1, not the Peppol identifier.
Do not run this until step 3 shows the old entry is gone.
response = requests.post(
f"{BASE_URL}/api/v1/participants/{participant_id}/register",
headers={"X-API-Key": "your_api_key"},
)
result = response.json()
print(result["smp_registered"], result["sml_registered"], result["total_doc_types"])
The request takes no body. You do not choose document types β GoRoute derives them from
the participant's country. A refusal from the SMP comes back as HTTP 502 with an
error_code. SMP Registration documents the response
fields and every error code, including the extra step Oman participants need on the Fawtara
Portal.
Step 5 β Verifyβ
GET /api/v1/participants/{participant_id}/smp-status β note the hyphen; smp-status is one
path segment.
status = requests.get(
f"{BASE_URL}/api/v1/participants/{participant_id}/smp-status",
headers={"X-API-Key": "your_api_key"},
).json()
print(status["registered"], status["participant"])
There is no webhook that announces a completed move, and no progress endpoint to poll for one.
Poll smp-status instead, and treat registered as the signal.
Moving several participantsβ
There is no bulk endpoint. Each participant is an independent sequence of the five steps above, so loop over them and handle each failure on its own β one participant whose old provider has not yet deregistered should not stop the rest.
Moving away from GoRouteβ
POST /api/v1/participants/{participant_id}/deregister β a POST, not a DELETE, and it
requires the participants:manage permission. Its status is deleted, not_found (already
gone, which counts as success) or error_<status>. A refusal leaves the participant published
and returns HTTP 502. See
SMP Registration.
While the move is happeningβ
Between your old provider's deregistration and GoRoute's registration, the participant is not in the directory. Documents addressed to it in that window will not be delivered; senders get an error and have to send again.
- Tell your regular trading partners before you start.
- Note anything you are expecting to receive, and ask senders to retry afterwards.
- Keep the window short by doing steps 4 and 5 as soon as step 3 confirms the entry is gone.
After the moveβ
- Confirm
smp-statusreports the participant as registered. - Send a test invoice and receive one.
- Check the document types on the participant record are the set you expected.
- Point your webhooks at the right endpoint if they were configured elsewhere.
- Tell trading partners who address you directly that your Access Point has changed.