Funnel Webhooks
Send webhook postbacks to external systems when funnel events occur.
OptiPub can send webhook postbacks to external URLs when funnel events fire. This lets you notify third-party systems — such as CRMs, analytics platforms, or custom backends — in real time when subscribers take actions like signing up, opening an email, or clicking a link.
Webhooks are sent using the Make Post Request to Url funnel action. It can send either a GET or a POST request, and you can either send OptiPub's default JSON payload (subscription, subscriber, and event data) or supply your own custom request body. URLs and request bodies support macros so you can inject subscriber-specific values like email address or ESP variables.
Setting Up a Funnel Webhook
Step 1. Create or edit a funnel.
Open an existing funnel or create a new one in Marketing > Funnels.
Step 2. Add a trigger event.
Choose the funnel event that should trigger the webhook (e.g., New Subscription, Email Opened, Email Clicked). Click the + button on the event grid to add one.
Step 3. Add the "Make Post Request to Url" action.
Click the + button under your trigger event and select Make Post Request to Url from the action list.
Step 4. Configure the request.
| Field | Description |
|---|---|
| Name | Internal label for the action (not visible to subscribers). |
| Only once | When enabled, the action fires only once per subscriber for this funnel. Useful for avoiding duplicate notifications. |
| URL | The full endpoint URL including https://. This is where OptiPub sends the request. Supports macros. |
| Method | The HTTP method to use: GET or POST. Defaults to POST. |
| Body encoding (POST only) | How the request body is encoded: JSON (Content-Type: application/json) or Form (URL-encoded) (application/x-www-form-urlencoded, like a typical HTML form post). Defaults to JSON. |
| Custom body (POST only) | An optional custom request body. Leave blank to send OptiPub's default payload. See Customizing the request body. |
| Send Only If Active | When enabled, the request only fires if the subscription is still active. |
GET requests send no body. When Method is set to GET, the body encoding and custom body fields are hidden. To pass data on a GET request, include it as query-string parameters in the URL using macros (see below).
Step 5. Set the timing.
Choose when the webhook should fire after the trigger event:
| Option | Behavior |
|---|---|
| Immediately | Fires as soon as the event occurs. |
| Specific Day / Time | Fires on a specific day and time after the event. |
| Delayed | Fires after a set delay (e.g., 30 minutes, 2 hours). |
| Delayed at a Specific Time | Fires after a set number of days, at a specific time. |

Timing options for the webhook action.
Step 6. Save.
Click OK to add the action, then Save the funnel.
Webhook Payload
When a POST request fires without a custom body, OptiPub sends this default JSON payload to the configured URL. It includes the full subscription, subscriber (with emails and ESP variables), and event context. To send your own body instead, see Customizing the request body.
{
"id": 715462777,
"active": true,
"email_id": 10048162,
"publication_id": 7,
"subscriber_id": 57343261,
"started_at": "2024-10-17 16:11:50",
"ended_at": null,
"deleted_at": null,
"created_at": "2024-10-17T16:11:50.000000Z",
"updated_at": "2024-10-17T16:11:50.000000Z",
"publication": {
"id": 7,
"name": "OptiPub Daily",
"active": true,
"code": "opd"
},
"subscriber": {
"id": 57343261,
"created_at": "2024-10-17T16:11:50.000000Z",
"updated_at": "2024-10-17T16:11:50.000000Z",
"emails": [
{
"id": 10048162,
"email": "[email protected]",
"md5": "01f6ea24e7137bd99a7b73436fd7ef30",
"variables": [
{ "id": 1002021, "name": "phone", "value": "5554445949" },
{ "id": 1002703, "name": "first_name", "value": "John" },
{ "id": 1002707, "name": "last_name", "value": "Doe" }
]
}
]
},
"email": {
"id": 10048162,
"email": "[email protected]",
"md5": "01f6ea24e7137bd99a7b73436fd7ef30"
},
"event": {
"event": "NewSubscription",
"data": {
"ip": "17.30.57.47",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"effort_id": "809502",
"variables": [
{ "name": "first_name", "value": "John" },
{ "name": "last_name", "value": "Doe" },
{ "name": "phone", "value": "5554445949" }
]
}
},
"subscription": {
"id": 715462777,
"active": true,
"email_id": 10048162,
"publication_id": 7,
"subscriber_id": 57343261,
"started_at": "2024-10-17 16:11:50"
}
}The payload above is condensed for readability. The actual payload includes additional fields on the
subscription,subscriber, and nested objects.
Macros
Both the URL and a custom request body support macros — placeholders that OptiPub replaces with subscriber-specific values when the request fires. Macros use the format {$name} and are case-insensitive.
| Macro | Value |
|---|---|
{$email} | The subscriber's email address for this subscription. |
{$email_md5} | The MD5 hash of that email address. |
{$ip_address} | The IP address from the triggering event, when available. |
{$user_agent} | The user agent from the triggering event, when available. |
{$effort_id} | The effort ID from the triggering event, when available. |
{$esp_<name>} | Any ESP variable stored on the email, by variable name — e.g. {$esp_first_name}, {$esp_phone}. |
Where macros work:
- In the URL — values are automatically URL-encoded, so macros are safe to use in query-string parameters (e.g.
https://example.com/hook?email={$email}). This is the primary way to pass data on GET requests. - In a custom body — macros are substituted inside string values (not keys). Values are inserted as-is (not URL-encoded).
Customizing the Request Body
For POST requests, you can replace the default payload with your own body by filling in the Custom body field. Leave it blank to send the default payload.
Enter a valid JSON object. If the body is empty or is not valid JSON, OptiPub falls back to the default payload.
The Body encoding setting controls how the body is sent:
| Encoding | Content-Type | Behavior |
|---|---|---|
| JSON | application/json | The JSON object is sent as the raw request body. |
| Form (URL-encoded) | application/x-www-form-urlencoded | Enter a JSON object of field names to values; OptiPub sends it as URL-encoded form fields. With the default payload, nested keys use bracket notation. |
Example — custom JSON body with macros:
{
"email": "{$email}",
"first_name": "{$esp_first_name}",
"source": "optipub",
"effort": "{$effort_id}"
}Custom headers, authentication, and HTTP methods other than GET/POST are not currently supported.
Common Use Cases
| Use Case | Example |
|---|---|
| CRM sync | POST new subscriber data to your CRM when they sign up. |
| Analytics tracking | Notify your analytics platform when subscribers open or click. |
| Partner postbacks | Fire a conversion postback to an affiliate or ad network. |
| Slack/Teams alerts | Send a notification to a webhook URL when a high-value event occurs. |
| Custom workflows | Trigger downstream automation in Zapier, Make, or a custom API. |
Updated 6 days ago

