---
source_url: https://www.pubnub.com/docs/migration-guides/legacy-webhooks
title: Migrate from legacy webhooks to Events & Actions
updated_at: 2026-09-30T07:20:08.000Z
---

# Migrate from legacy webhooks to Events & Actions

## Documentation index

To discover more PubNub resources:

1. Fetch [PubNub's llms.txt](https://www.pubnub.com/llms-full.txt) for a list of available pages in Markdown format.
2. Identify relevant URLs from that index.
3. Fetch the target pages.

Do not assume a path exists, always check the index first.

[Events & Actions](https://www.pubnub.com/docs/integrations/event-forwarding/overview.md) replaced webhook configuration on the Admin Portal **Keysets** page. PubNub automatically migrated existing paid-plan webhooks when this change shipped, before 16 January 2024. Check whether a webhook you configured on the Keysets page for Presence, Mobile Push Notifications, or Message Persistence is already an event listener and action in Events & Actions. If it isn't, this guide moves it there and updates any code that parses the webhook payload for the current shape.

## Before you start

Confirm you have:

* Admin Portal access to the keyset with the legacy webhook configured.
* An Events & Actions plan that covers your listener and action needs. The [Free plan](https://www.pubnub.com/docs/integrations/event-forwarding/overview.md#availability-by-plan) includes one listener with a webhook-only action; higher tiers raise those limits and add retries.

## Migrate with an AI coding assistant

If you use an AI coding assistant, paste this prompt into it to update your webhook handlers. The prompt makes the assistant read this guide, list every handler that parses a PubNub webhook, and stop before it removes legacy payload parsing. Do the Admin Portal steps in [Move your webhook to an event listener and action](#move-your-webhook-to-an-event-listener-and-action) yourself.

```text
Migrate this codebase's PubNub webhook handlers from legacy webhooks to the
Events & Actions payload shape.

1. Read the migration guide first:
   https://www.pubnub.com/docs/migration-guides/legacy-webhooks.md
   If the PubNub MCP server is connected, you can call get_general_migration_guide
   instead. Where the guide and your own knowledge of PubNub disagree, follow the
   guide and tell me.
2. Before you edit anything, list every HTTP handler that receives a PubNub
   webhook for Presence, Mobile Push Notifications, or Message Persistence. Also
   list every place that reads its fields, such as user_id or sub_key. Then show me a plan
   and wait for my approval.
3. Ask me which of these webhooks already exist as an event listener with a
   webhook action in Events & Actions. PubNub migrated paid-plan webhooks
   automatically before 16 January 2024. Creating the rest is Admin Portal work
   that you can't do.
4. Update parsing for the current shape. Records sit in a data array next to a
   dataSchema field. Read the record from data[0] and use userId and subKey
   instead of user_id and sub_key.
5. For Push error and Device removed events set up with the envelope turned on,
   read each record from event.payload.data and use subKey instead of sub_key.
6. For any other event type, check the payload in
   https://www.pubnub.com/docs/integrations/event-forwarding/payloads.md
   instead of guessing the shape.
7. STOP before you remove any legacy parsing code. Keep it until I confirm that
   the Events & Actions listener for that event is live and sends to this
   handler.
8. Make one small change at a time. After each change, run the build and tests
   and show me the output.
9. Never put the PubNub secret key in client code, and never commit keys,
   webhook secrets, or other credentials.
10. When you finish, list every file you changed and the steps left for me.
```

## Move your webhook to an event listener and action

1. Create an event listener for the event you previously received by webhook, following [Create an event listener](https://www.pubnub.com/docs/integrations/event-forwarding/configure.md#create-an-event-listener).
2. Add a webhook action to that listener with the same destination URL, following [Create a Webhook action](https://www.pubnub.com/docs/integrations/event-forwarding/create-webhook-action.md).
3. Repeat for each legacy webhook you had configured and still want to receive.

## Update your webhook payload parsing

The webhook payload shape changed. The current payload wraps records in a `data` array and includes a `dataSchema` field.

```json
{
  "dataSchema": "pubnub.com/schemas/events/presence.user.channel.joined?v=1.0.0",
  "data": [
    {
      "id": "a36773df-d828-4d40-99ab-26b8ebe46e41",
      "channel": "Channel-Barcelona",
      "userId": "Jack-device",
      "occupancy": 2,
      "data": {
        "action": "join",
        "timestamp": "1750065086",
        "precise_timestamp": "1750065086809",
        "occupancy": "2",
        "uuid": "Jack-device"
      },
      "timestamp": "2025-06-16T09:11:26.809Z",
      "subKey": "sub-c-b0451d-1337-4b42-bee0-1905c7c02db"
    }
  ]
}
```

Legacy webhooks put one record at the top level and used snake_case keys such as `user_id` and `sub_key`. Read the current record from `data[0]`, and use `userId` and `subKey` instead.

This example shows the Presence "user started subscription to channel" event. For every other event type, and for enveloped variants that add Events & Actions metadata, see [Events & Actions payloads](https://www.pubnub.com/docs/integrations/event-forwarding/payloads.md).

## Update Mobile Push Notifications parsing

Legacy Push Webhooks sent the push error or device record at the top level, with snake_case keys such as `sub_key`. For example, a legacy device removal looked like this:

```json
{
  "sub_key": "sub-c-e1559b02-3320-11ea-b686-76f717eaed2c",
  "timestamp": "16007987966269679",
  "platform": "apns2",
  "action": "remove",
  "device": "f3b26d22f3b26d22f3b26d22f3b26d22f3b26d22f3b26d22f3b26d22f3b26d22"
}
```

To receive push errors and device removals through Events & Actions, create one listener for the **Push error** event type and one for **Device removed**, and pair both with a Webhook action. [Set up Push Webhooks](https://www.pubnub.com/docs/integrations/mobile-push-notifications/set-up-push-webhooks.md) walks through the setup and shows the current payload for both events. That page turns the envelope on, so read each record from `event.payload.data` and use `subKey` instead of `sub_key`.

## Related tasks

* [Configure Events & Actions](https://www.pubnub.com/docs/integrations/event-forwarding/configure.md). Create the event listener that replaces your legacy webhook.
* [Create a Webhook action](https://www.pubnub.com/docs/integrations/event-forwarding/create-webhook-action.md). Add and configure the webhook action itself, including retries and custom headers.
* [Forward push errors and device removals to your endpoint](https://www.pubnub.com/docs/integrations/mobile-push-notifications/set-up-push-webhooks.md). Forward push errors and device removals through Events & Actions.
* [Events & Actions payloads](https://www.pubnub.com/docs/integrations/event-forwarding/payloads.md). The payload shape for every event type and envelope variant.
* [Events & Actions](https://www.pubnub.com/docs/integrations/event-forwarding/overview.md). The event listener and action model, and plan availability.

Last updated at: 2026-09-30T07:20:08.000Z
