Register a company on Peppol
Step-by-step use case to check the prerequisites, register a company on the Peppol network through the API, follow its activation and configure document reception.
NovaFisko registers a company on the Peppol network through the B2Brouter access point. This guide checks the prerequisites, starts the registration, follows the activation and configures the types of documents received. It is the flow of the Peppol tab of the application.
Prerequisites: a token with the read and write abilities and the public_token of the company.
Peppol registration is a real external effect: the company becomes reachable on the network. It is blocked in the demo firm (403, code demo_mode). Test it on a real company.
Step 1: read the status and the prerequisites
curl https://api.novafisko.com/v1/companies/k3Jd9fPq2LmX/peppol \
-H "Authorization: Bearer $NOVAFISKO_TOKEN"
{
"identity": null,
"participant_id": "0208:0999900134",
"status": "none",
"account": null,
"transport": null,
"smp": {"published": false, "checked_at": null},
"access_point": null,
"supported_documents": [],
"can_register": false,
"blockers": ["L'adresse e-mail de contact est manquante."],
"blocker_codes": ["email_missing"],
"managed_by_novadesko": false,
"registered_elsewhere": false,
"external_provider": null,
"provider_configured": true,
"environment": "production",
"contact": {"address": "Rue de Nimy 12", "postalcode": "7000", "city": "Mons", "province": null, "email": null, "phone": null},
"last_error": null
}
| Field | Description |
|---|---|
status |
none, pending, active, inactive, error, external or deleted |
participant_id |
Peppol identifier calculated from the enterprise number or the VAT number |
can_register |
true when no blocker prevents registration |
blocker_codes |
Stable codes of the blockers. blockers gives their translated text |
registered_elsewhere |
The participant already exists with another access point |
managed_by_novadesko |
The existing registration is managed from Novadesko |
Possible blockers
| Code | Meaning | Fix |
|---|---|---|
provider_not_configured |
The access point is not configured on the platform | Contact support |
vat_number_missing |
Neither a VAT number nor a usable enterprise number | Complete the company details |
address_missing |
Incomplete address | Provide address, postal_code, city |
email_missing |
No contact email address | Provide email |
managed_by_novadesko |
Already registered via Novadesko | Nothing to do, reception is already in place |
registered_elsewhere |
Already registered with another provider | See Already registered elsewhere |
Step 2: register the company
The fields sent complete or replace the contact details of the company for the registration.
curl -X POST https://api.novafisko.com/v1/companies/k3Jd9fPq2LmX/peppol/register \
-H "Authorization: Bearer $NOVAFISKO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "factures@comptoir-montois.example",
"phone": "+32 65 00 00 00",
"address": "Rue de Nimy 12",
"postal_code": "7000",
"city": "Mons",
"province": "Hainaut"
}'
| Field | Description |
|---|---|
email |
Contact address, 190 characters max |
phone |
Phone, 40 characters max |
address, postal_code, city, province |
Address of the registered office |
options.round_before_sum, options.apply_taxes_per_line, options.registered_for_empl_tax |
Calculation options of the account at the access point, optional booleans |
The response is 201 for a new registration, 200 if the company was already active. The body has the same shape as in step 1:
{
"identity": {
"id": 57,
"scheme": "iso6523-actorid-upis",
"value": "0208:0999900134",
"full_id": "iso6523-actorid-upis::0208:0999900134",
"provider": "b2brouter",
"status": "active",
"incoming_enabled": true,
"activated_at": "2026-10-05T09:02:11.000000Z"
},
"participant_id": "0208:0999900134",
"status": "active",
"account": {"id": "184223", "name": "Le Comptoir Montois SRL", "archived": false},
"transport": {
"enabled": true,
"reception": true,
"standard_documents": true,
"invoice": true,
"credit_note": true,
"self_billing": false,
"order": false,
"application_response": false
},
"smp": {"published": true, "checked_at": "2026-10-05T09:02:14+00:00"},
"access_point": {"smp_host": "smp.b2brouter.net", "provider_name": "B2Brouter", "endpoint_url": null, "technical_contact": null},
"supported_documents": ["invoice", "credit_note"],
"can_register": false,
"blockers": ["Le dossier est déjà inscrit sur Peppol."],
"blocker_codes": ["already_registered"],
"registered_elsewhere": false,
"provider_configured": true,
"environment": "production",
"last_error": null
}
The route is limited to 6 calls per minute.
If the registration is refused
A refusal returns 422 (or the status passed on by the provider) with the blockers and the current state:
{
"message": "Le dossier ne peut pas être inscrit sur Peppol.",
"errors": {"peppol": ["Le dossier ne peut pas être inscrit sur Peppol."]},
"blockers": ["Ce numéro est déjà inscrit sur Peppol auprès d'un autre fournisseur."],
"blocker_codes": ["registered_elsewhere"],
"state": {"status": "external", "registered_elsewhere": true, "external_provider": "Autre point d'accès"}
}
A problem on the access point side carries the provider_error code. Retry later.
Step 3: follow the activation
Publication in the Peppol directory can take a few minutes. Force a check:
curl -X POST https://api.novafisko.com/v1/companies/k3Jd9fPq2LmX/peppol/refresh \
-H "Authorization: Bearer $NOVAFISKO_TOKEN"
The company is reachable when status is active and smp.published is true. The route is limited to 12 calls per minute.
Rather than polling refresh in a loop, subscribe a webhook to the peppol.status_changed event.
Step 4: configure reception
curl -X PATCH https://api.novafisko.com/v1/companies/k3Jd9fPq2LmX/peppol/transport \
-H "Authorization: Bearer $NOVAFISKO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reception": true, "invoice": true, "credit_note": true, "self_billing": true}'
| Option | Role |
|---|---|
enabled |
Peppol transport active |
reception |
Reception of incoming documents |
standard_documents |
Standard set of documents |
invoice, credit_note |
Invoices and credit notes |
self_billing |
Self-billing |
order |
Orders |
application_response |
Application responses |
Send only the options to change. The others remain unchanged. The complete list of document types is available with GET peppol/document-types.
Check a partner
To find out whether a customer or a supplier is reachable on Peppol:
curl "https://api.novafisko.com/v1/companies/k3Jd9fPq2LmX/peppol/lookup?vat=BE0999900233&country=BE" \
-H "Authorization: Bearer $NOVAFISKO_TOKEN"
You can also pass identifier=0208:0999900233. For a third party of the company, GET third-parties/{id}/peppol returns the cached status and ?refresh=1 forces a new check.
Unregister the company
curl -X DELETE https://api.novafisko.com/v1/companies/k3Jd9fPq2LmX/peppol \
-H "Authorization: Bearer $NOVAFISKO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason_type": "other", "custom_reason": "Changement de logiciel de facturation"}'
reason_type is expensive, accountant or other. custom_reason is required with other. The response returns the identity one last time with the deleted status.
Technical log
GET peppol/logs?limit=50 returns the latest exchanges with the access point (method, URI, status, duration, error), 200 at most. Useful for diagnosing a provider_error.