Skip to content

Webhooks

Webhooks allow you to receive real-time HTTP notifications when invoice statuses change or connections are updated. Instead of polling the API, register a webhook URL and Mandato will POST events to it.

Each account has a single webhook configuration. Events are signed with HMAC-SHA256 so you can verify their authenticity.

When retrieving the current webhook configuration, the secret is masked:

{
"url": "https://your-app.com/webhooks/mandato",
"secret": "wh_***",
"events": [
"invoice.accepted",
"invoice.rejected",
"invoice.error",
"connection.expired"
]
}
FieldTypeDescription
urlstring|nullThe URL where events are delivered
secretstring|nullWebhook signing secret (masked after creation)
eventsarray|nullEvent types to subscribe to (null = all events)

When creating or updating a webhook, the full secret is returned once:

{
"url": "https://your-app.com/webhooks/mandato",
"secret": "wh_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"events": [
"invoice.accepted",
"invoice.rejected",
"invoice.error",
"connection.expired"
]
}

POST /v1/webhooks

Registers or updates the webhook URL for your account. If a webhook already exists, it is replaced. A new signing secret is generated each time.

FieldTypeRequiredDescription
urlstringYesHTTPS URL to receive webhook events
eventsarrayNoEvent types to subscribe to. Omit to receive all events.
EventDescription
invoice.createdInvoice was created and queued
invoice.validatedInvoice passed validation
invoice.submittedInvoice was submitted to the government system
invoice.acceptedGovernment accepted the invoice
invoice.rejectedGovernment rejected the invoice
invoice.errorProcessing error occurred
connection.activeGovernment connection became active
connection.expiredGovernment connection token expired
Terminal window
curl -X POST https://api.getmandato.dev/v1/webhooks \
-H "Authorization: Bearer sk_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/mandato",
"events": [
"invoice.accepted",
"invoice.rejected",
"invoice.error",
"connection.expired"
]
}'
{
"data": {
"url": "https://your-app.com/webhooks/mandato",
"secret": "wh_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"events": [
"invoice.accepted",
"invoice.rejected",
"invoice.error",
"connection.expired"
]
}
}
StatusTypeDescription
400validation_errorInvalid URL format or unknown event types

GET /v1/webhooks

Returns the current webhook configuration. The signing secret is masked.

Terminal window
curl https://api.getmandato.dev/v1/webhooks \
-H "Authorization: Bearer sk_test_your_key"
{
"data": {
"url": "https://your-app.com/webhooks/mandato",
"secret": "wh_***",
"events": [
"invoice.accepted",
"invoice.rejected",
"invoice.error",
"connection.expired"
]
}
}

If no webhook is configured, all fields are null:

{
"data": {
"url": null,
"secret": null,
"events": null
}
}

DELETE /v1/webhooks

Removes the webhook configuration. No more events will be delivered until a new webhook is registered.

Terminal window
curl -X DELETE https://api.getmandato.dev/v1/webhooks \
-H "Authorization: Bearer sk_test_your_key"
{
"data": {
"deleted": true
}
}

When an event occurs, Mandato sends an HTTP POST request to your webhook URL with the following format:

HeaderDescription
Content-Typeapplication/json
X-Mandato-SignatureHMAC-SHA256 signature of the request body
X-Mandato-EventEvent type (e.g., invoice.accepted)
X-Mandato-Delivery-IdUnique delivery ID for deduplication
{
"id": "evt_a1b2c3d4e5f6",
"type": "invoice.accepted",
"createdAt": "2025-01-15T10:00:15.000Z",
"data": {
"id": "inv_a1b2c3d4e5f6",
"country": "RO",
"supplierVat": "RO12345678",
"customerVat": "RO87654321",
"status": "accepted",
"netAmount": "5200.00",
"vatAmount": "988.00",
"grossAmount": "6188.00",
"currency": "RON",
"govId": "4523789012",
"externalId": "order-12345"
}
}

If your endpoint returns a non-2xx status code or times out (30-second limit), Mandato retries with exponential backoff:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry12 hours

After 5 failed retries, the delivery is marked as failed. Failed deliveries are visible in the dashboard.

Always verify the X-Mandato-Signature header before processing webhook events. See the Webhooks guide for implementation details and code examples.