---
source_url: https://www.pubnub.com/docs/sdks/java/api-reference/objects
title: App Context API for Java SDK
updated_at: 2026-06-12T11:25:27.202Z
sdk_name: PubNub Java SDK
sdk_version: 6.4.5
---

> 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


# App Context API for Java SDK

PubNub Java SDK, use the latest version: 6.4.5

Install:

```bash
Add PubNub dependency to your build@6.4.5
```

:::warning Breaking changes in v9.0.0
PubNub Java SDK version 9.0.0 unifies the codebases for Java and [Kotlin](https://www.pubnub.com/docs/sdks/kotlin) SDKs, introduces a new way of instantiating the PubNub client, and changes asynchronous API callbacks and emitted [status events](https://www.pubnub.com/docs/sdks/java/status-events). These changes can impact applications built with previous versions (< `9.0.0`) of the Java SDK.
For more details about what has changed, refer to [Java/Kotlin SDK migration guide](https://www.pubnub.com/docs/sdks/kotlin/migration-guides/kotlin-v9-migration-guide).
:::

This page describes App Context (formerly Objects v2). To upgrade from Objects v1, refer to the [migration guide](https://www.pubnub.com/docs/general/resources/migration-guides/objects-v2-migration).

App Context provides easy-to-use, serverless storage for user and channel data you need to build innovative, reliable, scalable applications. Use App Context to store metadata about your application users and channels, and their membership associations, without running your own databases.

PubNub also triggers events when object data changes: set, update, or removal. Setting the same data again doesn't trigger an event. Clients can receive these events in real time and update their front-end application accordingly.

## User

### Get metadata for all users

Returns a paginated list of UUID metadata. Optionally includes Custom.

:::warning Required keyset configuration
To get all channel and user metadata, you must uncheck the
Disallow Get All Channel Metadata
and
Disallow Get All User Metadata
checkboxes in the App Context section of your keyset configuration in the
[Admin Portal](https://admin.pubnub.com)
.
:::

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.getAllUUIDMetadata()
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .includeTotalCount(Boolean)
    .includeCustom(Boolean)
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| limit | Integer | Optional | `100` | Number of objects to return. Default/Max: 100. |
| page | PNPage | Optional |  | Cursor-based pagination. |
| filter | String? | Optional |  | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| sort | List<PNSortKey> | Optional | `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| includeTotalCount | Boolean | Optional | `false` | Whether to include the total count in the paginated response. Default is false. |
| includeCustom | Boolean | Optional | `false` | Whether to include the Custom object in the response. |

#### Sample code

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

```java
import com.pubnub.api.PubNubException;
import com.pubnub.api.UserId;
import com.pubnub.api.java.PubNub;
import com.pubnub.api.java.endpoints.objects_api.utils.PNSortKey;
import com.pubnub.api.java.models.consumer.objects_api.uuid.PNUUIDMetadata;
import com.pubnub.api.java.v2.PNConfiguration;

import java.util.Arrays;
import java.util.List;

public class GetAllUUIDMetadataApp {
    public static void main(String[] args) throws PubNubException {
        // Configure PubNub instance
        PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("demoUserId"), "demo");
        configBuilder.publishKey("demo");
        configBuilder.secure(true);

        PubNub pubnub = PubNub.create(configBuilder.build());

        // Get all UUID Metadata
        pubnub.getAllUUIDMetadata()
                .limit(20)
                .sort(Arrays.asList(PNSortKey.asc(PNSortKey.Key.ID), PNSortKey.desc(PNSortKey.Key.UPDATED)))
                .includeTotalCount(true)
                .includeCustom(true)
                .async(result -> {
                    result.onSuccess(res -> {
                        System.out.println("Total Count: " + res.getTotalCount());
                        List<PNUUIDMetadata> uuidMetadataList = res.getData();
                        for (PNUUIDMetadata metadata : uuidMetadataList) {
                            System.out.println("UUID: " + metadata.getId());
                            System.out.println("Name: " + metadata.getName().getValue());
                            System.out.println("Email: " + metadata.getEmail().getValue());
                            System.out.println("Custom: " + metadata.getCustom().getValue());
                        }
                    }).onFailure(exception -> {
                        System.out.println("Error retrieving UUID metadata: " + exception.getMessage());
                    });
                });
    }
}
```

#### Response

```java
public class PNGetAllUUIDMetadataResult extends EntityArrayEnvelope<PNUUIDMetadata> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNUUIDMetadata> data;
    PNPage nextPage() {
        return PNPage.next(next);
    }
    PNPage previousPage() {
        return PNPage.previous(prev);
    }
}

public class PNUUIDMetadata extends PNObject {
    String id;
    Object custom;
    String updated;
    String eTag;
    String name;
    String email;
    String externalId;
    String profileUrl;
}
```

### Get user metadata

Returns metadata for the specified UUID, optionally including the custom data object for each.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.getUUIDMetadata()
    .uuid(String)
    .includeCustom(Boolean)
```

| Parameter | Description |
| --- | --- |
| `uuid`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |
| `includeCustom`Type: BooleanDefault: `false` | Whether to include the Custom object in the response. |

#### Sample code

```java
pubNub.getUUIDMetadata().async(result -> { /* check result */ });
```

#### Response

```java
public class PNGetUUIDMetadataResult extends EntityEnvelope<PNUUIDMetadata> {
    int status;
    PNUUIDMetadata data;
}

public class PNUUIDMetadata extends PNObject {
    String id;
    Object custom;
    String updated;
    String eTag;
    String name;
    String email;
    String externalId;
    String profileUrl;
}
```

### Set user metadata

:::warning Unsupported partial updates of custom metadata
The value of the custom metadata parameter sent in this method always overwrites the value stored on PubNub servers. If you want to add new custom data to an existing one, you must:
1. Get the existing metadata and store it locally.
2. Append the new custom metadata to the existing one.
3. Set the entire updated custom object.
:::

Set metadata for a UUID in the database, optionally including the custom data object for each.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.setUUIDMetadata()
    .uuid(String)
    .name(String)
    .externalId(String)
    .profileUrl(String)
    .email(String)
    .custom(Map<String, Object>)
    .includeCustom(true)
    .ifMatchesEtag(String)
```

| Parameter | Description |
| --- | --- |
| `uuid`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |
| `name`Type: StringDefault: n/a | Display name for the user. |
| `externalId`Type: StringDefault: n/a | User's identifier in an external system. |
| `profileUrl`Type: StringDefault: n/a | The URL of the user's profile picture. |
| `email`Type: StringDefault: n/a | The user's email address. |
| `custom`Type: AnyDefault: n/a | Custom JSON values. Can be strings, numbers, or booleans. Filtering by Custom isn’t supported. |
| `includeCustom`Type: BooleanDefault: `false` | Whether to include the `custom` object in the fetch response. |
| `ifMatchesEtag`Type: StringDefault: n/a | Use the eTag from an applicable get metadata call to ensure updates only apply if the object hasn’t changed. If the eTags differ, the server returns HTTP 412. |

:::tip API limits
To learn about the maximum length of parameters used to set user metadata, refer to [REST API docs](https://www.pubnub.com/docs/sdks/rest-api/set-user-metadata).
:::

#### Sample code

```java
PNSetUUIDMetadataResult pnSetUUIDMetadataResult = pubNub.setUUIDMetadata()
        .name("Foo")
        .profileUrl("http://example.com")
        .email("foo@example.com")
        .includeCustom(true)
        .sync();
```

#### Response

```java
public class PNSetUUIDMetadataResult extends EntityEnvelope<PNUUIDMetadata> {
    protected int status;
    protected PNUUIDMetadata data;
}

public class PNUUIDMetadata extends PNObject {
    String id;
    Object custom;
    String updated;
    String eTag;
    String name;
    String email;
    String externalId;
    String profileUrl;
}
```

### Remove user metadata

Removes the metadata from a specified UUID.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.removeUUIDMetadata()
    .uuid(String)
```

| Parameter | Description |
| --- | --- |
| `uuid`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |

#### Sample code

```java
pubNub.removeUUIDMetadata().async(result -> { /* check result */ });
```

#### Response

```java
public class PNRemoveUUIDMetadataResult extends EntityEnvelope<JsonElement> {
    int status;
    JsonElement data;
}
```

## Channel

### Get metadata for all channels

Returns a paginated list of channel metadata. Optionally includes Custom.

:::warning Required keyset configuration
To get all channel and user metadata, you must uncheck the
Disallow Get All Channel Metadata
and
Disallow Get All User Metadata
checkboxes in the App Context section of your keyset configuration in the
[Admin Portal](https://admin.pubnub.com)
.
:::

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.getAllChannelsMetadata(
        .limit(Integer)
        .page(PNPage)
        .filter(String)
        .sort(List<PNSortKey>)
        .includeTotalCount(Boolean)
        .includeCustom(Boolean)
```

| Parameter | Description |
| --- | --- |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `includeTotalCount`Type: BooleanDefault: `false` | Whether to include the total count in the paginated response. Default is false. |
| `includeCustom`Type: BooleanDefault: `false` | Whether to include the Custom object in the response. |

#### Sample code

```java
PNGetAllChannelsMetadataResult pnGetAllChannelsMetadataResult = pubNub.getAllChannelsMetadata().sync();
```

#### Response

```java
public class PNGetAllChannelsMetadataResult extends EntityArrayEnvelope<PNChannelMetadata> {
    int status;
    List<PNChannelMetadata> data;
    Integer totalCount;
    String next;
    String prev;
}

public class PNChannelMetadata extends PNObject {
    String id;
    Object custom;
    String updated;
    String eTag;
    String name;
    String description;
}
```

### Get channel metadata

Returns metadata for the specified Channel, optionally including the custom data object for each.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.getChannelMetadata()
    .channel(String)
    .includeCustom(Boolean)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel name. |
| `includeCustom`Type: BooleanDefault: `false` | Whether to include the Custom object in the response. |

#### Sample code

```java
PNGetChannelMetadataResult pnGetChannelMetadataResult = pubNub.getChannelMetadata()
        .channel("myChannel")
        .sync();
```

#### Response

```java
public class PNGetChannelMetadataResult extends EntityEnvelope<PNChannelMetadata> {
    protected int status;
    protected PNChannelMetadata data;
}

public class PNChannelMetadata extends PNObject {
    String id;
    Object custom;
    String updated;
    String eTag;
    String name;
    String description;
}
```

### Set channel metadata

:::warning Unsupported partial updates of custom metadata
The value of the custom metadata parameter sent in this method always overwrites the value stored on PubNub servers. If you want to add new custom data to an existing one, you must:
1. Get the existing metadata and store it locally.
2. Append the new custom metadata to the existing one.
3. Set the entire updated custom object.
:::

Set metadata for a Channel in the database, optionally including the custom data object for each.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.setChannelMetadata()
    .channel(String)
    .name(String)
    .description(String)
    .custom(Map<String, Object>)
    .includeCustom(Boolean)
    .ifMatchesEtag(String)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel ID. |
| `name`Type: StringDefault: n/a | Name for the channel. |
| `description`Type: StringDefault: n/a | Description of a channel. |
| `custom`Type: Map`<String, Object>`Default: n/a | Any object of key-value pairs with supported data types. [App Context filtering language](https://www.pubnub.com/docs/general/metadata/filtering) doesn’t support filtering by custom properties. |
| `includeCustom`Type: BooleanDefault: `false` | Whether to include the `custom` object in the fetch response. |
| `ifMatchesEtag`Type: StringDefault: n/a | The entity tag to be used to ensure updates only happen if the object hasn't been modified since it was read. Use the eTag you received from an applicable get metadata method to check against the server entity tag. If the eTags don't match, an HTTP 412 error is thrown. |

:::tip API limits
To learn about the maximum length of parameters used to set channel metadata, refer to [REST API docs](https://www.pubnub.com/docs/sdks/rest-api/set-channel-metadata).
:::

#### Sample code

```java
pubNub.setChannelMetadata()
        .channel("myChannel")
        .name("Some Name")
        .includeCustom(true)
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNSetChannelMetadataResult extends EntityEnvelope<PNChannelMetadata> {
    protected int status;
    protected PNChannelMetadata data;
}

public class PNChannelMetadata extends PNObject {
    String id;
    Object custom;
    String updated;
    String eTag;
    String name;
    String description;
}
```

#### Other examples

##### Iteratively update existing metadata

```java
import com.pubnub.api.PubNubException;
import com.pubnub.api.UserId;
import com.pubnub.api.java.PubNub;
import com.pubnub.api.java.models.consumer.objects_api.channel.PNChannelMetadata;
import com.pubnub.api.java.models.consumer.objects_api.channel.PNSetChannelMetadataResult;
import com.pubnub.api.java.v2.PNConfiguration;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.equalTo;

public class UpdateCustomChannelMetadataApp {
    public static void main(String[] args) throws PubNubException{
        PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("user01"), "demo").publishKey("demo");

        PubNub pubnub = PubNub.create(configBuilder.build());

        final String channel = "channelId";
        final String channelName = "Channel1on1";
        final String channelDescription = "Channel for 1on1 conversation";
        final String status = "active";
        final String type = "1on1";
        final Map initialCustom = new HashMap();
        initialCustom.put("Days", "Mon-Fri");

        final PNSetChannelMetadataResult setChannelMetadataResult = pubnub.setChannelMetadata()
                .channel(channel)
                .description(channelDescription)
                .name(channelName)
                .custom(initialCustom)
                .includeCustom(true)
                .status(status)
                .type(type)
                .sync();

        final PNChannelMetadata channelMetadataAfterGet = pubnub.getChannelMetadata()
                .channel(channel)
                .includeCustom(true)
                .sync().getData();

        Map<String, Object> updatedCustomMetadata = channelMetadataAfterGet.getCustom().getValue();
        Map<String, Object> additionalMetadata = new HashMap<>();
        additionalMetadata.put("Months", "Jan-May");

        updatedCustomMetadata.putAll(additionalMetadata);

        final PNSetChannelMetadataResult updatedChannelMetadata = pubnub.setChannelMetadata()
                .channel(channel)
                .custom(updatedCustomMetadata)
                .includeCustom(true)
                .sync();

        PNChannelMetadata updatedData = updatedChannelMetadata.getData();

        assertThat(updatedData.getId(),               is(equalTo(channel)));
        assertThat(updatedData.getName().getValue(),  is(equalTo(channelName)));
        assertThat(updatedData.getDescription().getValue(), is(equalTo(channelDescription)));
        assertThat(updatedData.getStatus().getValue(), is(equalTo(status)));
        assertThat(updatedData.getType().getValue(),   is(equalTo(type)));

        Map<String, Object> expectedCustom = new HashMap<>();
        expectedCustom.put("Days",   "Mon-Fri");
        expectedCustom.put("Months", "Jan-May");
        assertThat(updatedData.getCustom().getValue(), is(equalTo(expectedCustom)));

        // clean up
        pubnub.removeChannelMetadata().channel(channel).sync();
        System.exit(0);
    }
}
```

### Remove channel metadata

Removes the metadata from a specified channel.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.removeChannelMetadata()
    .channel(String)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel ID. |

#### Sample code

```java
pubNub.removeChannelMetadata()
        .channel("myChannel")
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNRemoveChannelMetadataResult extends EntityEnvelope<JsonElement> {
    int status;
    protected JsonElement data;
}
```

## Channel memberships

### Get channel memberships

Returns a list of channel memberships for a user. Does not include subscriptions.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.getMemberships()
    .userId(String)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MembershipInclude)
    .async(result -> { /* check result */ });
```

| Parameter | Description |
| --- | --- |
| `userId`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `include`Type: `MembershipInclude`Default: All parameters set to `false` | Object holding the configuration for whether to include additional data in the response. |

#### Sample code

```java
PNGetMembershipsResult pnGetMembershipsResult = pubNub.getMemberships()
        .userId("userId01")
        .limit(10)
        .include(MembershipInclude.builder()
                .includeCustom(true)
                .includeStatus(true)
                .includeType(true)
                .includeTotalCount(true)
                .includeChannel(true)
                .includeChannelCustom(true)
                .includeChannelType(true)
                .includeChannelStatus(true)
                .build())
        .sort(Arrays.asList(PNSortKey.asc(PNSortKey.Key.TYPE)))
        .sync();
```

#### Response

```java
public class PNGetMembershipsResult extends EntityArrayEnvelope<PNMembership> {
    protected Integer totalCount;
    protected String next;
    protected String prev;
    protected int status;
    protected List<PNMembership> data;
}

public class PNMembership {
    PNChannelMetadata channel;
    Object custom;
    String updated;
    String eTag;
}
```

#### Sample code with pagination

```java
final PNGetMembershipsResult getMembershipsResult = pubNub.getMemberships()
        .limit(3)
        .include(MembershipInclude.builder()
                .includeCustom(true)
                .includeStatus(true)
                .includeType(true)
                .includeTotalCount(true)
                .includeChannel(true)
                .build())
        .sync();

if (getMembershipsResult.getNext() != null) {
    final PNGetMembershipsResult getMembershipsNextPageResult = pubNub.getMemberships()
            .page(getMembershipsResult.nextPage())
            .limit(3)
            .include(MembershipInclude.builder()
                    .includeCustom(true)
                    .includeStatus(true)
                    .includeType(true)
                    .includeTotalCount(true)
                    .includeChannel(true)
                    .build())
            .sync();
    System.out.println(getMembershipsNextPageResult);
}
```

### Set channel memberships

Set channel memberships for a User.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.setMemberships(Collection<PNChannelMembership>)
    .userId(String)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MembershipInclude)
    .async(result -> { /* check result */ });
```

| Parameter | Description |
| --- | --- |
| `channelMemberships` *Type: List`<PNChannelMembership>`Default: n/a | Collection of [PNChannelMembership](#pnchannelmembership) to add to membership. |
| `userId`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `include`Type: `MembershipInclude`Default: All parameters set to `false` | Object holding the configuration for whether to include additional data in the response. |

:::tip API limits
To learn about the maximum length of parameters used to set channel membership metadata, refer to [REST API docs](https://www.pubnub.com/docs/sdks/rest-api/set-membership-metadata).
:::

#### PNChannelMembership

`PNChannelMembership` is a utility class that uses the builder pattern to construct a channel membership with additional custom data.

| Parameter | Description |
| --- | --- |
| `channel` *Type: `ChannelId` | The name of the channel associated with this membership. |
| `custom`Type: `Object` | A dictionary that stores custom metadata related to the membership, allowing for additional context or information. |
| `status`Type: `String` | The status of the membership, for example: "active" or "inactive" |
| `type`Type: `String` | The type of membership for categorization purposes. |

#### Sample code

```java
final Map<String, Object> customMap = new HashMap<>();
customMap.putIfAbsent("membership_param1", "val1");
customMap.putIfAbsent("membership_param2", "val2");

PNChannelMembership pnChannelMembership = PNChannelMembership.builder("myChannelId")
        .custom(customMap)
        .status("inactive")
        .type("member")
        .build();

pubNub.setMemberships(Arrays.asList(pnChannelMembership))
        .include(MembershipInclude.builder()
                .includeTotalCount(true)
                .includeCustom(true)
                .includeChannel(true)
                .includeChannelCustom(true)
                .build())
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNSetMembershipResult extends EntityArrayEnvelope<PNMembership> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembership> data;
}

public class PNMembership {
    PNChannelMetadata channel;
    Object custom;
    String updated;
    String eTag;
}
```

### Remove channel memberships

Remove channel memberships for a User.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.removeMemberships(Collection<PNChannelMembership>)
    .userId(String)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MembershipInclude)
    .async(result -> { /* check result */ });
```

| Parameter | Description |
| --- | --- |
| `channelMemberships` *Type: List`<PNChannelMembership>`Default: n/a | Collection of [PNChannelMembership](#pnchannelmembership) to add to membership. |
| `userId`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `include`Type: `MembershipInclude`Default: All parameters set to `false` | Object holding the configuration for whether to include additional data in the response. |

#### Sample code

```java
final Map<String, Object> customMap = new HashMap<>();
customMap.putIfAbsent("membership_param1", "val1");
customMap.putIfAbsent("membership_param2", "val2");

PNRemoveMembershipResult pnRemoveMembershipResult = pubNub.removeMemberships(Arrays.asList("myChannelName"))
        .include(MembershipInclude.builder()
                .includeTotalCount(true)
                .includeCustom(true)
                .includeChannel(true)
                .includeType(true)
                .includeStatus(true)
                .build())
        .sync();
```

#### Response

```java
public class PNRemoveMembershipResults extends EntityArrayEnvelope<PNMembership> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembership> data;
}

public class PNMembership {
    PNChannelMetadata channel;
    Object custom;
    String updated;
    String eTag;
}
```

### Manage channel memberships

Manage a user's channel memberships.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.manageMemberships(Collection<PNChannelMembership>, Collection<String>)
    .userId(String)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MembershipInclude)
    .async(result -> { /* check result */ });
```

| Parameter | Description |
| --- | --- |
| `set` *Type: `Collection<PNChannelMembership>`Default: n/a | List of members [PNChannelMembership](#pnchannelmembership) to add to channel. |
| `remove` *Type: `Collection<Stirng>`Default: n/a | List of members channelIds to remove from channel. |
| `userId`Type: StringDefault: `pubnub.getConfiguration().getUserId().getValue()` | Unique User Metadata identifier. If not supplied, then userId from configuration will be used. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `include`Type: `MembershipInclude`Default: All parameters set to `false` | Object holding the configuration for whether to include additional data in the response. |

#### Sample code

```java
final Map<String, Object> customMap = new HashMap<>();
customMap.putIfAbsent("membership_param1", "val1");
customMap.putIfAbsent("membership_param2", "val2");

final List<PNChannelMembership> channelMembershipsToSet = Collections.singletonList(
        PNChannelMembership.builder("channelId02")
                .custom(customMap)
                .status("inactive")
                .type("member")
                .build());
final List<String> channelIdsToRemove = Collections.singletonList("channelId01");

pubNub.manageMemberships(channelMembershipsToSet, channelIdsToRemove)
        .userId("userId01")
        .include(MembershipInclude.builder()
                .includeTotalCount(true)
                .includeCustom(true)
                .includeChannel(true)
                .includeChannelCustom(true)
                .includeStatus(true)
                .includeType(true)
                .build())
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNManageMembershipResult extends EntityArrayEnvelope<PNMembership> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembership> data;
}

public class PNMembership {
    PNChannelMetadata channel;
    Object custom;
    String updated;
    String eTag;
}
```

## Channel members

### Get channel members

Returns a list of channel members. Includes user metadata when available.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.getChannelMembers(String)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MemberInclude)
    .async(result -> { /* check result */ });
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel ID. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `include`Type: `MemberInclude`Default: All parameters set to `false`. | Object holding the configuration for whether to include additional data in the response. |

#### Sample code

```java
PNGetChannelMembersResult pnGetChannelMembersResult = pubNub.getChannelMembers("testChannelId")
        .include(MemberInclude.builder()
                .includeTotalCount(true)
                .includeStatus(true)
                .includeType(true)
                .includeCustom(true)
                .includeUser(true)
                .includeUserCustom(true)
                .build())
        .sort(Arrays.asList(PNSortKey.desc(PNSortKey.Key.STATUS)))
        .sync();
```

#### Response

```java
public class PNRemoveMembershipResults extends EntityArrayEnvelope<PNMembers> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembers> data;
}

public class PNMembers {
    PNUUIDMetadata uuid;
    Object custom;
    String updated;
    String eTag;
}
```

### Set channel members

This method sets members in a channel.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.setChannelMembers(String, Collection<PNUser>)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MemberInclude)
    .async(result -> { /* check result */ });
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel name. |
| `channelMembers` *Type: [Collection<PNUser>](#pnuser)Default: n/a | List of members to add to channel. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | Cursor-based pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | Sort by `ID`, `NAME`, `UPDATED`, `STATUS`, `TYPE` with asc/desc for sort direction (for example, `PNSortKey.asc(PNSortKey.Key.TYPE)`). |
| `include`Type: `MemberInclude`Default: All parameters set to `false`. | Object holding the configuration for whether to include additional data in the response. |

:::tip API limits
To learn about the maximum length of parameters used to set channel members metadata, refer to [REST API docs](https://www.pubnub.com/docs/sdks/rest-api/set-channel-members-metadata).
:::

#### PNUser

`PNUser` is a utility class that utilizes the builder pattern to facilitate the construction of a user object with additional customization options. This class allows users to define custom metadata, a status, and a type for a user.

| Property | Description |
| --- | --- |
| `userId` *Type: `String` | The unique identifier for the user. This field cannot be null or empty. |
| `custom`Type: `Object` | A dictionary-like object that stores custom metadata related to the user, which provides additional context or information. |
| `status`Type: `String` | The status of the user, which can be any string such as `active` or `inactive`. |
| `type`Type: `String` | The categorization type of the user, allowing for differentiation between user types. |

#### Sample code

```java
final Map<String, Object> customMap = new HashMap<>();
customMap.putIfAbsent("members_param1", "val1");
customMap.putIfAbsent("members_param2", "val2");

final Collection<PNUser> channelMembers = Arrays.asList(
        PNUser.builder("userId1").status("status01").type("typeR").build(),
        PNUser.builder("userId2").custom(customMap).status("status02").type("typeS").build());

pubNub.setChannelMembers("testChannelId", channelMembers)
        .include(MemberInclude.builder()
                .includeCustom(true)
                .includeStatus(true)
                .includeType(true)
                .includeTotalCount(true)
                .includeUser(true)
                .includeUserCustom(true)
                .includeUserStatus(true)
                .includeUserType(true)
                .build())
        .sort(Arrays.asList(PNSortKey.asc(PNSortKey.Key.STATUS)))
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNSetChannelMembersResult extends EntityArrayEnvelope<PNMembers> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembers> data;
}

public class PNMembers {
    PNUUIDMetadata uuid;
    Object custom;
    String updated;
    String eTag;
}
```

### Remove channel members

Remove members from a Channel.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.removeChannelMembers(String, List<String>)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .includeTotalCount(Boolean)
    .includeCustom(Boolean)
    .includeUUID(PNUUIDDetailsLevel)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel name. |
| `channelMembers` *Type: Collection`<String>`Default: n/a | List of member userIds to remove from channel. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | The paging object used for pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | List of properties to sort by. Available options are `PNSortKey.Key.ID`, `PNSortKey.Key.NAME`, `PNSortKey.Key.UPDATED`, `PNSortKey.Key.STATUS` and `PNSortKey.Key.TYPE`. Use `PNSortKey.asc` or `PNSortKey.desc` to specify sort direction. For example: `PNSortKey.asc(PNSortKey.Key.TYPE)` or `PNSortKey.asc(PNSortKey.Key.STATUS)` |
| `include`Type: `MemberInclude`Default: All parameters set to `false` | Object defining options to include additional data in the response. |

#### Sample code

```java
pubNub.removeChannelMembers("channelId", Collections.singletonList("userId"))
        .include(MemberInclude.builder()
                .includeTotalCount(true)
                .includeStatus(true)
                .includeType(true)
                .includeCustom(true)
                .includeUser(true)
                .includeUserCustom(true)
                .build())
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNRemoveChannelMembersResult extends EntityArrayEnvelope<PNMembers> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembers> data;
}

public class PNMembers {
    PNUUIDMetadata uuid;
    Object custom;
    String updated;
    String eTag;
}
```

### Manage channel members

The method Set and Remove channel memberships for a user.

#### Method(s)

Use the following in the Java SDK:

```java
pubnub.manageChannelMembers(String, Collection<PNUser>, Collection<String>)
    .limit(Integer)
    .page(PNPage)
    .filter(String)
    .sort(List<PNSortKey>)
    .include(MemberInclude)
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel name. |
| `set` *Type: [Collection<PNUser>](#pnuser)Default: n/a | List of members to add to channel. |
| `remove` *Type: Collection`<String>`Default: n/a | List of userIds to remove from channel. |
| `limit`Type: IntegerDefault: `100` | Number of objects to return. Default/Max: 100. |
| `page`Type: PNPageDefault: n/a | The paging object used for pagination. |
| `filter`Type: StringDefault: n/a | Filter expression. Only matching objects are returned. See [filtering](https://www.pubnub.com/docs/general/metadata/filtering). |
| `sort`Type: List`<PNSortKey>`Default: `listOf()` | List of properties to sort by. Available options are `PNSortKey.Key.ID`, `PNSortKey.Key.NAME`, `PNSortKey.Key.UPDATED`, `PNSortKey.Key.STATUS` and `PNSortKey.Key.TYPE`. Use `PNSortKey.asc` or `PNSortKey.desc` to specify sort direction. For example: `PNSortKey.asc(PNSortKey.Key.TYPE)` or `PNSortKey.asc(PNSortKey.Key.STATUS)`. |
| `include`Type: `MemberInclude`Default: All parameters set to `false` | Object holding the configuration for whether to include additional data in the response. |

#### Sample code

```java
final Map<String, Object> customMap = new HashMap<>();
customMap.putIfAbsent("members_param1", "val1");
customMap.putIfAbsent("members_param2", "val2");

final List<PNUser> channelMembersToSet = Collections.singletonList(
        PNUser.builder("userId02")
                .custom(customMap)
                .status("status02")
                .type("type02")
                .build());
final List<String> channelMembersIdsToRemove = Collections.singletonList("userId01");

pubNub.manageChannelMembers("channelId", channelMembersToSet, channelMembersIdsToRemove)
        .include(MemberInclude.builder()
                .includeCustom(true)
                .includeStatus(true)
                .includeType(true)
                .includeTotalCount(true)
                .includeUser(true)
                .includeUserCustom(true)
                .includeUserStatus(true)
                .includeUserType(true)
                .build())
        .async(result -> { /* check result */ });
```

#### Response

```java
public class PNManageChannelMembersResult extends EntityArrayEnvelope<PNMembers> {
    Integer totalCount;
    String next;
    String prev;
    int status;
    List<PNMembers> data;
}

public class PNMembers {
    PNUUIDMetadata uuid;
    Object custom;
    String updated;
    String eTag;
}
```

## Terms in this document

* **Channel** - A pathway for sending and receiving messages between devices, created automatically when you first use it, that can handle any number of users and messages for different communication needs, like 1-1 text chats, group conversations, and other data streaming.
* **Channel pattern** - A way to group and analyze channel data to track performance metrics like message counts and user engagement over time with PubNub Insights.
* **User** - An individual or entity that interacts with a system, application, or service. In PubNub, a user typically refers to someone who sends or receives messages through the platform, identified by a unique user ID or username.
* **User ID** - UTF-8 encoded, unique string of up to 92 characters used to identify a single client (end user, device, or server) that connects to PubNub.