How to Start as SaaS Vendor
- Register at https://peppol.dativery.com/register.
- Open Settings / API Keys, choose Tenant only and set permissions.
- Create participant:
POST https://peppol.dativery.com/participants. - Start verification:
POST https://peppol.dativery.com/participants/{participantId}/verify/initiate?callback=https%3A%2F%2Fyour-saas.example.com%2Fverification%2Fdone. The returnedverificationUrlopens the onboarding flow and redirects back to the callback URL when the user finishes or cancels. - Check verification status:
GET https://peppol.dativery.com/participants/{participantId}/verify/status. - Register in Peppol:
POST https://peppol.dativery.com/participants/{participantId}/peppol/register. - Register webhooks:
POST https://peppol.dativery.com/participants/{participantId}/webhooks. - Send documents and consume inbox endpoints.
All endpoint examples below use absolute URLs with the production domain.
TypeScript Example
const APP_URL = process.env.APP_URL!;
const API_KEY = process.env.API_KEY!;
const USER_JWT = process.env.USER_JWT!; // user session token for browser handoff links
const headers = {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
};
async function jsonFetch(url: string, init: RequestInit = {}) {
const res = await fetch(url, {
...init,
headers: { ...headers, ...(init.headers ?? {}) },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
return res.json();
}
const participant = await jsonFetch('https://peppol.dativery.com/participants', {
method: 'POST',
body: JSON.stringify({
name: 'Firma s.r.o.',
registrationNumber: '123',
euVatId: 'CZ123',
countryCode: 'cz',
}),
});
const participantId = participant.id; // or "9929:123"
const callback = encodeURIComponent('https://your-saas.example.com/verification/done');
const verification = await jsonFetch(
`https://peppol.dativery.com/participants/${participantId}/verify/initiate?callback=${callback}`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${USER_JWT}`,
},
},
);
console.log('Verification URL:', verification.verificationUrl);
const status = await jsonFetch(`https://peppol.dativery.com/participants/${participantId}/verify/status`);
console.log('Verification status:', status);
await jsonFetch(`https://peppol.dativery.com/participants/${participantId}/peppol/register`, { method: 'POST' });
await jsonFetch(`https://peppol.dativery.com/participants/${participantId}/webhooks`, {
method: 'POST',
body: JSON.stringify({
url: 'https://your-saas.example.com/webhooks/peppol',
events: ['document.received', 'document.status.changed'],
}),
});
await jsonFetch(`https://peppol.dativery.com/participants/${participantId}/documents/send`, {
method: 'POST',
body: JSON.stringify({
receiverParticipantId: '9925:12345678',
documentType: 'invoice',
payloadFormat: 'ubl',
payload: '<Invoice>...</Invoice>',
}),
});
const inbox = await jsonFetch(`https://peppol.dativery.com/participants/${participantId}/documents/inbox`);
for (const doc of inbox.items ?? []) {
await jsonFetch(`https://peppol.dativery.com/documents/${doc.id}/acknowledge`, { method: 'POST' });
}PHP Example
<?php
$apiKey = getenv('API_KEY');
function requestJson($method, $url, $body = null) {
global $apiKey;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status >= 400) {
throw new Exception("HTTP $status: $response");
}
return json_decode($response, true);
}
$participant = requestJson('POST', 'https://peppol.dativery.com/participants', [
'name' => 'Firma s.r.o.',
'registrationNumber' => '123',
'euVatId' => 'CZ123',
'countryCode' => 'cz'
]);
$participantId = $participant['id'];
requestJson('POST', "https://peppol.dativery.com/participants/$participantId/verify/initiate?autoregister=true");
$status = requestJson('GET', "https://peppol.dativery.com/participants/$participantId/verify/status");
requestJson('POST', "https://peppol.dativery.com/participants/$participantId/peppol/register");
requestJson('POST', "https://peppol.dativery.com/participants/$participantId/webhooks", [
'url' => 'https://your-saas.example.com/webhooks/peppol',
'events' => ['document.received', 'document.status.changed']
]);
requestJson('POST', "https://peppol.dativery.com/participants/$participantId/documents/send", [
'receiverParticipantId' => '9925:12345678',
'documentType' => 'invoice',
'payloadFormat' => 'ubl',
'payload' => '<Invoice>...</Invoice>'
]);
$inbox = requestJson('GET', "https://peppol.dativery.com/participants/$participantId/documents/inbox");
foreach (($inbox['items'] ?? []) as $doc) {
requestJson('POST', 'https://peppol.dativery.com/documents/' . $doc['id'] . '/acknowledge');
}cURL Example
export APP_URL="https://your-domain.example.com"
export API_KEY="YOUR_API_KEY"
# Create participant
curl -X POST "https://peppol.dativery.com/participants" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Firma s.r.o.",
"registrationNumber": "123",
"euVatId": "CZ123",
"countryCode": "cz"
}'
# Start verification and receive verificationUrl (use a user JWT, not the tenant API key)
curl -X POST "https://peppol.dativery.com/participants/9929:123/verify/initiate?callback=https%3A%2F%2Fyour-saas.example.com%2Fverification%2Fdone" -H "Authorization: Bearer $USER_JWT"
# Check verification status
curl -X GET "https://peppol.dativery.com/participants/9929:123/verify/status" \
-H "Authorization: Bearer $API_KEY"
# Register participant to Peppol
curl -X POST "https://peppol.dativery.com/participants/9929:123/peppol/register" \
-H "Authorization: Bearer $API_KEY"
# Register webhook
curl -X POST "https://peppol.dativery.com/participants/9929:123/webhooks" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-saas.example.com/webhooks/peppol",
"events": ["document.received", "document.status.changed"]
}'
# Send document
curl -X POST "https://peppol.dativery.com/participants/9929:123/documents/send" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"receiverParticipantId":"9925:12345678","documentType":"invoice","payloadFormat":"ubl","payload":"<Invoice>...</Invoice>"}'
# Read inbox
curl -X GET "https://peppol.dativery.com/participants/9929:123/documents/inbox" \
-H "Authorization: Bearer $API_KEY"
# Acknowledge received document
curl -X POST "https://peppol.dativery.com/documents/DOCUMENT_ID/acknowledge" \
-H "Authorization: Bearer $API_KEY"Python Example
import os
import requests
API_KEY = os.environ['API_KEY']
USER_JWT = os.environ['USER_JWT']
HEADERS = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json',
}
def req(method, url, payload=None):
response = requests.request(method, url, headers=HEADERS, json=payload)
response.raise_for_status()
return response.json()
participant = req('POST', 'https://peppol.dativery.com/participants', {
'name': 'Firma s.r.o.',
'registrationNumber': '123',
'euVatId': 'CZ123',
'countryCode': 'cz',
})
participant_id = participant.get('id', '9929:123')
initiate = requests.post(
f"https://peppol.dativery.com/participants/{participant_id}/verify/initiate?callback=https%3A%2F%2Fyour-saas.example.com%2Fverification%2Fdone",
headers={
'Authorization': f'Bearer {USER_JWT}',
'Content-Type': 'application/json',
},
)
initiate.raise_for_status()
initiate = initiate.json()
print('Verification URL:', initiate.get('verificationUrl'))
status = req('GET', f'https://peppol.dativery.com/participants/{participant_id}/verify/status')
print('Verification status:', status)
req('POST', f'https://peppol.dativery.com/participants/{participant_id}/peppol/register')
req('POST', f'https://peppol.dativery.com/participants/{participant_id}/webhooks', {
'url': 'https://your-saas.example.com/webhooks/peppol',
'events': ['document.received', 'document.status.changed'],
})
req('POST', f'https://peppol.dativery.com/participants/{participant_id}/documents/send', {
'receiverParticipantId': '9925:12345678',
'documentType': 'invoice',
'payloadFormat': 'ubl',
'payload': '<Invoice>...</Invoice>',
})
inbox = req('GET', f'https://peppol.dativery.com/participants/{participant_id}/documents/inbox')
for doc in inbox.get('items', []):
req('POST', f"https://peppol.dativery.com/documents/{doc['id']}/acknowledge")