---
source_url: https://www.pubnub.com/docs/sdks/android/api-reference/message-actions
title: Message Actions API for Android SDK
updated_at: 2026-05-28T11:16:44.671Z
---

> 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


# Message Actions API for Android SDK

:::warning Unsupported docs
PubNub no longer maintains Android SDK docs, but our [Java SDK](https://www.pubnub.com/docs/sdks/java) or [Kotlin SDK](https://www.pubnub.com/docs/sdks/kotlin) are fully compatible with the Android platform and you can use them to build mobile apps, ensuring stable software development.
:::

Use message actions to add or remove metadata on published messages. Common uses include receipts and reactions. Clients subscribe to a channel to receive message action events. Clients can also fetch past message actions from Message Persistence, either on demand or when fetching original messages.

:::tip Reactions
"Message Reactions" is a specific application of the Message Actions API for emoji or social reactions.
:::

:::note Message Actions vs. Message Reactions
**Message Actions** is the flexible, low-level API for adding any metadata to messages (read receipts, delivery confirmations, custom data), while **Message Reactions** specifically refers to using Message Actions for emoji/social reactions.
In PubNub [Core](https://www.pubnub.com/docs/sdks) and [Chat](https://www.pubnub.com/docs/chat/overview) SDKs, the same underlying Message Actions API is referred to as **Message Reactions** when used for emoji reactions - it's the same functionality, just different terminology depending on the use case.
:::

## Add message action

:::warning Requires Message Persistence
Enable Message Persistence for your key in the [Admin Portal](https://admin.pubnub.com/) as described in the [support article](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-).
:::

Add an action to a published message. The response includes the added action.

### Method(s)

Use this Android method:

```java
this.pubnub.addMessageAction()
    .channel(String)
    .messageAction(PNMessageAction);
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| channel | String | Yes |  | Channel name to add the message action to. |
| messageAction | PNMessageAction | Yes |  | Message action payload (type, value, message timetoken). |
| async | PNCallback | Yes |  | Callback of type `PNAddMessageActionResult`. |

### Sample code

```java
pubnub.addMessageAction()
        .channel("my_channel")
        .messageAction(new PNMessageAction()
                .setType("reaction")
                .setValue("smiley_face")
                .setMessageTimetoken(15701761818730000L)
        )
        .async(new PNCallback<PNAddMessageActionResult>() {
            @Override
            public void onResponse(PNAddMessageActionResult result, PNStatus status) {
                if (!status.isError()) {
                    System.out.println(result.getType());
                    System.out.println(result.getValue());
                    System.out.println(result.getUuid());
                    System.out.println(result.getActionTimetoken());
                    System.out.println(result.getMessageTimetoken());
                } else {
                    status.getErrorData().getThrowable().printStackTrace();
                }
            }
        })
```

### Returns

The `addMessageAction()` operation returns a `PNAddMessageActionResult` which contains the following operations:

| Method | Description |
| --- | --- |
| `getType()`Type: `String` | Message action type. |
| `getValue()`Type: `String` | Message action value. |
| `getUuid()`Type: `String` | Publisher of the message action. |
| `getActionTimetoken()`Type: `Long` | Timestamp when the message action was created. |
| `getMessageTimetoken()`Type: `Long` | Timestamp when the message was created that the action belongs to. |

#### PNMessageAction

| Method | Description |
| --- | --- |
| `setType()`Type: `String` | Message action type. |
| `setValue()`Type: `String` | Message action value. |
| `setMessageTimetoken()`Type: `Long` | Timetoken of the target message. |

## Remove message action

:::warning Requires Message Persistence
Enable Message Persistence for your key in the [Admin Portal](https://admin.pubnub.com/) as described in the [support article](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-).
:::

Remove a previously added action from a published message. The response is empty.

### Method(s)

Use this Android method:

```java
this.pubnub.removeMessageAction()
    .channel(String)
    .messageTimetoken(Long)
    .actionTimetoken(Long);
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: String | Channel name to remove the message action from. |
| `messageTimetoken` *Type: Long | Timetoken of the target message. |
| `actionTimetoken` *Type: Long | Timetoken of the message action to remove. |
| `async` *Type: PNCallback | Callback of type `PNRemoveMessageActionResult`. |

### Sample code

```java
pubnub.removeMessageAction()
        .channel("my_channel")
        .messageTimetoken(15701761818730000L)
        .actionTimetoken(15701775691010000L)
        .async(new PNCallback<PNRemoveMessageActionResult>() {
            @Override
            public void onResponse(PNRemoveMessageActionResult result, PNStatus status) {
                if (!status.isError()) {
                    // result has no actionable data
                    // it's enough to check if the status itself is not an error
                } else {
                    status.getErrorData().getThrowable().printStackTrace();
                }
            }
        });
```

### Returns

The `removeMessageAction()` operation returns no actionable data.

## Get message actions

:::warning Requires Message Persistence
Enable Message Persistence for your key in the [Admin Portal](https://admin.pubnub.com/) as described in the [support article](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-).
:::

Get a list of message actions in a channel. The response sorts actions by the action timetoken in ascending order.

:::note Truncated response
The number of message actions in the response may be truncated when internal limits are hit. If the response is truncated, a `more` property is returned with additional parameters. Send iterative calls to Message Persistence, adjusting the parameters to fetch more message actions.
:::

### Method(s)

Use this Android method:

```java
this.pubnub.getMessageActions()
    .channel(String)
    .start(Long)
    .end(Long)
    .limit(Integer);
```

| Parameter | Description |
| --- | --- |
| `channel` *Type: StringDefault: n/a | Channel name to list message actions for. |
| `start`Type: LongDefault: n/a | Message action timetoken for the start of the range (exclusive). |
| `end`Type: LongDefault: n/a | Message action timetoken for the end of the range (inclusive). |
| `limit`Type: IntegerDefault: 100 | Maximum number of actions to return. Default/Maximum is `100`. |
| `async` *Type: PNCallbackDefault: n/a | Callback of type `PNGetMessageActionsResult`. |

### Sample code

```java
pubnub.getMessageActions()
        .channel("my_channel")
        .async(new PNCallback<PNGetMessageActionsResult>() {
            @Override
            public void onResponse(PNGetMessageActionsResult result, PNStatus status) {
                if (!status.isError()) {
                    List<PNMessageAction> actions = result.getActions();
                    for (PNMessageAction action : actions) {
                        System.out.println(action.getType());
                        System.out.println(action.getValue());
                        System.out.println(action.getUuid());
                        System.out.println(action.getActionTimetoken());
                        System.out.println(action.getMessageTimetoken());
                    }
                } else {
                    status.getErrorData().getThrowable().printStackTrace();
                }
            }
        });
```

### Returns

The `getMessageActions()` operation returns a list of `PNGetMessageActionsResult` objects, each containing the following operations:

| Method | Description |
| --- | --- |
| `getType()`Type: `String` | Message action type. |
| `getValue()`Type: `String` | Message action value. |
| `getUuid()`Type: `String` | Publisher of the message action. |
| `getActionTimetoken()`Type: `Long` | Timestamp when the message action was created. |
| `getMessageTimetoken()`Type: `Long` | Timestamp when the message was created that the action belongs to. |

### Other examples

#### Fetch messages with paging

```java
public static void main(String args[]){
    getMessageActionsWithPaging("my_channel", System.currentTimeMillis() * 10_000L, new Callback() {
            @Override
            public void onMore(List<PNMessageAction> actions) {
                System.out.println("Next set of actions: " + actions.size());
            }

            @Override
            public void onDone() {
                System.out.println("All actions fetched");
            }
        });
}

/**
    * Fetches 5 message actions at a time, recursively and in a paged manner.
    *
    * @param channel  The channel where the message is published, to fetch message actions from.
    * @param start    The timetoken which indicates from where to start fetching message actions.
    * @param callback The callback to dispatch fetched message actions to.
    */
static void getMessageActionsWithPaging(String channel, Long start, Callback callback) {
    pubnub.getMessageActions()
            .channel(channel)
            .start(start)
            .limit(5)
            .async(new PNCallback<PNGetMessageActionsResult>() {
                @Override
                public void onResponse(PNGetMessageActionsResult result, PNStatus status) {
                    if (!status.isError() && !result.getActions().isEmpty()) {
                        callback.onMore(result.getActions());
                        getMessageActionsWithPaging(channel,
                            result.getActions().get(0).getActionTimetoken(), callback);
                    } else {
                        callback.onDone();
                    }
                }
            });
}

interface Callback {
    void onMore(List<PNMessageAction> actions);

    void onDone();
}
```

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