A webhook sends each new subscriber and each form message to an address you choose, a few seconds after it happens. Use it to put subscribers into your newsletter tool, form messages into a spreadsheet or a CRM, or anything else that takes a web request. Webhooks are part of pageo Pro.
Add a webhook
- In your pageo admin, open Settings.
- Under Webhook, paste your endpoint URL and click Add webhook. The address must start with
https://. - Click Send test event. Your endpoint gets a
pingevent, and the result shows under Recent deliveries.
With Zapier, Make, or n8n, start a new automation with their "Catch hook" or "Webhook" trigger and paste the URL it gives you.
Events
| Event | Sent when |
|---|---|
subscriber.created | A visitor confirms their subscription to your updates |
form.submitted | A visitor sends your contact form or a custom form |
ping | You click Send test event |
The request
pageo sends a POST with a JSON body and these headers:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Pageo-Event | The event name, for example form.submitted |
X-Pageo-Delivery | The event id, the same as id in the body. Use it to skip an event you already handled |
X-Pageo-Signature | t=<unix seconds>,v1=<hex signature>. See Check the signature |
Every body has the same envelope:
{
"id": "evt_6f1c2b9e-3a4d-4c1e-9b7a-2f0d8e5c1a34",
"type": "subscriber.created",
"created_at": "2026-10-17T09:30:00.000Z",
"data": {}
}
subscriber.created
{
"email": "sam@example.com",
"name": "Sam",
"subscribed_at": "2026-10-17T09:30:00.000Z",
"page": { "username": "yourname", "url": "https://www.pageo.me/yourname" }
}
name is null when the subscriber did not give one.
form.submitted
{
"submission_id": "3c9a0e1f-7b2d-4f6a-8e5c-1d0b9a7f2e64",
"form": { "id": "8b2f4c1e-6d3a-4e9b-a7c5-0f1e2d3c4b5a", "title": "Contact" },
"name": "Sam",
"email": "sam@example.com",
"fields": [
{ "label": "Message", "value": "Are you free for a shoot next month?" }
],
"submitted_at": "2026-10-17T09:30:00.000Z",
"source": null,
"service": null,
"page": { "username": "yourname", "url": "https://www.pageo.me/yourname" }
}
fields holds every field the visitor filled in, in the order of the form. A request from your work page has source set to "work" and service set to the service the visitor picked, or null when they picked none.
Check the signature
Each webhook has a signing secret that starts with whsec_. Copy it from Settings, then Webhook. Check the signature before you trust a request, so that only pageo can send events to your endpoint.
The signature is an HMAC-SHA256 of <t>.<raw body>, keyed with your secret, written as hex. Use the raw body exactly as it arrived, before you parse the JSON.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyPageoSignature(secret, header, rawBody) {
const parts = Object.fromEntries(header.split(",").map((part) => part.split("=")));
const timestamp = Number(parts.t);
// reject requests older than five minutes, so an old request cannot be sent again
if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const expected = createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
const received = Buffer.from(parts.v1 ?? "", "hex");
return received.length === 32 && timingSafeEqual(received, Buffer.from(expected, "hex"));
}
When you replace the secret in Settings, the old one stops working at once. Update your endpoint with the new secret.
Retries and timeouts
- Answer with any
2xxstatus to mark the event as delivered. pageo does not read the response body. - pageo waits up to 5 seconds for an answer.
- When the request fails, times out, or gets a
429or a5xx, pageo tries again after 1 second and again after 4 more seconds. A4xxother than429is not retried. - pageo does not follow redirects. Use the final address of your endpoint.
- Events can arrive more than once, and not always in order. Use
X-Pageo-Deliveryto skip duplicates.
Recent deliveries in Settings shows the last 20 deliveries from the past 7 days, with the status code or the error. pageo does not keep a copy of the payloads.
Turn off a webhook
In Settings, under Webhook, click Remove. If your Pro plan ends, pageo stops sending events until you upgrade again. Your URL and secret stay saved.