---
title: "What does the RevenueDot webhook event SUBSCRIBER_ALIAS mean?"
description: "SUBSCRIBER_ALIAS is sent when a new app user id joins an existing customer. RevenueCat deprecated it, so RevenueDot sends it only to webhooks that ask for it."
url: https://revenuedot.app/docs/webhooks/webhook-subscriber-alias
---

# 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 `logIn` and 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_types` filter names `subscriber_alias`, and always keeps it in the customer's event history.

## What your server should do

1. Add the new id to the customer's list of ids in your own records.
2. Subscribe to it only if you need to follow id changes.
3. Prefer reading `aliases` on any event, which lists every id of the customer.
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":"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?](https://revenuedot.app/docs/webhooks/webhook-transfer.md)
- [What does the RevenueDot webhook event PURCHASE_REDEEMED mean?](https://revenuedot.app/docs/webhooks/webhook-purchase-redeemed.md)
- [What does the RevenueDot webhook event INITIAL_PURCHASE mean?](https://revenuedot.app/docs/webhooks/webhook-initial-purchase.md)
- [SUBSCRIBER_ALIAS fields and a recorded example payload](https://revenuedot.app/docs/api/webhook-events.md#subscriber_alias)
- [Webhooks guide: set up, verify and test](https://revenuedot.app/docs/guides/webhooks.md)

## Source

- [RevenueDot docs: which webhook events RevenueDot sends](https://revenuedot.app/docs/api/webhook-events)
- [RevenueCat: webhook event types and fields (the format RevenueDot follows)](https://www.revenuecat.com/docs/integrations/webhooks/event-types-and-fields)
- [RevenueDot core: events.ts (the event types and the rules that derive them)](https://github.com/revenuedot/revenuedot/blob/main/packages/core/src/events.ts)
- [RevenueDot server: services/events.ts (how an event is recorded and delivered)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/services/events.ts)
- [RevenueDot server: services/purchases.ts (where store changes become events)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/services/purchases.ts)

Checked: 2026-10-03
