Webhooks
Webhooks let your systems react to events in Allegro in real time. When
something happens — a new audience member joins, an entitlement is granted, a
foreign key is attached — Allegro sends an HTTP POST request to a URL you
control. You don't need to poll the API; Allegro pushes changes to you.
Creating a Webhook
- Go to Organization Settings → Developer → Webhooks.
- Click Add Webhook.
- Enter the Endpoint URL — the HTTPS URL on your server that will receive deliveries.
- Enter a Description to help you identify the webhook later.
- Choose which Events to subscribe to. You can subscribe to individual events or to all events.
- Click Create. Allegro immediately sends a ping event to your endpoint to confirm it is reachable.
Each organization can have up to 5 webhooks. If you need more, delete an existing one first.
Activating and Deactivating
Every webhook has an Active toggle. Deactivating a webhook suspends deliveries without deleting the webhook or its delivery history. Reactivate it at any time to resume.
Delivery Payload
Every delivery is an HTTP POST with a JSON body in the following envelope
format:
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"event": "audience_member.created",
"created_at": "2024-10-15T14:32:00Z",
"data": { ... }
}
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the event (UUID). Matches the X-Allegro-Event-Id header. |
event | string | The event type (e.g. audience_member.created). |
created_at | string | ISO 8601 timestamp of when the event occurred. |
data | object | The resource representation of the entity that changed. Shape varies by event — see Events Reference. |
Request Headers
Every delivery includes the following HTTP headers:
| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | Allegro-Webhooks |
X-Allegro-Event | The event type (e.g. audience_member.created). |
X-Allegro-Event-Id | The UUID of the event that triggered this delivery. |
X-Allegro-Delivery | Identifier for the delivery record. Stays the same across retries and manual redeliveries of that delivery. |
X-Allegro-Signature-256 | An HMAC-SHA256 signature of the request body (see below). |
Signature Verification
Allegro signs every delivery using HMAC-SHA256. The signature is sent in the
X-Allegro-Signature-256 header in the format sha256=<hex-digest>.
The signature is computed over the raw request body using your webhook's signing secret as the key.
Verify the signature before processing any webhook payload. Without verification, your endpoint could accept forged requests from anyone on the internet.
Finding Your Signing Secret
Open the webhook detail page (Organization Settings → Developer → Webhooks → your webhook). The signing secret is displayed there. Treat it like a password — do not commit it to source control.
PHP Example
function verifyAllegroSignature(string $rawBody, string $secret, ?string $signatureHeader): bool
{
// Header format: "sha256=<hex-digest>". Reject a missing or malformed header.
if ($signatureHeader === null || !str_starts_with($signatureHeader, 'sha256=')) {
return false;
}
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
return hash_equals($expected, $signatureHeader);
}
// Usage (e.g. in a Laravel controller):
$rawBody = $request->getContent();
$signature = $request->header('X-Allegro-Signature-256');
if (!verifyAllegroSignature($rawBody, config('services.allegro.webhook_secret'), $signature)) {
abort(401, 'Invalid signature');
}
Node.js Example
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyAllegroSignature(rawBody, secret, signatureHeader) {
if (!signatureHeader?.startsWith('sha256=')) return false;
const expected =
'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
const actual = Buffer.from(signatureHeader);
const expectedBuf = Buffer.from(expected);
if (actual.length !== expectedBuf.length) return false;
return timingSafeEqual(actual, expectedBuf);
}
// Usage (e.g. in an Express handler):
const rawBody = req.rawBody; // requires bodyParser with verify option
const signature = req.headers['x-allegro-signature-256'];
if (
!verifyAllegroSignature(
rawBody,
process.env.ALLEGRO_WEBHOOK_SECRET,
signature,
)
) {
return res.status(401).send('Invalid signature');
}
Use a constant-time comparison (hash_equals in PHP, timingSafeEqual in
Node.js) to prevent timing attacks.
Retries
When a delivery fails — your endpoint returns a non-2xx status code or does not respond within 10 seconds — Allegro retries automatically:
| Attempt | Delay after previous attempt |
|---|---|
| Initial | Immediate |
| Retry 1 | 60 seconds |
| Retry 2 | 300 seconds (5 minutes) |
After 3 total attempts (the initial delivery plus 2 retries), the delivery is marked Failed and no further retries occur. The webhook itself remains active and continues to receive future events.
Respond to deliveries as quickly as possible. If processing takes time, accept
the delivery immediately (return 200 OK) and handle it in a background job.
Viewing and Managing Deliveries
Open a webhook from Organization Settings → Developer → Webhooks to see its recent deliveries. Deliveries are kept for 180 days.
Each delivery record shows:
- The event type and delivery timestamp
- HTTP response status returned by your endpoint
- The full request payload and response body
Redelivery
You can manually redeliver any past delivery from the delivery detail view. This is useful for replaying events after you fix a bug in your endpoint or if your server was temporarily unavailable.
Ping
When you create an active webhook, Allegro sends a ping event to your endpoint
to verify that it is reachable. The ping's data payload echoes the webhook's
id, subscribed events, and created_at timestamp. Webhooks created inactive
are not pinged.
Related
- Events Reference — full list of subscribable events and their payload shapes
- Settings — how to access Organization Settings