---
source_url: https://www.pubnub.com/docs/sdks/unity/api-reference/presence
title: Presence API for Unity SDK
updated_at: 2026-06-26T11:07:08.760Z
sdk_name: PubNub Unity SDK
sdk_version: v9.4.0
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Presence API for Unity SDK

PubNub Unity SDK, use the latest version: v9.4.0

Presence lets you track who is online or offline and store custom state information. Presence shows:

* When a user has joined or left a channel
* How many users are subscribed to a particular channel (occupancy)
* Which channels a user or device is subscribed to
* Presence state associated with these users

Learn more about our Presence feature in the [Presence overview](https://www.pubnub.com/docs/general/presence/overview).

:::note Presence event modes
Presence mode indicates when presence events are triggered for that channel. It can be either:
* Announce Mode
* Interval Mode
The mode is dependant on the occupancy count. This setting is controlled through [Admin Portal](https://admin.pubnub.com/). To learn more about this, visit [Presence documentation](https://www.pubnub.com/docs/general/presence/presence-events#presence-event-modes).
:::

## Here now

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

This method returns information about the current state of a channel, including a list of unique user IDs (universally unique identifiers, UUIDs) currently subscribed to the channel and the total occupancy count of the channel.

:::note Cache
This method has a 3-second response cache time.
:::

### Method(s)

To call `Here Now` you can use the following method(s) in the Unity SDK:

```csharp
pubnub.HereNow()
    .Channels(Array)
    .ChannelGroups(Array)
    .IncludeState(bool)
    .IncludeUUIDs(bool)
    .Limit(int)
    .Offset(int)
    .QueryParam(Dictionary<string,object>)
    .Execute(System.Action<PNHereNowResult, PNStatus>)
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| Channels | Array | Optional |  | The `Channels` to get the `here now` details. |
| ChannelGroups | Array | Optional |  | The `ChannelGroups` to get the `here now` details. Wildcards are not supported. |
| IncludeState | bool | Optional |  | If `true`, the response will include the presence states of the users for `Channels`/`ChannelGroups`. |
| IncludeUUIDs | bool | Optional |  | If `true`, the response will include the `UUIDs` of the connected clients. |
| Limit | int | Optional | `1000` | Maximum number of occupants to return per channel. Valid range: `0-1000`. Use `0` to get occupancy counts without user details. This parameter is only applied when specific `Channels` are provided. |
| Offset | int | Optional | `0` | Zero-based starting index for pagination. Returns occupants starting from this position in the list. Must be `>= 0`. Requires `Limit > 0`. Use with `Limit` to paginate through large occupant lists. This parameter is only applied when specific `Channels` are provided and only included in the request when `Offset > 0`. |
| QueryParam | Dictionary<string, | Optional |  | Dictionary `object` to pass name/value pairs as query `string` params with PubNub URL request for debug purpose. |
| Async | PNCallback | Optional |  | PNCallback of type PNHereNowResult. |
| Execute | System.Action | Yes |  | `System.Action` of type `PNHereNowResult`. |
| ExecuteAsync | None | Optional |  | Returns `Task<PNResult<PNHereNowResult>>`. |

### Sample code

#### Get a list of UUIDs subscribed to channel

:::tip Reference code
This example is a self-contained code snippet ready to be run. It includes necessary imports and executes methods with console logging. Use it as a reference when working with other examples in this document.
:::

```csharp
using System.Collections.Generic;
using PubnubApi;
using PubnubApi.Unity;
using UnityEngine;

public class HereNowExample : MonoBehaviour {
    // Reference to a pubnub manager previously setup in Unity Editor
    // For more details, see https://www.pubnub.com/docs/sdks/unity#configure-pubnub
    [SerializeField] private PNManagerBehaviour pubnubManager;

    // An editor-serialized array with test channel IDs
    [SerializeField] private string[] testChannelIds = { "coolChannel", "coolChannel2" };

    private async void Start() {
        // Getting a reference to the Pubnub instance
        var pubnub = pubnubManager.pubnub;

        // Note that you can also initialize Pubnub instance for Unity directly from code:
        /*
        PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
        {
	        SubscribeKey = "demo",
	        PublishKey = "demo",
        };
        Pubnub pubnub = PubnubUnityUtils.NewUnityPubnub(pnConfiguration);
        */

        // Executing the HereNow operation to get a list of UUIDs subscribed to channels
        var herenowResponse = await pubnub.HereNow()
            .Channels(testChannelIds)
            .IncludeUUIDs(true)
            .ExecuteAsync();

        // Result and status of the HereNow operation
        var herenowResult = herenowResponse.Result;
        var status = herenowResponse.Status;

        // Handling potential errors
        if (status.Error) {
            Debug.LogError($"Error in HereNow operation: {status.ErrorData.Information}");
        } else {
            if (herenowResult?.Channels != null && herenowResult.Channels.Count > 0) {
                foreach (KeyValuePair<string, PNHereNowChannelData> kvp in herenowResult.Channels) {
                    PNHereNowChannelData channelData = kvp.Value;

                    Debug.Log("---");
                    Debug.Log($"channel: {channelData.ChannelName}");
                    Debug.Log($"occupancy: {channelData.Occupancy}");
                    Debug.Log("Occupants:");

                    if (channelData.Occupants != null && channelData.Occupants.Count > 0) {
                        foreach (var occupant in channelData.Occupants) {
                            Debug.Log($"uuid: {occupant.Uuid}");
                            Debug.Log($"state: {(occupant.State != null ? pubnub.JsonPluggableLibrary.SerializeToJsonString(occupant.State) : "No state")}");
                        }
                    }
                }
            } else {
                Debug.Log("No occupants found.");
            }
        }
    }
}
```

### Returns

The `HereNow()` operation returns a `PNResult<PNHereNowResult>` which contains the following properties:

| Property Name | Type | Description |
| --- | --- | --- |
| `Result` | PNHereNowResult | Returns a `PNHereNowResult` object. |
| `Status` | PNStatus | Returns a `PNStatus` object. |

`PNHereNowResult` contains the following properties:

| Property Name | Type | Description |
| --- | --- | --- |
| `TotalChannels` | int | Total `Channels`. |
| `TotalOccupancy` | int | Total `Occupancy`. |
| `Channels` | `Dictionary<string, PNHereNowChannelData>` | A map with values of `PNHereNowChannelData` for each `channel`. See [PNHereNowChannelData](#pnherenowchanneldata) for more details. |

#### PNHereNowChannelData

| Property Name | Type | Description |
| --- | --- | --- |
| `ChannelName` | string | `Channel` name. |
| `Occupancy` | int | `Occupancy` of the `channel`. |
| `Occupants` | List`<PNHereNowOccupantData>` | A list of `PNHereNowOccupantData`, see [PNHereNowOccupantData](#pnherenowoccupantdata) for more details. |

#### PNHereNowOccupantData

| Property Name | Type | Description |
| --- | --- | --- |
| `Uuid` | string | `UUIDs` of the user. |
| `State` | object | `State` of the user. |

### Other examples

#### Get a list of UUIDs subscribed to channel synchronously

```csharp
using PubnubApi;
using PubnubApi.Unity;

pubnub.HereNow()
    // tailor the next two lines to example
    .Channels(new string[] {
        "coolChannel",
        "coolChannel2"
        })
    .IncludeUUIDs(true)
    .Execute(new PNHereNowResultEx(
        (result, status) => {
            if (status.Error) {
                // handle error
                return;
            }

            if (result.Channels != null && result.Channels.Count > 0) {
                foreach (KeyValuePair<string, PNHereNowChannelData> kvp in result.Channels) {
                    PNHereNowChannelData channelData = kvp.Value;
                    Debug.Log("---");
                    Debug.Log("channel:" + channelData.ChannelName);
                    Debug.Log("occupancy:" + channelData.Occupancy);
                    Debug.Log("Occupants:");
                    if (channelData.Occupants != null && channelData.Occupants.Count > 0) {
                        for (int index = 0; index < channelData.Occupants.Count; index++) {
                            PNHereNowOccupantData occupant = channelData.Occupants[index];
                            Debug.Log(string.Format("uuid: {0}", occupant.Uuid));
                            Debug.Log(string.Format("state:{1}", (occupant.State != null) ?
                            pubnub.JsonPluggableLibrary.SerializeToJsonString(occupant.State) : ""));
                        }
                    }
                }
            }
        }
    ));
```

#### Returning state

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

```csharp
using PubnubApi;
using PubnubApi.Unity;

PNResult<PNHereNowResult> herenowResponse = await pubnub.HereNow()
    .Channels(new string[] {
        // who is present on those channels?
        "my_channel"
    })
    .IncludeState(true) // include state with request (false by default)
    .IncludeUUIDs(true) // if false, only shows occupancy count
    .ExecuteAsync();

PNHereNowResult herenowResult = herenowResponse.Result;
PNStatus status = herenowResponse.Status;
//handle it
```

#### Example response

```csharp
{
    "status" : 200,
    "message" : "OK",
    "service" : "Presence",
    "uuids" : [
        {
            "uuid" : "myUUID0"
        },
        {
            "state" : {
                "abcd" : {
                    "age" : 15
                }
            },
            "uuid" : "myUUID1"
        },
        {
            "uuid" : "b9eb408c-bcec-4d34-b4c4-fabec057ad0d"
        },
        {
            "state" : {
                "abcd" : {
                    "age" : 15
                }
            },
            "uuid" : "myUUID2"
        },
        {
            "state" : {
                "abcd" : {
                    "age" : 24
                }
            },
            "uuid" : "myUUID9"
        }
    ],
    "occupancy" : 5
}
```

#### Return occupancy only

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

You can return only the `occupancy` information for a single channel by specifying the channel and setting `UUIDs` to `false`:

```csharp
using PubnubApi;
using PubnubApi.Unity;

PNResult<PNHereNowResult> herenowResponse = await pubnub.HereNow()
    .Channels(new string[] {
            // who is present on those channels?
        "my_channel"
    })
    .IncludeState(false) // include state with request (false by default)
    .IncludeUUIDs(false) // if false, only shows occupancy count
    .ExecuteAsync();

PNHereNowResult herenowResult = herenowResponse.Result;
PNStatus status = herenowResponse.Status;
//handle it
```

#### Example response

```csharp
{
    "status": 200,
    "message": "OK",
    "payload": {
        "channels": {
            "81d8d989-b95f-443c-a726-04fac323b331": {
                "uuids": [ "70fc1140-22b5-4abc-85b2-ff8c17b24d59" ],
                "occupancy": 1
            },
            "81b7a746-d153-49e2-ab70-3037a75cec7e": {
                "uuids": [ "91363e7f-584b-49cc-822c-52c2c01e5928" ],
                "occupancy": 1
            },
            "c068d15e-772a-4bcd-aa27-f920b7a4eaa8": {
                "uuids": [ "ccfac1dd-b3a5-4afd-9fd9-db11aeb65395" ],
                "occupancy": 1
            }
        },
        "total_channels": 3,
        "total_occupancy": 3
    },
    "service": "Presence"
}
```

## Where now

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

This method returns the list of channels a UUID is subscribed to.

:::note Timeout events
If the app restarts (or the page refreshes) within the heartbeat window, no timeout event is generated.
:::

### Method(s)

To call `WhereNow()` you can use the following method(s) in the Unity SDK:

```csharp
pubnub.WhereNow()
    .Uuid(string)
    .QueryParam(Dictionary<string,object>)
    .Execute(System.Action<PNWhereNowResult, PNStatus>)
```

| Parameter | Description |
| --- | --- |
| `Uuid` *Type: string | `Uuid`. |
| `QueryParam`Type: Dictionary`<string, object>` | Dictionary `object` to pass name/value pairs as query `string` params with PubNub URL request for debug purpose. |
| AsyncType: Command | PNCallback of type PNWhereNowResult. |
| `Execute` *Type: `System.Action` | `System.Action` of type `PNWhereNowResult`. |
| `ExecuteAsync`Type: None | Returns `Task<PNResult<PNWhereNowResult>>`. |

### Sample code

You simply need to define the `uuid` and the `callback` function to be used to send the data to as in the example below.

#### Get a list of channels a UUID is subscribed to

```csharp
using PubnubApi;
using PubnubApi.Unity;

PNResult<PNWhereNowResult> wherenowResponse = await pubnub.WhereNow()
    .ExecuteAsync();

PNWhereNowResult wherenowResult = wherenowResponse.Result;
PNStatus status = wherenowResponse.Status;
// returns a pojo with channels
// channel groups which I am part of.
```

### Returns

The `WhereNow()` operation returns a `PNResult<PNWhereNowResult>` which contain the following properties:

| Property Name | Type | Description |
| --- | --- | --- |
| `Result` | PNWhereNowResult | Returns a `PNWhereNowResult` object. |
| `Status` | PNStatus | Returns a `PNStatus` object. |

`PNWhereNowResult` contains the following properties:

| Property Name | Type | Description |
| --- | --- | --- |
| `Channels` | List`<string>` | The list of `channels` where the `UUID` is present. |

### Other examples

#### Get a list of channels synchronously

```csharp
using PubnubApi;
using PubnubApi.Unity;

pubnub.WhereNow()
    .Execute(new PNWhereNowResultExt(
        (result, status) => {
            // returns a pojo with channels
            // channel groups which I am part of.
        }
    ));
```

#### Obtain information about the current list of channels of some other UUID

```csharp
using PubnubApi;
using PubnubApi.Unity;

PNResult<PNWhereNowResult> wherenowResponse = await pubnub.WhereNow()
    .Uuid("some-other-uuid") // uuid of the user we want to spy on.
    .ExecuteAsync();

PNWhereNowResult wherenowResult = wherenowResponse.Result;
PNStatus status = wherenowResponse.Status;
// returns a pojo with channels
// channel groups which "some-other-uuid" part of.ere_now_example_1
```

## User state

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

The state API is used to set/get key/value pairs specific to a subscriber `Uuid`.

State information is supplied as a Generic Dictionary object(`Dictionary<string, object>`) of key/value pairs.

### Method(s)

#### Set state

```csharp
pubnub.SetPresenceState()
    .Channels(Array)
    .ChannelGroups(Array)
    .State(Dictionary<string, object>)
    .Uuid(string)
    .QueryParam(Dictionary<string,object>)
    .Execute(System.Action<PNSetStateResult, PNStatus>)
```

| Parameter | Description |
| --- | --- |
| `Channels`Type: Array | `Channels` to set `state`. |
| `ChannelGroups`Type: Array | `ChannelGroups` to set `state`. |
| `State`Type: Dictionary`<string, object>` | `State` to set. |
| `Uuid` *Type: string | `Uuid` |
| `QueryParam`Type: Dictionary`<string, object>` | Dictionary `object` to pass name/value pairs as query `string` params with PubNub URL request for debug purpose. |
| AsyncType: PNCallback | PNCallback of type PNSetStateResult. |
| `Execute` *Type: `System.Action` | `System.Action` of type `PNSetStateResult`. |
| `ExecuteAsync`Type: None | Returns `Task<PNResult<PNSetStateResult>>`. |

#### Get state

```csharp
pubnub.GetPresenceState()
    .Channels(Array)
    .ChannelGroups(Array)
    .Uuid(string)
    .QueryParam(Dictionary<string,object>)
    .Execute(System.Action<PNGetStateResult, PNStatus>)
```

| Parameter | Description |
| --- | --- |
| `Channels`Type: Array | `Channel` name to fetch the `state`. |
| `ChannelGroups`Type: Array | `ChannelGroups` name to fetch the `state`. |
| `Uuid` *Type: string | `Uuid` |
| `QueryParam`Type: Dictionary`<string, object>` | Dictionary `object` to pass name/value pairs as query `string` params with PubNub URL request for debug purpose. |
| AsyncType: PNCallback | PNCallback of type PNGetStateResult. |
| `Execute` *Type: `System.Action` | `System.Action` of type `PNGetStateResult`. |
| `ExecuteAsync`Type: None | Returns `Task<PNResult<PNGetStateResult>>`. |

### Sample code

#### Set state

```csharp
using PubnubApi;
using PubnubApi.Unity;

Dictionary<string, object> myState = new Dictionary<string, object>();
myState.Add("age", 20);

PNResult<PNSetStateResult> setstateResponse = await pubnub.SetPresenceState()
    .Channels(new string[] {
        "ch1",
        "ch2",
        "ch3"
    })
    .State(myState)
    .ExecuteAsync();

PNSetStateResult setstateResult = setstateResponse.Result;
PNStatus status = setstateResponse.Status;
// handle set state response
```

#### Get state

```csharp
using PubnubApi;
using PubnubApi.Unity;

PNResult<PNGetStateResult> getstateResponse = await pubnub.GetPresenceState()
    .Channels(new string[] {
        // channels to fetch state for
        "ch1",
        "ch2",
        "ch3"
    })
    .ChannelGroups(new string[] {
        // channel groups to fetch state for
        "cg1",
        "cg2",
        "cg3"
    })
    .Uuid("suchUUID") // uuid of user to fetch, or for own uuid
    .ExecuteAsync();

PNGetStateResult getstateResult = getstateResponse.Result;
PNStatus status = getstateResponse.Status;
// handle response
```

### Returns

The `SetPresenceState()` operation returns a `PNResult<PNSetStateResult>` which contains the following properties:

| Property Name | Type | Description |
| --- | --- | --- |
| `Result` | PNGetStateResult | Returns a `PNSetStateResult` object. |
| `Status` | PNStatus | Returns a `PNStatus` object. |

`PNSetStateResult` contains the following property:

| Property Name | Type | Description |
| --- | --- | --- |
| `State` | Dictionary`<string, object>` | Dictionary of `UUIDs` and the user states. |

The `GetPresenceState()` operation returns a `PNResult<PNGetStateResult>` which contains the following properties:

| Property Name | Type | Description |
| --- | --- | --- |
| `Result` | PNGetStateResult | Returns a `PNGetStateResult` object. |
| `Status` | PNStatus | Returns a `PNStatus` object. |

`PNGetStateResult` contains the following property:

| Property Name | Type | Description |
| --- | --- | --- |
| `StateByUUID` | Dictionary`<string, object>` | Dictionary of `UUIDs` and the user states. |

### Other examples

#### Set state synchronously

```csharp
using PubnubApi;
using PubnubApi.Unity;

Dictionary<string, object> myState = new Dictionary<string, object>();
myState.Add("age", 20);

pubnub.SetPresenceState()
    .Channels(new string[] {
        "ch1",
        "ch2",
        "ch3"
    })
    .State(myState)
    .Execute(new PNSetStateResultExt(
        (result, status) => {
            // handle set state response
        }
    ));
```

#### Get state synchronously

```csharp
using PubnubApi;
using PubnubApi.Unity;

pubnub.GetPresenceState()
    .Channels(new string[] {
        // channels to fetch state for
        "ch1",
        "ch2",
        "ch3"
    })
    .ChannelGroups(new string[] {
        // channel groups to fetch state for
        "cg1",
        "cg2",
        "cg3"
    })
    .Uuid("suchUUID") // uuid of user to fetch, or for own uuid
    .Execute(new PNGetStateResultExt(
        (result, status) => {
            // handle response
        }
    ));
```

#### Set state for channels in channel group

```csharp
using PubnubApi;
using PubnubApi.Unity;

Dictionary<string, object> myState = new Dictionary<string, object>();
myState.Add("age", 20);

PNResult<PNSetStateResult> setstateResponse = await pubnub.SetPresenceState()
    .ChannelGroups(new string[] {
        // apply on those channel groups
        "cg1",
        "cg2",
        "cg3"
    })
    .Channels(new string[] {
        // apply on those channels
        "ch1",
        "ch2",
        "ch3"
    })
    .State(myState) // the new state
    .ExecuteAsync();

PNSetStateResult setstateResult = setstateResponse.Result;
PNStatus status = setstateResponse.Status;
// on new state for those channels
```

The above code would return the following response to the client:

```csharp
{
    first  : "Robert",
    last   : "Plant",
    age    : 59,
    region : "UK"
}
```