Appearance
Webhooks
Webhooks allow your application to receive real-time notifications when events occur in AbaNinja. Instead of polling the API, AbaNinja sends an HTTP POST request to your configured URL whenever a subscribed event is triggered.
Setting Up a Webhook
- Navigate to Settings > Automation > Webhooks
- Click Create Webhook
- Enter the Webhook URL — the HTTPS endpoint that will receive events
- Select the events you want to subscribe to
- Save the webhook
A signature is generated automatically for each webhook. Use this signature to verify that incoming requests are genuinely from AbaNinja.
Available Events
| Event | Description |
|---|---|
payment-received | A payment has been received for a document |
product-updated | A product has been created, updated, or deleted |
Payload Format
Every webhook request is an HTTP POST with a JSON body containing the following fields:
| Field | Type | Description |
|---|---|---|
uuid | string | Unique identifier of the webhook event |
timestamp | integer | Unix timestamp of the event |
eventType | string | The event type (e.g. payment-received) |
isTest | boolean | true if sent via the test function |
eventData | object | Event-specific data (see below) |
payment-received
json
{
"uuid": "a00fc048-ebf6-4c22-84d5-4f82c679a892",
"timestamp": 1785738594,
"eventType": "payment-received",
"isTest": true,
"eventData": {
"paymentUuid": "3afd69a2-d6b6-404a-8474-6c828c73082d",
"documentUuid": "e9ccc5dd-c6d5-4ac9-bc68-600be9360544",
"documentType": "invoice",
"balance": 801.35
}
}| Field | Type | Description |
|---|---|---|
eventData.paymentUuid | string | UUID of the payment |
eventData.documentUuid | string | UUID of the related document |
eventData.documentType | string | Type of document (e.g. invoice) |
eventData.balance | number | Remaining balance after the payment |
product-updated
json
{
"uuid": "e3f7c4c0-80c1-4542-807e-f89298fb7cde",
"timestamp": 1785738814,
"eventType": "product-updated",
"isTest": true,
"eventData": {
"paymentUuid": "64cf4681-0e7a-491a-8d44-807482dc1631",
"modificationType": "DELETED"
}
}| Field | Type | Description |
|---|---|---|
eventData.paymentUuid | string | UUID of the product |
eventData.modificationType | string | One of CREATED, UPDATED, or DELETED |
Verifying the Signature
Every webhook request includes the x-abaninja-signature-sha256 header. This is an HMAC-SHA256 hash of the request body, signed with your webhook's secret signature.
Always verify this header to ensure the request originates from AbaNinja:
javascript
import crypto from 'crypto';
function verifyWebhookSignature(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler
const signature = req.headers['x-abaninja-signature-sha256'];
const isValid = verifyWebhookSignature(req.rawBody, signature, YOUR_WEBHOOK_SECRET);
if (!isValid) {
return res.status(401).send('Invalid signature');
}WARNING
Always use a timing-safe comparison to prevent timing attacks when verifying signatures.
Testing Webhooks
You can send test events directly from the webhook configuration page:
- Open your webhook in Settings > Automation > Webhooks
- In the Test Webhook section, select an event from the dropdown
- Click Send
Test events have isTest: true in the payload.
Delivery History
Each webhook has a delivery history that shows past events with their status:
- Timestamp of each delivery attempt
- Response code returned by your endpoint
- Response body from your endpoint
Navigate to your webhook and click on an event entry to view the delivery details.
Best Practices
- Always verify the
x-abaninja-signature-sha256header - Respond with a
2xxstatus code within a reasonable time to acknowledge receipt - Process webhook payloads asynchronously if your handling logic is complex
- Use the
uuidfield to deduplicate events in case of retries - Use the
isTestflag to distinguish test events from production events