API Documentation
Technical guide for integrating your software with Simple Peppol Gateway
Table of Contents
Authentication
All API requests require authentication using a Bearer token. You'll receive an API token when your account is created.
Authorization: Bearer SBG_your_api_token_here
API tokens are prefixed with SBG_ and should be kept secure.
Never commit tokens to version control.
Security Note: Tokens are hashed using SHA-256 with your account's salt. Store tokens securely and rotate them periodically.
Base URL
The base URL is the same for every customer. The environment is selected entirely by the path — the token is used as-is in both.
- Production:
https://peppol-api.simplebill.pro/api/v1— sends to the live Peppol network. - Sandbox:
https://peppol-api.simplebill.pro/api-sandbox/v1— validate your integration against the test Peppol network before going live.
Sending Documents
Send Peppol documents (invoices, credit notes, orders) via the POST /api/v1/documents endpoint.
Request
POST /api/v1/documents
Content-Type: application/json
Authorization: Bearer SBG_your_api_token_here
Idempotency-Key: your-unique-idempotency-key (optional)
{
"sender_peppol_id": "0199:pixeline",
"receiver_peppol_id": "0199:triaxis",
"document_type_id": "urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0",
"process_id": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"payload_format": "ubl",
"payload_xml": "<Invoice xmlns='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'>...</Invoice>",
"client_reference": "simplebill-invoice-1234"
}
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
sender_peppol_id |
string | Yes | Your registered Peppol participant ID (e.g., "0199:pixeline") |
receiver_peppol_id |
string | Yes | Recipient's Peppol participant ID |
document_type_id |
string | Yes | Peppol document type URN (e.g., invoice, credit note) |
process_id |
string | Yes | Peppol process URN |
payload_format |
string | Yes | Either "ubl" or "sbdh" |
payload_xml |
string | Yes | The UBL XML document (max 10 MB) |
client_reference |
string | No | Your unique reference for idempotency (prevents duplicate sends) |
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued"
}
Checking Document Status
Poll the document status using GET /api/v1/documents/{id}:
GET /api/v1/documents/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer SBG_your_api_token_here
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "sent",
"direction": "outbound",
"sender_peppol_id": "0199:pixeline",
"receiver_peppol_id": "0199:triaxis",
"document_type_id": "urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0",
"sent_at": "2025-11-29T10:30:00Z"
}
Document statuses: queued,
processing,
sent,
delivered,
failed
Receiving Documents
You can receive inbound Peppol documents in two ways: via webhooks (recommended) or by polling the API.
Polling Method
List inbound documents using GET /api/v1/inbox:
GET /api/v1/inbox?page=1&per_page=50
Authorization: Bearer SBG_your_api_token_here
Response:
{
"data": [
{
"id": "660e8400-e29b-41d4-a716-446655440000",
"status": "delivered",
"sender_peppol_id": "0199:triaxis",
"receiver_peppol_id": "0199:pixeline",
"document_type_id": "urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0",
"received_at": "2025-11-29T10:30:00Z"
}
],
"current_page": 1,
"per_page": 50,
"total": 1
}
Retrieving Document Payload
Get the full XML payload using GET /api/v1/inbox/{id}:
GET /api/v1/inbox/660e8400-e29b-41d4-a716-446655440000
Authorization: Bearer SBG_your_api_token_here
Response:
{
"id": "660e8400-e29b-41d4-a716-446655440000",
"payload_xml": "<StandardBusinessDocument>...</StandardBusinessDocument>",
...
}
Webhooks
Configure webhooks to receive real-time notifications when documents are received. Webhooks are sent via HTTP POST to your configured endpoint.
Webhook Payload
POST https://your-endpoint.com/webhooks/peppol
X-SimpleBill-Event: peppol.inbound_document.received
X-SimpleBill-Signature: sha256=abc123...
Content-Type: application/json
{
"event": "peppol.inbound_document.received",
"id": "660e8400-e29b-41d4-a716-446655440000",
"sender_peppol_id": "0199:triaxis",
"receiver_peppol_id": "0199:pixeline",
"document_type_id": "urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0",
"process_id": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"received_at": "2025-11-29T10:30:00Z",
"payload_xml": "<StandardBusinessDocument>...</StandardBusinessDocument>"
}
Webhook Signature Verification
Verify webhook authenticity by checking the X-SimpleBill-Signature header.
The signature is computed as HMAC-SHA256(request_body, webhook_secret).
Important: Always verify webhook signatures to ensure requests are from Simple Peppol Gateway.
Usage Tracking
Monitor your API usage for the current billing period:
GET /api/v1/usage/current
Authorization: Bearer SBG_your_api_token_here
Response:
{
"period_start": "2025-11-01",
"period_end": "2025-11-30",
"outbound_count": 123,
"inbound_count": 45,
"outbound_bytes": 1234567,
"inbound_bytes": 7654321
}
Error Handling
The API uses standard HTTP status codes:
200- Success400- Bad Request (invalid parameters)401- Unauthorized (invalid or missing token)403- Forbidden (insufficient permissions)404- Not Found422- Validation Error429- Too Many Requests (rate limit exceeded)500- Internal Server Error
Error responses include a JSON body with error details:
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"message": "The given data was invalid.",
"errors": {
"sender_peppol_id": ["The sender peppol id field is required."]
}
}
Code Examples
cURL
curl -X POST https://peppol-api.simplebill.pro/api/v1/documents \
-H "Authorization: Bearer SBG_your_api_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoice-1234" \
-d '{
"sender_peppol_id": "0199:pixeline",
"receiver_peppol_id": "0199:triaxis",
"document_type_id": "urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0",
"process_id": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"payload_format": "ubl",
"payload_xml": "<Invoice>...</Invoice>",
"client_reference": "invoice-1234"
}'
PHP (Guzzle)
$client = new \GuzzleHttp\Client();
$response = $client->post('https://peppol-api.simplebill.pro/api/v1/documents', [
'headers' => [
'Authorization' => 'Bearer SBG_your_api_token_here',
'Content-Type' => 'application/json',
'Idempotency-Key' => 'invoice-1234',
],
'json' => [
'sender_peppol_id' => '0199:pixeline',
'receiver_peppol_id' => '0199:triaxis',
'document_type_id' => 'urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0',
'process_id' => 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0',
'payload_format' => 'ubl',
'payload_xml' => $ublXml,
'client_reference' => 'invoice-1234',
],
]);
$result = json_decode($response->getBody(), true);
Python (requests)
import requests
response = requests.post(
'https://peppol-api.simplebill.pro/api/v1/documents',
headers={
'Authorization': 'Bearer SBG_your_api_token_here',
'Content-Type': 'application/json',
'Idempotency-Key': 'invoice-1234',
},
json={
'sender_peppol_id': '0199:pixeline',
'receiver_peppol_id': '0199:triaxis',
'document_type_id': 'urn:fdc:peppol.eu:2017:poacc:billing:3:ver2.0',
'process_id': 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0',
'payload_format': 'ubl',
'payload_xml': ubl_xml,
'client_reference': 'invoice-1234',
}
)
result = response.json()
Need Help?
For additional support, questions, or to request API access, please contact us:
Contact Support