API Overview
The Invostaq API lets you send and receive e-invoices through the Peppol network. This page gives you the full picture before you dive into individual guides.
Invoice lifecycle
You Invostaq Peppol Network
│ │ │
│ POST /v2/invoices/send │ │
│ ──────────────────────────► │ │
│ │ Validate + build UBL XML │
│ │ Submit to Access Point │
│ │ ────────────────────────────► │
│ { status: "success" } │ │
│ ◄────────────────────────── │ │
│ │ │
│ │ transaction.sent │
│ │ ◄──────────────────────────── │
│ Webhook: Delivered │ │
│ ◄────────────────────────── │ │
- You send invoice data via
POST /v2/invoices/send(or legacyPOST /v2/invoices/send) with your API key - Invostaq validates the data, builds a UBL 2.1 XML document, and submits it to the Peppol Access Point
- You get an immediate response with
status: "success"and atransactionId— the invoice is nowProcessing - The Access Point delivers the invoice to the recipient and calls back
- You receive a webhook with the final status:
DeliveredorFailed
Base URL
| Environment | Base URL |
|---|---|
| Production | https://api.invostaq.com/api |
| Sandbox | https://api.invostaq.com/api (same URL, uses sk_test_ key) |
All endpoint paths in this documentation are relative to the base URL. There is no separate sandbox URL — environment routing is determined by your API key prefix.
Public API endpoints
Authenticated with the x-api-key header. These are the endpoints you use to send invoices.
| Method | Path | Description |
|---|---|---|
GET | /v2/lookup?participantId={id} | Check if a recipient is registered on Peppol |
POST | /v2/invoices/send | Send an invoice through the Peppol network (recommended for new integrations) |
POST | /v2/invoices/send | Send an invoice (legacy contract, still supported) |
See the full API Reference for request/response schemas.
Authentication summary
| Endpoint type | Auth method | Header |
|---|---|---|
Public API (/v2/*) | API key | x-api-key: sk_test_... |
| Webhook callbacks | Secret header | X-Webhook-Secret: ... |
See Authentication for details on key management, sandbox vs. live keys, and rate limits.
Request format
- Content type:
application/json - Dates: ISO 8601 format (
2024-06-15T00:00:00Z) - Money: Decimal numbers (
1050.00, not"1050.00") - Participant IDs: ISO 6523 format (
0196:971501234567— 4-digit scheme, colon, identifier)
Response format
Success responses return the resource directly:
{
"status": "success",
"transactionId": "txn_abc123def456",
"databaseRecordId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"provider": "Invostaq"
}
Error responses use RFC 7807 Problem Details:
{
"type": "https://invostaq.com/errors/totals-mismatch",
"title": "Invoice totals mismatch",
"detail": "Computed line total is 105.00, but totalAmount is 999.99.",
"status": 400
}
Match on the type field for programmatic error handling. See the Error Reference for all error types.
Rate limits
| Method | Limit | Scope |
|---|---|---|
| GET | 60/min | Per API key |
| POST | 20/min | Per API key |
Exceeding the limit returns 429 Too Many Requests with a Retry-After header.
Idempotency
The send endpoint supports idempotent requests via the Idempotency-Key header:
curl -X POST .../v2/invoices/send \
-H "Idempotency-Key: inv-2024-001-send" \
...
- If the key has been seen before (same tenant), the API returns the original result without resubmitting to Peppol
- Keys can be any string up to 128 characters
- Always include an idempotency key in production — it protects against duplicate submissions on network timeouts
Peppol participant ID format
Invostaq uses ISO 6523 identifiers for Peppol routing:
{scheme}:{identifier}
| Scheme | Country / Standard | Example |
|---|---|---|
0196 | UAE (TRN) | 0196:971501234567 |
0088 | International (GLN) | 0088:1234567890123 |
0007 | Sweden (Org number) | 0007:1234567890 |
0106 | Netherlands (KVK) | 0106:12345678 |
0208 | Belgium (CBE) | 0208:0453054123 |
0231 | Saudi Arabia (TIN) | 0231:300000000000003 |
Use GET /v2/lookup to verify a participant ID is registered before sending.