SMP Registration
The Service Metadata Publisher (SMP) is the directory that tells the Peppol network where to find you. When you register in the SMP, other participants can discover your capabilities and send you documents.
What is SMP?โ
The SMP stores:
- Who you are โ Your Peppol identifier
- What you can receive โ Document types and processes
- How to reach you โ Your Access Point's endpoint
- Security info โ Certificates for message encryption
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SMP Record โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Participant: 0106:12345678 โ
โ โโโ Document: Invoice-2 โ
โ โ โโโ Process: BIS Billing 3.0 โ
โ โ โโโ Endpoint: https://ap.goroute.ai/as4 โ
โ โโโ Document: CreditNote-2 โ
โ โโโ Process: BIS Billing 3.0 โ
โ โโโ Endpoint: https://ap.goroute.ai/as4 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
How SMP Lookup Worksโ
When GoRoute sends an invoice to a receiver:
1. Sender provides: 0106:12345678 (receiver ID)
โ
โผ
2. GoRoute queries SML: Where is this participant's SMP?
โ
โผ
3. SML returns: smp-goroute.acc.edelivery.tech (SMP URL)
โ
โผ
4. GoRoute queries SMP: What are this participant's capabilities?
โ
โผ
5. SMP returns:
- Document types: Invoice, Credit Note
- Access Point: https://receiver-ap.example.com/as4
- Certificate: [X.509 certificate]
โ
โผ
6. GoRoute delivers invoice to receiver's Access Point
Registration Processโ
Step 1: Create Participantโ
First, create a participant record in GoRoute:
import requests
participant = {
"scheme": "0106",
"identifier": "12345678",
"name": "My Company BV",
"country": "NL",
"email": "invoices@mycompany.nl"
}
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/participants",
headers={
"X-API-Key": "your_api_key",
"Content-Type": "application/json"
},
json=participant
)
result = response.json()
print(f"Participant ID: {result['id']}")
Step 2: Register in SMPโ
POST /api/v1/participants/{participant_id}/register โ requires the
participants:manage permission.
{participant_id} is a UUID, not a Peppol identifierThe path parameter is the UUID of the GoRoute participant record returned by Step 1 โ
the id field. It is not the scheme:value Peppol identifier. Passing 0106:12345678
here fails.
You do not choose document types. GoRoute derives them from the participant's country:
- AU and NZ participants: PINT A-NZ Invoice and Credit Note (registered under both the
busdox-docid-qnsandpeppol-doctype-wildcardschemes) plus Peppol BIS 3.0. - All other countries: Peppol BIS 3.0 Invoice and Credit Note only.
There is no document_types array to send and no process_id to pick.
import requests
response = requests.post(
f"https://app.goroute.ai/peppol-api/api/v1/participants/{participant_id}/register",
headers={"X-API-Key": "your_api_key"},
)
result = response.json()
print(result["participant"], result["service_group"])
print(result["smp_registered"], result["sml_registered"], result["total_doc_types"])
The response reports what the SMP accepted:
| Field | Meaning |
|---|---|
participant | The scheme:value Peppol identifier |
service_group | created, already_exists, or error_<status> |
document_types | One entry per document type, each with doc_type_id, scheme and a status of ok or error_<status> |
smp_registered | True only when the ServiceGroup and every document type succeeded |
sml_registered | True when the ServiceGroup succeeded โ PHOSS creates the SML entry alongside it |
total_doc_types | Count of document types now recorded locally |
sml_registered and smp_registered move independentlyA participant whose ServiceGroup was created but whose document types were rejected exists
in the SML and resolves to nothing. A sender addressing it receives a 404 and an AS4
TRANSPORT_ERROR. If smp_registered is false, the registration is incomplete even though
the participant looks present.
Registration errorsโ
Registration returns HTTP 502 with one of these error codes:
error_code | When |
|---|---|
SMP_REGISTRATION_FAILED | The PHOSS SMP refused or failed the registration |
OMAN_SMP_REGISTRATION_FAILED | An Oman participant was refused by OTA's SMP wrapper |
PARTICIPANT_NOT_FOUND | HTTP 404 โ no participant with that UUID in your organisation |
The Oman error carries a hint: OTA's SMP verifies with the Fawtara Portal that an accepted
ServiceProvider-Taxpayer connection exists before it will register a participant. Accept the
taxpayer's connection request on the portal first, then retry within three business days.
Step 3: Verify Registrationโ
GET /api/v1/participants/{participant_id}/smp-status โ note the hyphen. smp-status
is a single path segment; it is not two segments separated by a slash.
response = requests.get(
f"https://app.goroute.ai/peppol-api/api/v1/participants/{participant_id}/smp-status",
headers={"X-API-Key": "your_api_key"},
)
status = response.json()
print(status["registered"], status["participant"])
For a participant on GoRoute's own PHOSS SMP the response carries registered,
participant, the service_group_xml when the participant is present, and the locally
recorded local_smp_registered, local_sml_registered and local_document_types.
An Oman participant does not live in GoRoute's PHOSS SMP, and OTA's wrapper is PUT/DELETE
only โ there is no read route to query. smp-status returns what GoRoute recorded at
registration time (registered, participant, rail: "oman-central-smp",
smp_registered, sml_registered, document_types) plus a note saying so. Verify
authoritatively via the Fawtara Portal (E-Services > SMP Management), SML DNS resolution,
or a public SMP GET.
A failed status check returns HTTP 502 with error_code: SMP_CHECK_FAILED.
SMP Record Structureโ
An SMP record contains:
Service Groupโ
<?xml version="1.0" encoding="UTF-8"?>
<ServiceGroup xmlns="http://busdox.org/serviceMetadata/publishing/1.0/">
<ParticipantIdentifier scheme="iso6523-actorid-upis">0106:12345678</ParticipantIdentifier>
<ServiceMetadataReferenceCollection>
<ServiceMetadataReference
href="https://smp.goroute.ai/0106:12345678/services/urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"/>
</ServiceMetadataReferenceCollection>
</ServiceGroup>
Service Metadataโ
<?xml version="1.0" encoding="UTF-8"?>
<ServiceMetadata xmlns="http://busdox.org/serviceMetadata/publishing/1.0/">
<ServiceInformation>
<ParticipantIdentifier scheme="iso6523-actorid-upis">0106:12345678</ParticipantIdentifier>
<DocumentIdentifier scheme="busdox-docid-qns">
urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1
</DocumentIdentifier>
<ProcessList>
<Process>
<ProcessIdentifier scheme="cenbii-procid-ubl">
urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
</ProcessIdentifier>
<ServiceEndpointList>
<Endpoint transportProfile="peppol-transport-as4-v2_0">
<EndpointURI>https://ap.goroute.ai/as4</EndpointURI>
<RequireBusinessLevelSignature>false</RequireBusinessLevelSignature>
<Certificate>MIIF...</Certificate>
<ServiceDescription>GoRoute Peppol Access Point</ServiceDescription>
<TechnicalContactUrl>https://goroute.ai/#contact</TechnicalContactUrl>
</Endpoint>
</ServiceEndpointList>
</Process>
</ProcessList>
</ServiceInformation>
</ServiceMetadata>
Document Capabilitiesโ
Billing Documentsโ
Most participants register for billing documents:
BILLING_CAPABILITIES = [
{
"document_type": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
"process_id": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"description": "Peppol BIS Billing 3.0 Invoice"
},
{
"document_type": "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2",
"process_id": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"description": "Peppol BIS Billing 3.0 Credit Note"
}
]
Full Capabilitiesโ
For organizations needing all document types:
FULL_CAPABILITIES = [
# Billing
{"document_type": "Invoice-2", "process_id": "billing:01:1.0"},
{"document_type": "CreditNote-2", "process_id": "billing:01:1.0"},
# Ordering
{"document_type": "Order-2", "process_id": "ordering:01:1.0"},
{"document_type": "OrderResponse-2", "process_id": "ordering:01:1.0"},
# Catalogue
{"document_type": "Catalogue-2", "process_id": "catalogue:01:1.0"},
# Despatch
{"document_type": "DespatchAdvice-2", "process_id": "despatch:01:1.0"}
]
SMP Managementโ
Changing document capabilitiesโ
An earlier revision of this page documented a PUT route for editing a participant's
document types. No such route exists. Document types are not editable through the API
at all: they are derived from the participant's country when you register, exactly as
described in Step 2.
If a participant's document types are wrong, the levers you actually have are:
- Correct the participant's
countryon the participant record, then - Call
POST /api/v1/participants/{participant_id}/registeragain โ re-registering PUTs the ServiceMetadata for the country-derived document types afresh.
Registering additional document types beyond BIS 3.0 and PINT A-NZ is not something the API supports today. Contact support if you need one.
Deregister from SMPโ
POST /api/v1/participants/{participant_id}/deregister โ a POST, not a DELETE, and
it requires the participants:manage permission.
response = requests.post(
f"https://app.goroute.ai/peppol-api/api/v1/participants/{participant_id}/deregister",
headers={"X-API-Key": "your_api_key"},
)
result = response.json()
print(result["participant"], result["status"])
status | Meaning |
|---|---|
deleted | The ServiceGroup was removed |
not_found | It was already gone โ the desired end state, so this counts as success |
error_<status> | The SMP refused; the participant is still published |
Deleting the ServiceGroup cascades to all of its ServiceMetadata. On success the local record is kept but marked unregistered, and its document types are cleared.
If the SMP refuses the delete, GoRoute deliberately leaves the local flags untouched and the
call fails with HTTP 502 and error_code: SMP_DEREGISTRATION_FAILED. Recording a
removal that did not happen would mean believing a participant was gone while they remained
reachable โ and Oman requires deregistration within one working day of a connection ending.
Re-check with smp-status rather than assuming.
Deregistering from SMP means other participants can no longer send you documents via Peppol. Only do this if you're migrating to another Access Point or leaving the network.
Test vs Productionโ
Test SMPโ
SML: acc.edelivery.tech
SMP: smp-test.goroute.ai
Production SMPโ
SML: edelivery.tech
SMP: smp.goroute.ai
Test and production are completely separate networks. A participant registered in test cannot receive documents from production, and vice versa.
Troubleshootingโ
Registration Failedโ
Error: "Participant already registered with another AP"
The identifier is already registered with a different Access Point. The previous provider must deregister before GoRoute can register.
# Contact GoRoute support for migration assistance
# admin@goroute.ai
Lookup Returns Nothingโ
Error: "Participant not found in SMP"
- Check if registration completed successfully
- Verify you're using the correct environment (test/prod)
- Wait 5-10 minutes for DNS propagation
Wrong Document Typesโ
Error: "Receiver does not support document type"
The receiver's SMP registration doesn't include the document type you're trying to send.
# Check the receiver's capabilities first. The lookup takes a single
# peppol_id in scheme:value form, not a separate scheme and identifier.
response = requests.get(
"https://app.goroute.ai/peppol-api/api/v1/participants/lookup",
params={"peppol_id": "0106:12345678"},
headers={"X-API-Key": "your_api_key"}
)
capabilities = response.json()["capabilities"]
Best Practicesโ
- Register Early โ Complete SMP registration before going live
- Test First โ Always register in test environment before production
- Check What Was Registered โ Document types are derived from the participant's country, so confirm the set with
smp-statusrather than assuming you chose them - Monitor Status โ Set up alerts for SMP registration changes
- Keep Records โ Maintain history of registration changes
API Referenceโ
All paths are relative to https://app.goroute.ai/peppol-api. {participant_id} is the
UUID of the GoRoute participant record in every case.
| Method | Path | Permission | Notes |
|---|---|---|---|
POST | /api/v1/participants/{participant_id}/register | participants:manage | No request body. Document types are derived from the participant's country. |
POST | /api/v1/participants/{participant_id}/deregister | participants:manage | POST, not DELETE |
GET | /api/v1/participants/{participant_id}/smp-status | Authenticated | A single hyphenated path segment |
There is no capabilities-editing route. See "Changing document capabilities" above.