What does the RevenueDot webhook event TEST mean?

The RevenueDot webhook event TEST is a sample event that RevenueDot sends only when you ask for a test delivery.

Quick facts#

Event TEST
Where RevenueDot webhook (event.type), RevenueCat's webhook format
Sent to Every enabled webhook whose filters match
What it means Sent by the dashboard's "Send test event" or POST .../integrations/webhooks/{id}/test. Shaped like a purchase, for no real customer, so it never carries experiments.

When it is sent#

  • You pressed Send test event in the dashboard, or called the test endpoint of the webhook.
  • It is shaped like a purchase so that your parser meets every field.
  • It is for no real customer.

What your server should do#

  1. Answer HTTP 200 and do not grant anything.
  2. Use it to check your signature verification against the real header.
  3. Look in the dashboard's delivery log if it does not arrive.
  4. Deduplicate on event.id: deliveries can repeat, because anything but HTTP 200 is retried after 5, 10, 20, 40 and 80 minutes.

Example#

JavaScript
import { createHmac, timingSafeEqual } from "node:crypto";

// X-RevenueCat-Webhook-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
function verify(rawBody, header, secret, toleranceSeconds = 300) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? "");
  if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > toleranceSeconds) return false;
  const expected = createHmac("sha256", secret).update(`${m[1]}.${rawBody}`).digest();
  return timingSafeEqual(expected, Buffer.from(m[2], "hex"));
}

// Sign a sample delivery the way RevenueDot does, then handle it.
const secret = "whsec_test_secret";
const rawBody = JSON.stringify({ api_version: "1.0", event: {"id":"66339910-3BFF-49F4-B873-D1283D673DE2","type":"TEST","app_user_id":"user_1","product_id":"pro_monthly","period_type":"NORMAL"} });
const t = Math.floor(Date.now() / 1000);
const header = `t=${t},v1=${createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex")}`;

const seen = new Set(); // use a database table in production

function handle(rawBody, header) {
  if (!verify(rawBody, header, secret)) return "401 bad signature";
  const { event } = JSON.parse(rawBody);
  if (seen.has(event.id)) return "200 duplicate";
  seen.add(event.id);
  if (event.type !== "TEST") return "200 ignored";
  return "200, check the signature works, change nothing";
}

console.log(handle(rawBody, header));

Run-checked: npm run check:snippets runs this snippet with Node and compares its output with check the signature works (checked 2026-10-03).

How RevenueDot produces it#

The webhook test route (routes/v2/partner-integrations.ts) builds a TEST event shaped like a purchase for no real customer, stores it and queues it to the webhook you tested, where it is signed like any delivery. It never carries experiments.

Source#

Checked: 2026-10-03

Edit this page on GitHub ↗ View as Markdown Last updated