Webhooks
Send events and alerts from My Journey Analytics to your own systems as HTTP requests, and verify that they came from us.
A webhook sends an HTTP request to an address you choose when something happens in My Journey Analytics. Use webhooks to feed events into your own backend, trigger workflows, or notify tools we do not connect to directly.
There are two ways to send webhooks:
| Use | Sends a request when | Set it up in |
|---|---|---|
| HTTP Webhook destination | A matching event is captured | Destinations |
| Alert notification | An insight alert fires | The insight's alerts |
To post to Slack instead, see Slack.
Send events to a webhook
- Open Destinations from the navigation and choose New destination.
- Pick HTTP Webhook.
- Enter the Webhook URL and choose the Method (
POSTby default). - Under the trigger, choose which events should send a request, and add any filters.
- Adjust the JSON Body and Headers if you need to.
- Save and enable the destination.
From then on, every matching event sends one request, as it arrives.
The request body
By default the body contains the whole event and person:
{
"event": "{event}",
"person": "{person}"
}Values in curly brackets are filled in from the event. You can pick out exactly the fields you need:
{
"name": "{event.event}",
"user": "{event.distinct_id}",
"url": "{event.properties.$current_url}",
"email": "{person.properties.email}",
"time": "{event.timestamp}"
}The main values available are:
| Value | Contains |
|---|---|
event.uuid, event.event, event.distinct_id, event.timestamp | The event's ID, name, distinct ID and time |
event.properties | The event's properties |
event.url | A link to the event in the app |
person.properties | The person's properties |
project.id, project.name | The project the event belongs to |
Test before you enable
Once the destination is created, use Start testing and Test function to send a sample event and see the request and your server's response. Each real request is logged on the destination's Invocations tab, and Metrics shows how many succeeded or failed.
Failures and retries
Your server should answer with a 2xx status quickly. A request that fails with a status of 400 or above, or gets no response, counts as a failure. Failures that are worth retrying are tried again after a delay, and each attempt appears on the Invocations tab.
Verify webhook signatures
To prove a request came from My Journey Analytics, give the destination a Signing secret. Requests are then signed following the Standard Webhooks specification, with three extra headers:
| Header | Contains |
|---|---|
webhook-id | A unique ID for the message. It stays the same when a request is retried |
webhook-timestamp | When it was sent, in seconds since 1970 |
webhook-signature | v1, followed by the signature |
The secret must be base64 and decode to at least 24 bytes. It may start with whsec_. To create one:
openssl rand -base64 32The signature is an HMAC-SHA256, with the decoded secret as the key, of <webhook-id>.<webhook-timestamp>.<raw body>, encoded as base64. To check it in Node.js:
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyWebhook(rawBody, headers, secret) {
const id = headers["webhook-id"];
const timestamp = headers["webhook-timestamp"];
const signatures = (headers["webhook-signature"] || "").split(" ");
// Reject old messages to stop replays.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected = createHmac("sha256", key)
.update(`${id}.${timestamp}.${rawBody}`)
.digest("base64");
return signatures.some((entry) => {
const [version, signature] = entry.split(",");
return (
version === "v1" &&
signature.length === expected.length &&
timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
);
});
}Use the body exactly as received, before parsing the JSON. Any Standard Webhooks library can do the same check. Use webhook-id to ignore a message you have already handled.
Send alerts to a webhook
Insight alerts can notify a webhook when a value crosses a threshold:
- Open the insight and set up an alert.
- Under Notify, choose Webhook and enter the URL.
Your plan sets how many alerts each project can have.
Good practice
- Use an
https://address. - Answer quickly and do slow work afterwards, so requests do not time out.
- Filter the destination to the events you need, rather than sending everything.
- Leave personal data out of the body unless the receiving system needs it.
Can't find what you need? Contact support