Skip to main content

Webhook Events Reference

This page lists every event you can subscribe to, grouped by the entity that changed, with an example delivery for each payload shape.

For the delivery envelope format, property scoping, and signature verification, see Webhooks Overview.

Payload Shape

The envelope is the same for every event. Only data changes:

{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"event": "audience_member.created",
"created_at": "2026-08-12T14:32:00+00:00",
"property": "magazine",
"data": { ... }
}

For every event except ping, data is a single JSON:API resource object:

KeyDescription
idThe record's identifier.
typeThe resource type, fixed per event group (for example audience_members).
attributesThe record's fields. This is the part that differs between the shapes documented below.
metaPresent only where noted below. Carries information about the record rather than its content.

Events that share a shape share an example. All twenty-three subscribable events resolve to one of eight shapes, plus ping.

Two timestamp formats appear in payloads

The envelope's created_at, and any field the platform explicitly formats (entitlement started_at and ended_at, and the ping's created_at), use an offset — 2026-08-12T14:32:00+00:00. Record timestamps inside attributes use the microsecond form — 2026-08-12T14:32:00.000000Z. Both are UTC and both parse as ISO 8601; parse them, don't string-compare them.

Treat unrecognized keys as optional

Payloads are additive. A future release can add attributes, and data may carry extra top-level keys such as relationships depending on how the record was loaded when the event fired. Read the keys you need and ignore the rest.

Audience Member

These events fire when an audience member record is created, updated, or deleted.

EventTrigger
audience_member.createdFired when a new audience member is created.
audience_member.updatedFired when an audience member is updated (excludes activity-only changes).
audience_member.deletedFired when an audience member is deleted.
note

audience_member.updated is not fired for activity-only changes such as last_active_at updates. It fires only when meaningful profile data changes.

meta inside attributes holds the member's raw meta values, keyed by meta key and sorted alphabetically. Every value is a string, including numbers and booleans. For the tenant-defined subset of these values, subscribe to the user attribute events instead.

{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"event": "audience_member.created",
"created_at": "2026-08-12T14:32:00+00:00",
"property": "magazine",
"data": {
"id": "9d5c1f2a-8b3e-4a17-9f6d-2c4b8e1a7d30",
"type": "audience_members",
"attributes": {
"name": "Jane Doe",
"email": "[email protected]",
"email_verified": true,
"meta": {
"newsletter_opt_in": "1",
"postal_code": "90210"
},
"created_at": "2026-08-12T14:32:00.000000Z",
"updated_at": "2026-08-12T14:32:00.000000Z"
}
}
}

External Profile

External profiles store data from third-party providers (such as a CRM or identity provider) attached to a member.

EventTrigger
audience_member.external_profile.createdFired when an external profile is added to a member.
audience_member.external_profile.updatedFired when an external profile is updated.
audience_member.external_profile.deletedFired when an external profile is removed.

attributes is the provider's stored payload verbatim, so its keys are whatever that provider supplies — the example below is illustrative, not a schema. Record timestamps are under meta rather than attributes, because attributes is entirely provider-controlled.

For the same reason, neither the member nor the provider name is in the payload: data.id identifies the profile row, so key your records on it. If you need the member, subscribe to the user attribute events as well — any user attribute configured to read from this provider is re-synced when the profile changes, and those events do carry audience_member_id.

{
"id": "b9f1c7d2-4a8e-4b03-9c15-6d2e8f3a1b47",
"event": "audience_member.external_profile.updated",
"created_at": "2026-08-12T14:35:12+00:00",
"property": "magazine",
"data": {
"id": "3f1b9c04-6d2e-4c8a-b5f7-1a9e3d7c2b48",
"type": "audience_member_external_profiles",
"attributes": {
"contact_id": "C-0031982",
"membership_level": "sustainer",
"lifetime_giving": 240,
"tags": ["donor", "event-attendee"]
},
"meta": {
"created_at": "2026-07-02T09:14:05.000000Z",
"updated_at": "2026-08-12T14:35:12.000000Z"
}
}
}

Foreign Key

Foreign keys link an audience member to an identifier in an external system (for example, a CRM contact ID or a subscriber ID in your publishing platform).

EventTrigger
audience_member.foreign_key.createdFired when a foreign key is attached to a member.
audience_member.foreign_key.updatedFired when a foreign key is updated.
audience_member.foreign_key.deletedFired when a foreign key is removed.

The payload carries the key and value pair but not the member it belongs to, so key your records on data.id.

{
"id": "c1d4e8a2-7b39-4f65-8a02-3e9c5b1d7f84",
"event": "audience_member.foreign_key.created",
"created_at": "2026-08-12T14:36:40+00:00",
"property": "magazine",
"data": {
"id": "7e2a5c81-9d34-4b6f-a017-8c3e2f9b5d60",
"type": "audience_member_foreign_keys",
"attributes": {
"key": "contact_id",
"value": "C-0031982",
"created_at": "2026-08-12T14:36:40.000000Z",
"updated_at": "2026-08-12T14:36:40.000000Z"
}
}
}

User Attribute

User attributes are the tenant-defined profile fields configured in the admin. These events fire only for keys defined in the tenant's user attribute registry — internal and unmapped member meta keys are ignored.

EventTrigger
audience_member.user_attribute.createdFired when a user attribute value is set on a member for the first time.
audience_member.user_attribute.updatedFired when a user attribute value changes.
audience_member.user_attribute.deletedFired when a user attribute value is removed from a member.

slug is the attribute's slug from the registry, and value is always a string regardless of the attribute's configured type. Unlike every other shape on this page, id is a numeric string rather than a UUID — it identifies the stored value, not the attribute definition, so key your own records on audience_member_id plus slug.

{
"id": "a48f2d19-6c05-4e73-b8d1-9f27a3e5c064",
"event": "audience_member.user_attribute.updated",
"created_at": "2026-08-12T14:38:02+00:00",
"property": "magazine",
"data": {
"id": "1842",
"type": "audience_member_user_attributes",
"attributes": {
"audience_member_id": "9d5c1f2a-8b3e-4a17-9f6d-2c4b8e1a7d30",
"slug": "newsletter_opt_in",
"value": "1"
}
}
}

Entitlement

Entitlement events fire when a member's access to a product changes.

EventTrigger
entitlement.createdFired when an entitlement is granted.
entitlement.updatedFired when an entitlement is updated.
entitlement.deletedFired when an entitlement is deleted.

is_active is computed from started_at and ended_at at the moment the event fired: an entitlement is active once started_at has passed and until ended_at does. A null ended_at means indefinite access. Revoking an entitlement sets ended_at and fires entitlement.updated, not entitlement.deleted.

The entitlement's id is repeated inside attributes as well as at the top of data. The member and the product are not in the payload — key your records on the entitlement id, and read the member and product from the API when you need them.

{
"id": "d7c93b15-2e48-4a06-91f5-7b3c8d2e6a19",
"event": "entitlement.created",
"created_at": "2026-08-12T14:40:18+00:00",
"property": "magazine",
"data": {
"id": "c8e40a72-5d16-4f39-8b2c-1e7a9d4f3b05",
"type": "entitlements",
"attributes": {
"id": "c8e40a72-5d16-4f39-8b2c-1e7a9d4f3b05",
"started_at": "2026-08-12T00:00:00+00:00",
"ended_at": null,
"note": "Granted by support",
"is_active": true,
"created_at": "2026-08-12T14:40:18.000000Z",
"updated_at": "2026-08-12T14:40:18.000000Z"
}
}
}

Purchase

Purchase events fire when a member's purchase is created or changes (for example, a refund). Purchases are not hard-deleted, so there is no purchase.deleted event.

EventTrigger
purchase.createdFired when a purchase is created.
purchase.updatedFired when a purchase is updated (for example, refunded).

status is one of pending, completed, failed, or refunded. amount is an integer in the currency's smallest unit — 999 with a currency of usd means $9.99. The provider_* fields are the payment provider's own identifiers.

A purchase is created as pending, and an anonymous checkout is created with a null audience_member_id and entitlement_id; both are filled in when the payment is fulfilled. Expect every purchase.created to be followed by a purchase.updated that carries the settled record.

{
"id": "e2a6f483-9c71-4d50-b8e3-4f1a7c9d2b60",
"event": "purchase.updated",
"created_at": "2026-08-12T14:42:55+00:00",
"property": "magazine",
"data": {
"id": "7a1e5b39-4c82-4067-9d1f-3b8e2a6c5d40",
"type": "purchase_webhooks",
"attributes": {
"id": "7a1e5b39-4c82-4067-9d1f-3b8e2a6c5d40",
"audience_member_id": "9d5c1f2a-8b3e-4a17-9f6d-2c4b8e1a7d30",
"device_session_id": "5b2f8c14-7a63-4e09-8d25-1f9c3b7a2e58",
"plan_id": "e91d4a07-3b56-4c82-9f14-6d2e8a5c1b73",
"entitlement_id": "c8e40a72-5d16-4f39-8b2c-1e7a9d4f3b05",
"provider": "stripe",
"provider_session_id": "cs_test_a1b2c3d4e5f6",
"provider_payment_id": "pi_3Q1a2b3c4d5e6f7g",
"provider_refund_id": null,
"status": "completed",
"amount": 999,
"currency": "usd",
"metadata": null,
"return_url": "https://acme.com/thank-you",
"created_at": "2026-08-12T14:41:03.000000Z",
"updated_at": "2026-08-12T14:42:55.000000Z"
}
}
}

Interaction

Interaction events fire when an interaction is created, updated, or deleted.

EventTrigger
interaction.createdFired when an interaction is created.
interaction.updatedFired when an interaction is updated.
interaction.deletedFired when an interaction is deleted.

status is draft or published. actions is the interaction's ordered action list; every entry has a type, and the remaining keys depend on it. Interactions are soft-deleted, so interaction.deleted carries the record with deleted_at set rather than omitting it.

{
"id": "f5b81e27-6a94-4c13-8d70-2e9f4a1c6b38",
"event": "interaction.updated",
"created_at": "2026-08-12T14:45:20+00:00",
"property": null,
"data": {
"id": "2c9e7f14-8b05-4a63-91d8-5f3a2e7c4b19",
"type": "interaction_webhooks",
"attributes": {
"id": "2c9e7f14-8b05-4a63-91d8-5f3a2e7c4b19",
"title": "Sustainer Upsell",
"slug": "sustainer-upsell",
"status": "published",
"actions": [
{
"type": "template",
"template_id": "8d1f4a92-3c67-4b05-a2e8-7f9c1d5b3a26",
"target_selector": "#article-body",
"field_values": [
{
"slug": "headline",
"value": "Support independent reporting"
}
],
"placement_method": "before",
"truncation_unit": null,
"truncation_count": null,
"truncation_style": null,
"delay_type": null,
"delay_value": null,
"delay_scroll_unit": null,
"delay_scroll_selector": null
}
],
"created_at": "2026-08-01T10:02:44.000000Z",
"updated_at": "2026-08-12T14:45:20.000000Z",
"deleted_at": null
}
}
}

Template

Template events fire when a template is created, updated, or deleted.

EventTrigger
template.createdFired when a template is created.
template.updatedFired when a template is updated.
template.deletedFired when a template is deleted.

The payload includes the template's full html, js, and css bodies, so template deliveries are the largest ones Allegro sends. fields describes the template's field definitions, and the sync_source and github_* fields are populated only for templates kept in sync with a Git repository. Templates are soft-deleted, so template.deleted carries the record with deleted_at set.

{
"id": "0a3d9c76-4e18-4b52-8f01-6c7a2e9d5b34",
"event": "template.updated",
"created_at": "2026-08-12T14:48:07+00:00",
"property": null,
"data": {
"id": "8d1f4a92-3c67-4b05-a2e8-7f9c1d5b3a26",
"type": "template_webhooks",
"attributes": {
"id": "8d1f4a92-3c67-4b05-a2e8-7f9c1d5b3a26",
"title": "Sustainer Banner",
"slug": "sustainer-banner",
"status": "published",
"html": "<div class=\"banner\"><h2>{{ headline }}</h2></div>",
"js": "",
"css": ".banner { padding: 1rem; }",
"fields": [
{
"slug": "headline",
"description": "Banner headline",
"type": "text"
}
],
"external_css_urls": [],
"created_at": "2026-07-28T16:20:11.000000Z",
"updated_at": "2026-08-12T14:48:07.000000Z",
"deleted_at": null,
"sync_source": "github",
"github_path": "templates/sustainer-banner.html",
"github_sha": "9f2c1d7e8a3b4c5d6e7f8091a2b3c4d5e6f70819",
"github_commit_sha": "1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d",
"synced_at": "2026-08-12T14:48:07.000000Z"
}
}
}

System

EventTrigger
pingA test event sent when an active webhook is created.

ping is not subscribable — it is sent automatically and cannot be selected when configuring event subscriptions.

The ping is the one delivery whose data is not a JSON:API resource object. It echoes the webhook's own id, subscribed events, and created_at. Pings ignore property scoping and, because webhooks are created from the organization dashboard, normally carry property: null.

{
"id": "6d0f8a13-2b47-4e95-8c26-1a3f7d9b5e02",
"event": "ping",
"created_at": "2026-08-12T14:30:00+00:00",
"property": null,
"data": {
"id": "4b7e1c29-8d53-4a06-9f18-2e6c5b3a7d94",
"events": ["audience_member.created", "entitlement.created"],
"created_at": "2026-08-12T14:29:58+00:00"
}
}

Adding New Events

The subscribable event list is generated from the event registry in the platform. New event types registered there become immediately available in the webhook subscription UI and in this reference.

  • Webhooks Overview — creating webhooks, property scoping, delivery envelope, signature verification, and retries
  • Properties — property hosts and the request context that populates the envelope's property field
  • Entitlements — how entitlements and products work
  • Audience Members — member profiles and data