Skip to main content

Managing Webhooks Programmatically via REST

Written by Danny Allen

This article will show you how to add and manage webhooks via our API.

Terminology

Sink (Integration Sink):

A destination where your system's data is sent. Think of it as a target pipeline—in this case, your webhook.

Webhook

A tool that automatically pushes real-time data directly to your server's URL the moment a specific event happens.

CRUD

An acronym for Create, Read (List), Update, and Delete. These are the four standard actions you can perform on any database record.

JSON / NDJSON

Formats used to package and exchange data. Standard JSON wraps everything into a single, structured file, while NDJSON (Newline-Delimited JSON) streams data line-by-line like a continuous feed.

Stringified / Parsing

Stringifying squashes complex, multi-line settings into a single long string of text so the database can store it easily. Parsing is the reverse process, unpacking that single line of text back into a structured, readable format.

Metadata:

The administrative "labeling" information (such as unique IDs, creation dates, or status codes) rather than the main payload of the message itself.

Normalization

The process of cleaning and rearranging data so that it is formatted consistently every time, making it much easier for your code to read.


A webhook is just a way to automatically push data to your own server whenever something happens. To set one up, the system marks it as a webhook (configType: 1) and asks you for just two main pieces of information:

  1. targetUrl: The digital mailing address (URL) where you want us to deliver the data.

  2. signingSecret: A secret digital key used to verify that the data actually came from us and hasn't been tampered with.

type WebhookConfiguration = {
targetUrl?: string;
signingSecret?: string;
};

When you save a webhook, the system stores everything in a master record. Think of this record like an administrative file folder that holds all the technical details, including:

  • classId & protocol: The internal IDs that tell the system exactly which account, tier, or product category this webhook belongs to.

  • Event subscriptions: The checklist of specific triggers you want to hear about (for example: "Tell me when a member enrols" or "Tell me when a coupon is redeemed").

  • Integration status: Whether this webhook is currently turned on, turned off, or suspended.

  • The settings text (WebhookConfiguration): A squashed line of text containing your target URL and security key, packed away neatly so the system can read it later.


CRUD Operations

To create, view, change, or delete a webhook, you use the standard actions below. You don't need to worry about manually logging in or typing out full web addresses for every single action; the system's built-in code helper automatically handles your security login passport and points your requests to the right server environment.

Here is the map of destinations for each action:

Action

Function

Endpoint

List

listIntegrationSinks(classId, protocol)

GET /integrations/sinks/list?classId=&protocol=

Create

createIntegrationSink(payload)

POST /integrations/sink

Edit

updateIntegrationSink(payload)

PUT /integrations/sink

Delete

deleteIntegrationSink(protocol, id)

DELETE /integrations/sink/{protocol}/{id}

Note on Listing: When you ask for a list of your webhooks, the system does the tidying up for you. It accepts the data in whatever format the server sends it, unpacks the squashed settings text back into readable options, and pre-sorts your webhooks into neat folders organised by type and ID so your code can find them instantly.


Payload Schema

Create Payload

When creating a webhook sink, use the following payload structure:

{ 
id: "",
classId,
protocol: "MEMBERSHIP" | "SINGLE_USE_COUPON" | "EVENT_TICKETING",
passEventId: string[], // or couponEvents/membershipEvents depending on protocol
status: 1 | 2, // 1 = disabled, 2 = active
configType: 1, // WEBHOOK configuration:
JSON.stringify({ targetUrl }),
}

Update Payload

The Update operation (PUT) reuses the exact same object structure as the Create payload, with a few distinctions:

  • It must include the existing id and the createdAt timestamp.

  • It can optionally accept a new signingSecret inside the stringified configuration object if you are explicitly rotating the secret.

Event Subscriptions by Protocol

The payload property you use to subscribe to events changes depending on the protocol chosen:

  • Pass / Membership Objects (passEventId): Uses bitflags mapped as an array of strings. Supported flags include RECORD_CREATED, INSTALLED, RECORD_UPDATED, UNINSTALLED, INVALIDATED, and RECORD_DELETED.

  • Membership-Specific (membershipEvents): Sent as an object wrapped around an IDs array ({ ids }). Supported flags are ENROLLED and UPDATED.

  • Coupon-Specific (couponEvents): Sent as an object wrapped around an IDs array ({ ids }). Supported flags are CREATED, REDEEMED, UPDATED, and DELETED.

Status Codes Reference

The IntegrationStatus field evaluates to the following integer states:

  • 0: None

  • 1: Disabled

  • 2: Active

  • 3: Suspended

Did this answer your question?