---
source_url: https://www.pubnub.com/docs/data-storage/structured-data/subscribe-to-events
title: Subscribe to DataSync events
updated_at: 2026-09-30T07:20:08.000Z
---

# Subscribe to DataSync events

## 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.

This guide shows you how to subscribe to real-time DataSync events and handle them as they arrive. DataSync events are delivered on ordinary PubNub channels as [message type](https://www.pubnub.com/docs/pub-sub/overview.md#message-types-categorize-traffic-on-a-shared-channel) 5. Receiving them requires subscribe permission on the relevant channels.

## Before you start

* DataSync must be enabled on your keyset. Refer to [Enable DataSync](https://www.pubnub.com/docs/data-storage/structured-data/enable-structured-data.md).
* Events must be turned on for the class versions you want to watch. Refer to [Enable DataSync: enable events for a class version](https://www.pubnub.com/docs/data-storage/structured-data/enable-structured-data.md#enable-events-for-a-class-version).
* Your token must have `read` permission (subscribe) on the channels the events reach. Refer to [Grant DataSync access](https://www.pubnub.com/docs/data-storage/structured-data/grant-structured-data-access.md).

## Subscribe to a single entity

Subscribe to the entity's own ID channel to receive all events about that entity.

### JavaScript

```javascript
const subscription = pubnub.dataSyncEntity('product-sneaker-42').subscription()
subscription.onDataSync = (event) => {
    console.log(event.message.event, event.message.data)
}
subscription.subscribe()
```

### C#

```csharp
Channel channel = pubnub.Channel("product-sneaker-42");
Subscription subscription = channel.Subscription();

var listener = new SubscribeCallbackExt(
    (Pubnub pn, PNDataSyncEventResult dataSyncEvent) => Console.WriteLine(dataSyncEvent.Event),
    (Pubnub pn, PNStatus status) => { /* handle status */ });

pubnub.AddListener(listener);
subscription.Subscribe<object>();
```

The JavaScript SDK exposes `event.message.event`, `event.message.className`, and `event.message.data` from the wire envelope. The C# SDK exposes the same fields as properties on `PNDataSyncEventResult`: `Event`, `ClassName`, `ClassLevel`, `ClassVersion`, and `Source`, with the object state on `EntityData` (or `RelationshipData` for memberships and relationships).

The entity's ID channel also carries events about the entities linked to it. While the `wishlist-alice-sneaker` relationship links them, an update to `user-alice` also arrives on `product-sneaker-42`. Check `className` and `data.id` before you apply an event.

Events on the ID channel carry the `__default__` view of the payload, whatever projection the subscriber's token has. To receive a projection's view, subscribe to its [projection channel](#subscribe-to-a-projection-channel).

A common pattern is to fetch the object once to get its current state, then apply incoming events to keep it current. DataSync publishes each change event at least once, so a subscriber can receive the same event more than once. Compare `eTag` or `updatedAt` on each event against the state you hold, and discard events you've already applied.

When the [status listener](https://www.pubnub.com/docs/architecture/connection-management/overview.md#the-status-listener) reports a reconnect, fetch the object again. Live delivery doesn't resend an event published while the client was disconnected. Refer to [How events relate to subscribe](https://www.pubnub.com/docs/data-storage/structured-data/events.md#how-events-relate-to-subscribe).

## Handle different event types

Each event carries a `metadata.event` value of `create`, `update`, or `delete`. Read it together with `metadata.type` to dispatch correctly.

```javascript
subscription.onDataSync = (event) => {
    const change = event.message
    console.log(change.event, change.className, change.data.payload?.price)
}
```

A delete event carries only `id` and `deletedAt` in its `data` object. Use those two fields when deduplicating deletes. Refer to [Event format reference](https://www.pubnub.com/docs/data-storage/structured-data/event-format.md) for the full envelope schema.

## Subscribe to a projection channel

If the class declares a named projection and you need that view in real time, subscribe to the projection channel: `__<projection>__<id>`.

### JavaScript

```javascript
const subscription = pubnub.dataSyncEntity('user-alice').subscription({ projection: 'admin' })
subscription.onDataSync = (event) => {
    console.log(event.message.data)
}
subscription.subscribe()
```

### C#

```csharp
Channel channel = pubnub.Channel("__admin__user-alice");
Subscription subscription = channel.Subscription();

var listener = new SubscribeCallbackExt(
    (Pubnub pn, PNDataSyncEventResult dataSyncEvent) =>
    {
        Console.WriteLine(dataSyncEvent.Event);
        Console.WriteLine(dataSyncEvent.ClassName);
    },
    (Pubnub pn, PNStatus status) => { /* handle status */ });

pubnub.AddListener(listener);
subscription.Subscribe<object>();
```

Events on `__admin__user-alice` carry only the fields in the `admin` projection. When `email` changes, `data.payload` is `{ "email": "alice@example.com" }`.

:::warning Projection channels need channel grants
A token must have `read` (subscribe) permission on the projection channel `__<projection>__<id>`. Permission on the object's own ID channel is separate and doesn't cover the projection channel. Grant subscribe on projection channels as carefully as you grant the projection itself.
:::

## Subscribe to a group of objects with a wildcard

A wildcard subscription splits channel names at the dot. `product.*` matches `product.sneaker-42` but not `product-sneaker-42`. To watch a group of objects with one subscription, give their IDs a shared prefix that ends in a dot, like `product.`.

The token needs `read` on the wildcard channel name, for example a `channels` resource grant on `product.*`.

### JavaScript

```javascript
const subscription = pubnub.dataSyncEntity('product.*').subscription()

subscription.onDataSync = (event) => {
    // event.channel      -> 'product.sneaker-42'
    // event.subscription -> 'product.*'
    console.log('changed:', event.message.data.id)
}

subscription.subscribe()
```

### C#

```csharp
Channel channel = pubnub.Channel("product.*");
Subscription subscription = channel.Subscription();

var listener = new SubscribeCallbackExt(
    (Pubnub pn, PNDataSyncEventResult dataSyncEvent) =>
    {
        string changedId = dataSyncEvent.EntityData?.Id
            ?? dataSyncEvent.RelationshipData?.Id
            ?? dataSyncEvent.Id;
        Console.WriteLine("changed: " + changedId);
    },
    (Pubnub pn, PNStatus status) => { /* handle status */ });

pubnub.AddListener(listener);
subscription.Subscribe<object>();
```

An event delivered through a wildcard reports the concrete delivery channel rather than the pattern. Read the changed object's `id` from `data` rather than inferring it from the channel name.

This is ordinary [Wildcard Subscribe](https://www.pubnub.com/docs/pub-sub/subscribe/overview.md). The same approach works for projection channels: `__public__product.*` subscribes to the `public` view of every product.

## Note on memberships and relationships

Membership and relationship events never reach a channel named after the relationship or membership ID. They reach the ID channels of the two linked entities instead. To watch Alice's memberships appear and disappear, subscribe to `user-alice`, not to any membership ID.

Refer to [Events: membership and relationship events](https://www.pubnub.com/docs/data-storage/structured-data/events.md#membership-and-relationship-events).

Refer to [DataSync SDK entities (JavaScript)](https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-and-subscribe.md#datasync-sdk-entities) and [Add DataSync listener (C#)](https://www.pubnub.com/docs/sdks/c-sharp/api-reference/publish-and-subscribe.md#add-datasync-listener) for the full method reference.

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