Automation platforms
Turn a Hypeline change event into a trigger on Inngest, Zapier, Make, and Trigger.dev. A signed webhook destination is all any automation platform needs to run when a watched page changes.
A change event should be the thing that wakes an automation. Hypeline delivers every matched event as a signed HTTP POST, and any platform that can receive one becomes a trigger: "a watched page changed" runs your workflow, with the signature verified so you can trust the delivery. This group has a copy-paste recipe for each platform, built on one mental model.
The mental model
You create an alert (what to watch plus a filter), then add a webhook destination to it. Every event that alert matches is delivered to the destination as a signed POST. The destination URL is the automation platform's inbound webhook URL, so the platform receives the event directly. Nothing about the wire payload changes per platform: each recipe consumes the same signed body.
watched source changes -> alert matches -> signed POST to your platform's webhook URL -> your workflow runsRegister a destination once, per platform, using the same alert API the webhook delivery page documents:
# 1. Create an alert (or reuse one). source_ids empty = your whole library.
curl -X POST https://api.hypeline.io/v1/alerts \
-H "Authorization: Bearer $YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filter_query":"outage","language":"en","source_ids":[]}'
# 2. Add a webhook destination whose url is the platform's inbound webhook URL.
# delivery_mode instant is the shape every recipe here assumes.
curl -X POST https://api.hypeline.io/v1/alerts/{alert_id}/destinations \
-H "Authorization: Bearer $YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"kind":"webhook","url":"https://hooks.example-platform.com/abc123","delivery_mode":"instant"}'The create response reveals the whsec_ signing secret EXACTLY once. Store it: it is what your recipe uses to verify each delivery.
Destinations need a public HTTPS URL
Registration validates the destination URL and rejects private, loopback, and link-local addresses (SSRF protection on user-supplied URLs). A self-hosted automation platform on a LAN or localhost URL cannot be registered directly. Use a hosted platform, or expose your instance through a public HTTPS tunnel.
The delivered body
An instant webhook delivery carries a single StreamEvent as the raw JSON body. Its id is a UUIDv7 and doubles as the webhook-id header and your dedup key. The fields every recipe maps from:
| Field | Meaning |
|---|---|
id | Event UUIDv7. Same value as webhook-id. Your idempotency anchor. |
source_id | Stable UUID of the source that changed. |
source_type | The source tier: push, feed, or html. |
url | The URL of the new or changed content. |
title | Title of the content, when available. |
content | Extracted main content (capped). |
diff / delta | Structured change on an HTML change event (present only there). |
tags | The event's tags, for example topic:test, region:se. |
emitted_at | When the event was emitted (RFC 3339, UTC). |
signature / key_id / signed_at | The Ed25519 content signature (see below). |
alert_type | Set only on an engine alert notification (for example source_quiet); absent on a normal match. |
The full schema is in the API reference.
Recipes pin instant delivery
Every recipe here assumes delivery_mode: "instant", one event per POST. A digest destination (15min, hourly, or daily) posts a different wire shape: a batch wrapper with a destination_id and an events array. That shape is out of scope for these recipes; pin instant when you register the destination.
Two trust layers
Every delivery carries two independent signatures, and the recipes use whichever the platform makes easy:
| Layer | What it proves | How to verify |
|---|---|---|
| Standard Webhooks HMAC | This exact POST reached you intact and is not a replay. | HMAC-SHA256 over the raw body with the whsec_ secret. Needs the unparsed body bytes. |
| Event Ed25519 signature | The event content is authentic Hypeline, on any transport. | Public-key check over the canonical event. Survives a platform re-serializing the JSON. |
The HMAC secures a single delivery, so it needs the raw request bytes. Some platforms parse the body before your code sees it, which makes the HMAC impossible to recompute there. The Ed25519 signature is attached to the event content and verified against a JCS-canonicalized copy, so it holds even after a platform re-encodes the JSON. That property is what the Inngest and Trigger.dev recipes lean on. See verifying events for the full Ed25519 recipe.
The signing headers
Each POST carries three headers. webhook-id is the same UUIDv7 as the event id, so it is both your signature input and your dedup key:
| Header | Value |
|---|---|
webhook-id | The event UUID (also your idempotency / dedup key). |
webhook-timestamp | Unix-seconds time the delivery was signed. |
webhook-signature | One or more space-delimited v1,<base64> tokens. |
Dedup on the event id
Delivery is at-least-once, so the same event can arrive more than once. Every recipe dedups on the event id (the webhook-id): n8n static data, an Inngest event id, a Trigger.dev idempotencyKey, or a Zapier Storage check. Treat a repeated id as already handled.
Try it before you wire a platform
Prove the loop end to end before pointing a real workflow at it:
- Register a destination, then fire a real sample delivery with
POST /v1/destinations/{id}/test. The signed sample is byte-identical to a live delivery, which is exactly what Make's "determine data structure" step needs. - Point the destination at a webhook bin (
POST /v1/webhook-binsmints a capture URL;GET /v1/webhook-bins/{id}/capturesshows what arrived) to inspect headers and body without leaving Hypeline. - Or run the bundled
whreceivercommand locally: it prints each delivery and whether the signature verified.
Pick your platform
- Inngest: a transform turns the
POSTinto an Inngest event; durable functions subscribe by name. - Zapier and Make: Catch Hook (fast) or Catch Raw Hook plus a verifier step (Zapier), and a custom webhook module (Make).
- Trigger.dev: a route in your own code verifies with the
standardwebhookslibrary and callstasks.trigger().