Webhooks
Real-time notifications for invoice status changes, batch events, and incoming webhook integrations.
The KSeF API Gateway supports both outgoing webhooks (notifications from Gateway to your system) and incoming webhooks (receiving data from external platforms).
Outgoing Webhooks
Get notified when invoice statuses change, batches complete, or sessions expire.
Events
| Event | Description |
|---|---|
invoice.queued | Invoice accepted and queued for submission |
invoice.sending | Invoice being sent to KSeF |
invoice.registered | Invoice accepted by KSeF (has KSeF reference number) |
invoice.failed | Invoice rejected by KSeF |
batch.started | Batch processing started |
batch.completed | All invoices in batch processed successfully |
batch.partial | Batch completed with some failures |
batch.failed | Batch processing failed |
session.expired | KSeF session expired |
credential.expiring | Credential expires within 7 days |
Payload Format
Every event uses a standard envelope:
{
"webhook_id": "d1234567-...",
"event": "invoice.registered",
"timestamp": "2026-03-13T22:27:31Z",
"tenant_id": "60950d4b-...",
"data": {
"invoice_id": "c0e51a43-...",
"invoice_number": "FV/2026/03/001",
"status": "registered",
"ksef_number": "6112764898-20260313-A4EEA8C00000-D3",
"ksef_url": "https://ksef.mf.gov.pl/client-app/invoice-view/...",
"registered_at": "2026-03-13T22:27:31Z"
}
}HMAC Signature Verification
Every outgoing webhook is signed with HMAC-SHA256. Verify authenticity on your side:
import hmac, hashlib
def verify_webhook(payload_bytes: bytes, secret: str, signature: str) -> bool:
expected = hmac.new(secret.encode(), payload_bytes, hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)Request headers sent with each delivery:
| Header | Description |
|---|---|
X-Webhook-Signature | sha256={hmac_hex} |
X-Webhook-Event | Event type (e.g. invoice.registered) |
X-Webhook-Delivery-Id | Unique delivery UUID |
X-Webhook-Timestamp | ISO 8601 timestamp |
User-Agent | KSeFAPI-Webhook/1.0 |
Retry Policy
Failed deliveries are retried with exponential backoff: 10s → 30s → 2min → 10min → 1h. After 50 consecutive failures, the endpoint is automatically disabled.
Endpoint Management
| Method | Endpoint | Description |
|---|---|---|
POST | /api/webhooks/endpoints | Register new endpoint |
GET | /api/webhooks/endpoints | List all endpoints |
GET | /api/webhooks/endpoints/{id} | Get endpoint details |
PATCH | /api/webhooks/endpoints/{id} | Update endpoint |
DELETE | /api/webhooks/endpoints/{id} | Delete endpoint |
POST | /api/webhooks/endpoints/{id}/test | Send test ping |
GET | /api/webhooks/endpoints/{id}/deliveries | Delivery history |
Register an Endpoint
POST /api/webhooks/endpoints
Authorization: Bearer {token}
Content-Type: application/json{
"url": "https://your-system.com/api/ksef-webhook",
"events": ["invoice.registered", "invoice.failed"],
"secret": "whsec_your_secret_key",
"description": "Production ERP webhook"
}Incoming Webhooks
Receive invoices from external platforms (e-commerce, ERP) and automatically process them through the KSeF pipeline.
Supported Platforms
| Platform | Endpoint |
|---|---|
| Generic (your format) | POST /api/webhooks/incoming/generic/{integration_id} |
| Shopify | POST /api/webhooks/incoming/shopify/{integration_id} |
| WooCommerce | POST /api/webhooks/incoming/woocommerce/{integration_id} |
| BaseLinker | POST /api/webhooks/incoming/baselinker/{integration_id} |
Authentication
Incoming webhooks authenticate via X-Webhook-Key header containing the API key generated during integration creation.
Integration Management
| Method | Endpoint | Description |
|---|---|---|
POST | /api/webhooks/integrations | Create integration (returns API key once) |
GET | /api/webhooks/integrations | List integrations |
GET | /api/webhooks/integrations/{id} | Details + stats |
PATCH | /api/webhooks/integrations/{id} | Update config |
DELETE | /api/webhooks/integrations/{id} | Delete |
POST | /api/webhooks/integrations/{id}/rotate-key | Generate new API key |
POST | /api/webhooks/integrations/{id}/test | Dry-run with sample payload |
Dashboard & Monitoring
GET /api/webhooks/stats{
"outgoing": {
"total_endpoints": 3,
"active_endpoints": 2,
"last_24h": { "sent": 142, "failed": 3, "pending": 1 }
},
"incoming": {
"total_integrations": 2,
"active_integrations": 2,
"last_24h": { "received": 87, "processed": 85, "failed": 2 }
}
}GET /api/webhooks/deliveries?direction=outgoing&status=failed&last=24h&limit=50Paginated delivery log with filters — useful for debugging and monitoring.