What does the RevenueDot webhook event SUBSCRIBER_ALIAS mean?
The RevenueDot webhook event SUBSCRIBER_ALIAS means a new app user id was linked to an existing customer.
Quick facts#
| Event | SUBSCRIBER_ALIAS |
| Where | RevenueDot webhook (event.type), RevenueCat's webhook format |
| Sent to | Only webhooks whose event_types filter names subscriber_alias |
| Fields that are specific to it | original_app_user_id |
| What it means | A new app user id joined an existing customer: logIn onto an anonymous customer, logIn that merged an anonymous customer into an existing one, Android's alias call, or a restore that merged two customers. |
When it is sent#
- The app called
logInand the anonymous customer got a real app user id, or two customers were merged. - RevenueCat deprecated the event and sends it only to older projects.
- RevenueDot delivers it only to webhooks whose
event_typesfilter namessubscriber_alias, and always keeps it in the customer's event history.
What your server should do#
- Add the new id to the customer's list of ids in your own records.
- Subscribe to it only if you need to follow id changes.
- Prefer reading
aliaseson any event, which lists every id of the customer. - 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":"SUBSCRIBER_ALIAS","app_user_id":"user_1","product_id":"pro_monthly","original_app_user_id":"$RCAnonymousID:a"} });
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 !== "SUBSCRIBER_ALIAS") return "200 ignored";
return "add " + event.app_user_id + " to the customer's ids";
}
console.log(handle(rawBody, header));Run-checked: npm run check:snippets runs this snippet with Node and compares its output with add user_1 (checked 2026-10-03).
How RevenueDot produces it#
recordSubscriberAlias records it when a customer gets a new alias or two customers merge. OPT_IN_EVENT_TYPES in packages/core keeps it from any webhook that does not name it in its filter.
Related#
- What does the RevenueDot webhook event TRANSFER mean?
- What does the RevenueDot webhook event PURCHASE_REDEEMED mean?
- What does the RevenueDot webhook event INITIAL_PURCHASE mean?
- SUBSCRIBER_ALIAS fields and a recorded example payload
- Webhooks guide: set up, verify and test
Source#
- RevenueDot docs: which webhook events RevenueDot sends
- RevenueCat: webhook event types and fields (the format RevenueDot follows)
- RevenueDot core: events.ts (the event types and the rules that derive them)
- RevenueDot server: services/events.ts (how an event is recorded and delivered)
- RevenueDot server: services/purchases.ts (where store changes become events)
Checked: 2026-10-03