Poštár

Dokumentace API

Webhooky

Použijte webhooky pro příjem téměř okamžitých aktualizací o příchozích dokumentech a změnách životního cyklu. Payload webhooku je podepsán pomocí HMAC SHA-256 a odeslán s hlavičkou X-Webhook-Signature.

Registrovat webhook

Registrujte webhooky pro jednotlivé účastníky. Zahrňte pouze události, které potřebujete.

curl -X POST "https://api.peppos.cz/api/participants/{participantId}/webhooks" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/webhooks/peppol",
    "events": ["document.received", "mlr", "document.failed"]
  }'
await fetch("https://api.peppos.cz/api/participants/{participantId}/webhooks", {
  method: "POST",
  headers: {
    Authorization: "Bearer <token>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://your-app.example.com/webhooks/peppol",
    events: ["document.received", "mlr"],
  }),
});

Filtrování podle typu dokumentu

Pomocí volitelného pole documentTypes omezte doručování událostí dokumentu na konkrétní identifikátory typů dokumentů PEPPOL. Pokud je vynecháno nebo prázdné, jsou doručovány všechny typy dokumentů. Tento filtr nemá vliv na události account.verified a certificate.expiring.

{
  "url": "https://your-app.example.com/webhooks/peppol",
  "events": ["document.received"],
  "documentTypes": ["invoice", "creditnote"]
}

Typy událostí webhooku

UdálostVýznamTypická akce
document.receivedVáš účastník obdržel dokument.Synchronizujte schránku a zařaďte interní zpracování do fronty.
mlrOdpověď na úrovni zprávy pro stejnou dvojici dokument/zpráva: přijato nebo odmítnuto.Aktualizujte stav dokumentu ve svém ERP systému. V případě zamítnutí zkontrolujte a odešlete znovu.
invoice.responseOdpověď na fakturu (IMR, BIS 63) přijata pro vámi odeslanou fakturu nebo dobropis. Obchodní odpověď od kupujícího – např. AP (Přijato), RE (Zamítnuto), UQ (V dotazu), PD (Zaplaceno). Liší se od MLR: MLR je technická, IMR je obchodní.Aktualizujte stav faktury ve svém systému pohledávek. Při RE spusťte proces reklamace. Při PD označte jako zaplaceno.
order.responseOdpověď na objednávku (BIS 28) přijata pro vámi odeslanou objednávku. AP = přijato, RE = zamítnuto.Posuňte pracovní postup objednávky – spusťte plnění při AP, zahajte přezkum při RE.
document.sentOdchozí dokument byl přijat do odesílací pipeline.Označte jako odeslané / zařazené do fronty.
document.deliveredOdchozí doručení bylo úspěšně dokončeno.Označte jako doručené v ERP nebo v zákaznickém rozhraní.
document.failedOdeslání odchozího dokumentu selhalo.Vyvolejte upozornění a na své straně spusťte tok opakování/revize.
account.verifiedOvěření účastníka/účtu bylo dokončeno.Odemkněte kroky onboardingu a povolte produkční akce.
certificate.expiringPlatnost certifikátu se blíží ke konci.Obnovte certifikát před termínem vypršení.

Ukázky zpráv z praxe

Obálka webhooku je vždy { id, event, documentType, timestamp, data }. Níže jsou praktické příklady pro každou událost.

Dva webhooky na každou odpovědní zprávu. Při příchodu MLR, IMR nebo odpovědi na objednávku (OrderResponse) se aktivují dva webhooky: (1) událost přijetí zprávy (document.received, invoice.response nebo order.response); (2) událost mlr pro původní odchozí dokument, jehož stav se změnil. Oba payloady obsahují responseDocumentType ("mlr", "imr" nebo "order-response") a responseDocumentId (ID dokumentu IMR/OR, nebo null pro MLR).

Přijatá příchozí faktura — jeden webhook

document.received

{
  "id": "evt_2Bf0i7k3Qh",
  "event": "document.received",
  "documentType": "invoice",
  "timestamp": "2026-05-06T08:20:11.184Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "f9af7d6c-ccf5-4f6f-95d4-d5819b95fa8f",
    "documentExtId": "doc_ext_2026_0001",
    "senderName": "Supplier s.r.o.",
    "documentNumber": "INV-2026-0001",
    "recipientName": "Acme Trading CZ",
    "messageId": "ad3f58d2-0175-4d83-a9f9-8e2353baf9e8",
    "sender": { "peppolId": "9929:cz12345678" },
    "receiver": { "peppolId": "9929:cz87654321" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##...",
    "receivedAt": "2026-05-06T08:20:10.931Z",
    "status": "delivered",
    "senderRejected": false
  }
}

Přijatý MLR (technické potvrzení/odmítnutí) — dva webhooky

1/2 — přijata zpráva MLR · document.received

{
  "id": "evt_4Kp9nB2eRv",
  "event": "document.received",
  "documentType": "mlr",
  "timestamp": "2026-05-06T09:02:38.012Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "documentExtId": null,
    "senderName": null,
    "documentNumber": null,
    "recipientName": "Acme Trading CZ",
    "messageId": "c4d5e6f7-0011-2233-4455-667788990011",
    "sender": { "peppolId": "9929:cz87654321" },
    "receiver": { "peppolId": "9929:cz12345678" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:fdc:peppol.eu:poacc:trns:mlr:3::2.1",
    "receivedAt": "2026-05-06T09:02:37.891Z",
    "status": "delivered",
    "senderRejected": false,
    "responseDocumentType": "mlr",
    "responseDocumentId": null
  }
}

2/2 — původní dokument potvrzen/zamítnut · mlr

{
  "id": "evt_3Yu4m8Nq1a",
  "event": "mlr",
  "documentType": "mlr",
  "timestamp": "2026-05-06T09:02:41.443Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "documentExtId": null,
    "senderName": null,
    "documentNumber": null,
    "recipientName": "Acme Trading CZ",
    "messageId": "c4d5e6f7-0011-2233-4455-667788990011",
    "sender": { "peppolId": "9929:cz87654321" },
    "receiver": { "peppolId": "9929:cz12345678" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:fdc:peppol.eu:poacc:trns:mlr:3::2.1",
    "receivedAt": "2026-05-06T09:02:37.891Z",
    "status": "confirmed",
    "senderRejected": false,
    "responseDocumentType": "mlr",
    "responseDocumentId": null,
    "responseCode": "AP",
    "accepted": true
  }
}

Přijatý IMR (obchodní odpověď kupujícího na vaši fakturu) — dva webhooky

1/2 — přijat dokument IMR · invoice.response

{
  "id": "evt_R9xv3Aq4Lp",
  "event": "invoice.response",
  "documentType": "imr",
  "timestamp": "2026-05-06T11:14:32.771Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "c83e1b2d-0a47-4d12-b7e5-9f1ac3b84d52",
    "documentExtId": "doc_ext_2026_0002",
    "senderName": "Buyer GmbH",
    "documentNumber": "IMR-AP-2026-0042",
    "recipientName": "Acme Trading CZ",
    "messageId": "7f2c910b-3348-41e7-bba1-0f23abc89d11",
    "sender": { "peppolId": "9930:DE123456789" },
    "receiver": { "peppolId": "9929:cz87654321" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:fdc:peppol.eu:poacc:trns:invoice_response:3::2.1",
    "receivedAt": "2026-05-06T11:14:31.904Z",
    "status": "delivered",
    "senderRejected": false,
    "responseDocumentType": "imr",
    "responseDocumentId": "c83e1b2d-0a47-4d12-b7e5-9f1ac3b84d52",
    "responseCode": "AP",
    "accepted": true,
    "referencedDocumentId": "be5d4af1-9cf7-48f7-a4f9-0f5b7e1fbd81"
  }
}

2/2 — původní faktura potvrzena/zamítnuta · mlr

{
  "id": "evt_5Lm8pD3fWq",
  "event": "mlr",
  "documentType": "invoice",
  "timestamp": "2026-05-06T11:14:33.102Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "be5d4af1-9cf7-48f7-a4f9-0f5b7e1fbd81",
    "documentExtId": "doc_ext_invoice_001",
    "senderName": "Acme Trading CZ",
    "documentNumber": "INV-2026-0099",
    "recipientName": "Buyer GmbH",
    "messageId": "7f2c910b-3348-41e7-bba1-0f23abc89d11",
    "sender": { "peppolId": "9929:cz87654321" },
    "receiver": { "peppolId": "9930:DE123456789" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:fdc:peppol.eu:poacc:trns:invoice_response:3::2.1",
    "receivedAt": "2026-05-06T11:14:31.904Z",
    "status": "confirmed",
    "senderRejected": false,
    "responseDocumentType": "imr",
    "responseDocumentId": "c83e1b2d-0a47-4d12-b7e5-9f1ac3b84d52",
    "responseCode": "AP",
    "accepted": true
  }
}

Přijatá odpověď na objednávku (OrderResponse) — dva webhooky

1/2 — přijat dokument OrderResponse · order.response

{
  "id": "evt_W2zk5Bm7Nt",
  "event": "order.response",
  "documentType": "order-response",
  "timestamp": "2026-05-06T11:30:18.442Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "d91f2e4a-7b88-4c63-af29-3e8dc5a72b14",
    "documentExtId": "doc_ext_2026_0003",
    "senderName": "Supplier s.r.o.",
    "documentNumber": "OR-2026-0005",
    "recipientName": "Acme Trading CZ",
    "messageId": "aa8b451c-6712-4d88-92cb-1e0f7dcb3421",
    "sender": { "peppolId": "9929:cz12345678" },
    "receiver": { "peppolId": "9929:cz87654321" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:OrderResponse-2::OrderResponse##urn:fdc:peppol.eu:poacc:trns:order_response:3::2.1",
    "receivedAt": "2026-05-06T11:30:17.810Z",
    "status": "delivered",
    "senderRejected": false,
    "responseDocumentType": "order-response",
    "responseDocumentId": "d91f2e4a-7b88-4c63-af29-3e8dc5a72b14",
    "responseCode": "AP",
    "accepted": true,
    "referencedDocumentId": "f7a1c3d8-2b54-4e01-99c6-8d7af3b90e22"
  }
}

2/2 — původní objednávka potvrzena/zamítnuta · mlr

{
  "id": "evt_6Nq7rE4gXs",
  "event": "mlr",
  "documentType": "order",
  "timestamp": "2026-05-06T11:30:18.904Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "tenantExtId": "tenant_ext_001",
    "tenantName": "Acme Holding",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "participantExtId": "participant_ext_001",
    "participantName": "Acme Trading CZ",
    "webhookId": "webhook_123456",
    "webhookExtId": "wh_ext_primary",
    "documentId": "f7a1c3d8-2b54-4e01-99c6-8d7af3b90e22",
    "documentExtId": "doc_ext_order_001",
    "senderName": "Acme Trading CZ",
    "documentNumber": "ORD-2026-0022",
    "recipientName": "Supplier s.r.o.",
    "messageId": "aa8b451c-6712-4d88-92cb-1e0f7dcb3421",
    "sender": { "peppolId": "9929:cz87654321" },
    "receiver": { "peppolId": "9929:cz12345678" },
    "documentType": "urn:oasis:names:specification:ubl:schema:xsd:OrderResponse-2::OrderResponse##urn:fdc:peppol.eu:poacc:trns:order_response:3::2.1",
    "receivedAt": "2026-05-06T11:30:17.810Z",
    "status": "confirmed",
    "senderRejected": false,
    "responseDocumentType": "order-response",
    "responseDocumentId": "d91f2e4a-7b88-4c63-af29-3e8dc5a72b14",
    "responseCode": "AP",
    "accepted": true
  }
}

Životní cyklus odchozího dokumentu

document.sent

{
  "id": "evt_9pn2Q0w8Lx",
  "event": "document.sent",
  "documentType": "invoice",
  "timestamp": "2026-05-06T10:01:16.232Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "documentId": "be5d4af1-9cf7-48f7-a4f9-0f5b7e1fbd81",
    "messageId": "f1f12c53-8fb3-4ee9-a0cf-a8d8a696db91",
    "status": "sent"
  }
}

document.delivered

{
  "id": "evt_M4jP9s31xv",
  "event": "document.delivered",
  "documentType": "invoice",
  "timestamp": "2026-05-06T10:03:47.017Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "documentId": "be5d4af1-9cf7-48f7-a4f9-0f5b7e1fbd81",
    "messageId": "f1f12c53-8fb3-4ee9-a0cf-a8d8a696db91",
    "status": "delivered"
  }
}

document.failed

{
  "id": "evt_C1k4n2a7zQ",
  "event": "document.failed",
  "documentType": "invoice",
  "timestamp": "2026-05-06T10:04:25.559Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "documentId": "be5d4af1-9cf7-48f7-a4f9-0f5b7e1fbd81",
    "messageId": "f1f12c53-8fb3-4ee9-a0cf-a8d8a696db91",
    "status": "failed",
    "error": "SMP endpoint unavailable"
  }
}

Události účtu a certifikátu

account.verified

{
  "id": "evt_P7w0zv4J9n",
  "event": "account.verified",
  "documentType": null,
  "timestamp": "2026-05-06T10:10:04.291Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "verifiedAt": "2026-05-06T10:10:03.901Z"
  }
}

certificate.expiring

{
  "id": "evt_T4h8qb2M1d",
  "event": "certificate.expiring",
  "documentType": null,
  "timestamp": "2026-05-06T10:15:55.009Z",
  "data": {
    "tenantId": "tnt_3d9...",
    "participantId": "5a4f1e7f-95c7-4f7b-bec4-45b3f7e9db93",
    "certificateId": "b6f39c9a-6467-4f53-9598-5f1dd22f9f61",
    "expiresAt": "2026-06-05T00:00:00.000Z",
    "daysRemaining": 30
  }
}

Doporučený postup pro spolehlivé zpracování příchozích dokumentů

Nejbezpečnější přístup je: použít webhook jako spouštěč, poté přečíst schránku a následně potvrdit.

  1. Naslouchejte document.received (a volitelně mlr) událostem webhooku.
  2. Po přijetí webhooku zavolejte jeden z endpointů schránky:
    • GET https://api.peppos.cz/api/documents/inbox
    • GET https://api.peppos.cz/api/participants/{participantId}/documents/inbox
    • GET https://api.peppos.cz/api/tenants/{tenantId}/participants/{participantId}/documents/inbox
  3. Zpracujte každý dokument a poté zavolejte POST https://api.peppos.cz/api/documents/{documentId}/mlr/confirm.

Proč je to spolehlivé: endpointy schránky vracejí dokumenty, které ještě nebyly potvrzeny, takže i když doručení webhooku selže, váš polling/read-after-trigger tok stále dokáže obnovit všechny čekající položky.

Opakování, sémantika doručení a idempotence

  • Doručení webhooku se po prvním pokusu opakuje ještě 5krát (celkem 6 pokusů).
  • Schéma prodlev je 10 s, 20 s, 40 s, 80 s a 160 s po neúspěšných pokusech 1 až 5.
  • Pokud selžou všechny pokusy, doručení je v logách/událostech serveru označeno jako neúspěšné.
  • Navrhněte příjemce jako idempotentní: deduplikujte podle obálky události id a/nebo business tuple (event, documentId, messageId, status).
  • Ověřte X-Webhook-Signature vůči tajnému klíči vašeho webhooku před zpracováním payloadu.