Outgoing Webhooks
Status: Planned
MIDDAG Account will support outgoing webhooks to notify external systems when domain events occur. This allows you to build custom integrations without modifying the plugin.
How it works
When a significant event happens in the plugin (an entitlement is activated, an order is paid, an organization is updated), the plugin sends an HTTP POST request to one or more configured URLs. The receiving system processes the event and takes whatever action is appropriate.
Event catalog
Organization events
| Event | Fired when |
|---|---|
organization.created | A new organization is created |
organization.updated | Organization data is modified |
organization.verified | Organization verification status changes |
Entitlement events
| Event | Fired when |
|---|---|
entitlement.activated | An entitlement becomes active |
entitlement.suspended | An entitlement is suspended |
entitlement.expired | An entitlement reaches its expiration |
entitlement.cancelled | An entitlement is cancelled |
entitlement.renewed | An entitlement is renewed |
Order events
| Event | Fired when |
|---|---|
order.created | A new order is placed |
order.paid | An order payment is confirmed |
order.refunded | An order is refunded |
Quote events
| Event | Fired when |
|---|---|
quote.created | A new quote is created |
quote.accepted | A customer accepts a quote |
quote.paid | A quote is paid |
quote.expired | A quote passes its expiration date |
License events
| Event | Fired when |
|---|---|
license.activated | A license is activated on a site |
license.deactivated | A license is deactivated |
license.expired | A license expires |
Service request events
| Event | Fired when |
|---|---|
ticket.created | A new service request is opened |
ticket.completed | A service request is resolved |
ticket.sla_breached | An SLA target is breached |
Invoice events
| Event | Fired when |
|---|---|
invoice.issued | An invoice is issued |
tax_invoice.issued | An NFSe is successfully issued |
tax_invoice.failed | An NFSe emission fails |
Payload format
Every webhook payload follows a consistent envelope:
{
"event": "entitlement.activated",
"timestamp": "2026-05-04T14:30:00Z",
"version": "1",
"data": {
"id": 42,
"code": "PLG-202605-0001",
"organization_id": 7,
"status": "active",
"class": "plugin"
}
}| Field | Description |
|---|---|
event | Event type from the catalog above |
timestamp | ISO 8601 timestamp when the event occurred |
version | Payload schema version (currently "1") |
data | Event-specific data (the relevant entity or DTO) |
The data field contains the same structure returned by the REST API for the corresponding entity.
Retry policy
| Attempt | Delay | Notes |
|---|---|---|
| 1 | Immediate | First delivery attempt |
| 2 | 1 minute | First retry |
| 3 | 5 minutes | Second retry |
| 4 | 30 minutes | Third retry |
| 5 | 2 hours | Final retry |
A delivery is considered successful when the receiving server responds with an HTTP 2xx status code. Any other response (or a timeout) triggers a retry.
After all retry attempts are exhausted, the event is marked as failed. Failed events are visible in the admin UI and can be retried manually.
Signature verification
Every outgoing webhook includes a signature header so the receiving system can verify the request originated from MIDDAG Account:
X-Middag-Signature: sha256=<HMAC-SHA256 hex digest>The signature is computed as HMAC-SHA256(webhook_secret, raw_request_body). The receiving system should:
- Read the
X-Middag-Signatureheader. - Compute
HMAC-SHA256of the raw request body using the shared secret. - Compare the computed value with the header value using a constant-time comparison.
- Reject the request if the values do not match.
Configuration
Webhook endpoints are configured per organization in the admin UI:
| Setting | Description |
|---|---|
| URL | The HTTPS endpoint that receives webhook POSTs |
| Secret | Shared secret for HMAC signature verification |
| Events | Which events to send (select from the catalog) |
| Active | Enable or disable the endpoint |
Multiple endpoints can be configured per organization. Each endpoint can subscribe to a different set of events.
Requirements for receiving endpoints
- Must accept HTTP POST requests.
- Must respond within 30 seconds.
- Must use HTTPS (HTTP endpoints are not allowed).
- Should return HTTP 200 to acknowledge receipt.
- Should validate the
X-Middag-Signatureheader.
Delivery guarantees
Webhooks use at-least-once delivery. The same event may be delivered more than once (due to retries or infrastructure issues). Receiving systems should be idempotent -- processing the same event twice should produce the same result. Use the event + timestamp + data.id combination to detect duplicates.