Webhooks
Webhooks
The Webhooks API lets you subscribe an external HTTPS endpoint to events that happen inside e-bon — receipts being created, commands completing, devices going online or offline, reports being generated, etc. Every endpoint in this group lives under /api/v1/org/webhooks and is administrative: it manages the subscription, not the delivery payloads themselves. Once a subscription is in place, e-bon dispatches each matching event to your URL with an HMAC-SHA256 signature in the X-E-Bon-Signature header.
jwtAuth) and additionally require the calling user to have the Owner or Admin role on the organization. There is no API-key scope that grants access to webhook administration — generate a Portal session token (POST /api/v1/auth/login) and use it as Authorization: Bearer <jwt>. See Authentication › JWT authentication.The error envelope, rate limits and pagination conventions are documented once on API overview; only the per-endpoint error codes are listed in full on this page.
Event types
Subscriptions list one or more event types from this fixed set:
| Event | Fired when… |
|---|---|
receipt.created | A receipt has been persisted via POST /receipts. |
receipt.failed | Recording a receipt failed. |
command.completed | A fiscal command finished successfully on the AMEF. |
command.failed | A fiscal command was rejected by the AMEF. |
command.timeout | A fiscal command did not get a reply within the timeout window. |
device.online | A device's WebSocket connection came up. |
device.offline | A device's WebSocket connection dropped. |
report.generated | An X / Z / JE / MF report has been stored. |
webhook.test | Sent only by the Send test delivery endpoint below. |
GET /api/v1/org/webhooks
Lists all webhook subscriptions for the organization. Secrets are never returned by this endpoint — the raw signing secret is shown only at create time and on rotation.
- Auth: Portal JWT, role Owner or Admin.
Response (200 OK)
{
"webhooks": [
{
"id": "wh_abc123",
"orgId": "acme_corp",
"url": "https://hooks.example.com/e-bon",
"description": "Accounting integration",
"events": ["receipt.created", "report.generated"],
"enabled": true,
"failureCount": 0,
"lastDeliveryAt": "2026-04-09T08:09:55.000Z",
"lastDeliveryStatus": "success",
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-04-09T08:09:55.000Z",
"createdBy": "user_xyz"
}
]
}
Example
curl https://api.e-bon.ro/api/v1/org/webhooks \
-H "Authorization: Bearer <portal-jwt>"
Error codes
UNAUTHORIZED(401) — missing or invalid JWT.FORBIDDEN(403) — caller does not have Owner or Admin role.
The full HTTP catalogue is on API overview › HTTP error code catalogue.
POST /api/v1/org/webhooks
Creates a new webhook subscription. The raw signing secret is returned only once in the secret field of the response — store it immediately in your secret manager. There is no endpoint that returns the secret again.
- Auth: Portal JWT, role Owner or Admin.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
url | string | yes | Must be a valid HTTPS URL (the server rejects any non-https:// URL). |
description | string | no | Free-text label, ≤ 500 chars. |
events | string | yes | At least one event type from the table above. |
enabled | boolean | no | Defaults to true. Set to false to create a subscription that does not yet receive deliveries. |
Response (201 Created)
{
"webhook": {
"id": "wh_abc123",
"orgId": "acme_corp",
"url": "https://hooks.example.com/e-bon",
"description": "Accounting integration",
"events": ["receipt.created", "report.generated"],
"enabled": true,
"failureCount": 0,
"createdAt": "2026-04-09T08:10:00.000Z",
"createdBy": "user_xyz",
"secret": "whsec_8f3a9d…"
}
}
Example
curl -X POST https://api.e-bon.ro/api/v1/org/webhooks \
-H "Authorization: Bearer <portal-jwt>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/e-bon",
"description": "Accounting integration",
"events": ["receipt.created", "report.generated"]
}'
Error codes
VALIDATION_ERROR(400) — body failed Zod validation (non-HTTPS URL, missing/emptyevents,descriptionover 500 chars, unknown event type).UNAUTHORIZED(401) — missing or invalid JWT.FORBIDDEN(403) — caller does not have Owner or Admin role.
GET /api/v1/org/webhooks/{id}
Returns a single webhook subscription by ID. Secret is never returned.
- Auth: Portal JWT, role Owner or Admin.
Path parameters
| Parameter | Type | Notes |
|---|---|---|
id | string | Webhook subscription ID. |
Response (200 OK)
{
"webhook": {
"id": "wh_abc123",
"orgId": "acme_corp",
"url": "https://hooks.example.com/e-bon",
"description": "Accounting integration",
"events": ["receipt.created", "report.generated"],
"enabled": true,
"failureCount": 0,
"createdAt": "2026-03-01T12:00:00.000Z"
}
}
Example
curl https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123 \
-H "Authorization: Bearer <portal-jwt>"
Error codes
NOT_FOUND(404) — no webhook with that ID in your organization.UNAUTHORIZED/FORBIDDEN— see Authentication › Auth errors.
PATCH /api/v1/org/webhooks/{id}
Updates one or more fields on an existing webhook. At least one field must be provided. Re-enabling a previously disabled webhook (enabled: true) also resets failureCount to 0.
- Auth: Portal JWT, role Owner or Admin.
Request body
| Field | Type | Notes |
|---|---|---|
url | string | Must be HTTPS if provided. |
description | string | ≤ 500 chars. |
events | string | At least one event type from the table above. |
enabled | boolean | Toggle deliveries on/off. |
Response (200 OK)
Same shape as GET /api/v1/org/webhooks/{id} — the updated record without the secret.
Example
curl -X PATCH https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123 \
-H "Authorization: Bearer <portal-jwt>" \
-H "Content-Type: application/json" \
-d '{ "events": ["receipt.created"], "enabled": true }'
Error codes
VALIDATION_ERROR(400) — body failed Zod validation, or empty body (no fields to update).NOT_FOUND(404) — no webhook with that ID in your organization.UNAUTHORIZED/FORBIDDEN— see Authentication › Auth errors.
DELETE /api/v1/org/webhooks/{id}
Permanently deletes a webhook subscription and every delivery record stored in its deliveries subcollection. Returns 204 No Content on success.
- Auth: Portal JWT, role Owner or Admin.
Example
curl -X DELETE https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123 \
-H "Authorization: Bearer <portal-jwt>"
Error codes
NOT_FOUND(404) — no webhook with that ID in your organization.UNAUTHORIZED/FORBIDDEN— see Authentication › Auth errors.
POST /api/v1/org/webhooks/{id}/rotate-secret
Generates a fresh signing secret for the webhook and replaces the previous one. The new secret is returned only once in the response — store it before the request finishes.
- Auth: Portal JWT, role Owner or Admin.
Response (200 OK)
{
"secret": "whsec_NEW_VALUE…"
}
Example
curl -X POST https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123/rotate-secret \
-H "Authorization: Bearer <portal-jwt>"
Error codes
NOT_FOUND(404) — no webhook with that ID in your organization.UNAUTHORIZED/FORBIDDEN— see Authentication › Auth errors.
POST /api/v1/org/webhooks/{id}/test
Fires a synchronous test delivery with event type webhook.test to the webhook's URL. Returns the created delivery record (with the attempted HTTP status, response body fragment and any error message) so you can debug your endpoint without waiting for a real event.
- Auth: Portal JWT, role Owner or Admin.
- Side effect: persists a delivery record under
webhooks/{id}/deliveries.
Response (200 OK)
{
"delivery": {
"id": "del_test_abc",
"webhookId": "wh_abc123",
"orgId": "acme_corp",
"eventType": "webhook.test",
"payload": {
"id": "evt_…",
"type": "webhook.test",
"createdAt": "2026-04-09T08:10:00.000Z",
"orgId": "acme_corp",
"data": { "test": true, "message": "This is a test event from e-bon." }
},
"status": "success",
"attempt": 1,
"httpStatus": 200,
"createdAt": "2026-04-09T08:10:00.000Z",
"attemptedAt": "2026-04-09T08:10:00.500Z"
}
}
Example
curl -X POST https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123/test \
-H "Authorization: Bearer <portal-jwt>"
Error codes
NOT_FOUND(404) — no webhook with that ID in your organization.UNAUTHORIZED/FORBIDDEN— see Authentication › Auth errors.
GET /api/v1/org/webhooks/{id}/deliveries
Returns recent delivery attempts for the webhook, newest-first. Each delivery includes the dispatched payload, the attempt counter, the HTTP status returned by your endpoint, the response body fragment, and any error message captured by the retry sweeper.
- Auth: Portal JWT, role Owner or Admin.
Query parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
limit | integer | 50 | Page size, 1–200. |
status | string | — | One of pending, success, failed. |
Response (200 OK)
{
"deliveries": [
{
"id": "del_abc123",
"webhookId": "wh_abc123",
"orgId": "acme_corp",
"eventType": "receipt.created",
"payload": { "id": "evt_…", "type": "receipt.created" },
"status": "success",
"attempt": 1,
"httpStatus": 200,
"createdAt": "2026-04-09T08:09:55.000Z",
"attemptedAt": "2026-04-09T08:09:55.300Z"
}
]
}
Example
curl "https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123/deliveries?status=failed&limit=20" \
-H "Authorization: Bearer <portal-jwt>"
Error codes
VALIDATION_ERROR(400) — bad query (limit > 200, unknownstatusvalue).NOT_FOUND(404) — no webhook with that ID in your organization.UNAUTHORIZED/FORBIDDEN— see Authentication › Auth errors.
See also
- Webhook events — per-event payload reference, the four
X-EBon-*headers, and the HMAC SHA-256 signature verification flow. - Authentication — JWT login flow and the API-key scope catalogue.
- API overview — base URL, error envelope, rate limits, idempotency, pagination.
- Receipts and Devices — sources of the events that fire your webhooks.
- Troubleshooting › Webhook delivery failures — diagnose retries, the 20-failure auto-disable, and how to re-enable a subscription.
Devices
REST endpoints for managing fiscal devices (AMEFs) — CRUD, claim/release, live status, alerts, and the full set of device commands (cash balance, datetime, logos, VAT rates, header/footer, operators, void, reversal, etc.).
Billing
REST endpoints for managing the organization's Stripe subscription — checkout sessions, customer portal, subscription status, cancel/resume, invoices, and the Stripe webhook handler.