# RealtimeAnnotations The `RealtimeAnnotations` object lets you publish, delete, retrieve, and subscribe to [annotations](https://ably.com/docs/messages/annotations.md) on messages. Access it via the `annotations` property of a [`RealtimeChannel`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md). #### Javascript ``` const annotations = channel.annotations; ``` ## Subscribe to annotations `annotations.subscribe(type: string | string[], listener?: messageCallback): Promise` Register a listener that is called each time an `Annotation` matching one of the given types is received on the channel. `annotations.subscribe(listener?: messageCallback): Promise` Register a listener that is called each time any `Annotation` is received on the channel, regardless of type. To receive individual realtime annotations (instead of just the rolled-up summaries), the `annotation_subscribe` [channel mode](https://ably.com/docs/channels/options.md#modes) must be requested, since annotations are not delivered by default. Most clients will not need this and can rely on the summary updates instead. ### Parameters | Parameter | Required | Description | Type | | --- | --- | --- | --- | | type | Optional | A specific annotation type, or an array of types, to register the listener for. | String or `String[]` | | listener | Optional | A function called with each matching `Annotation`. | `messageCallback` |
### Returns `Promise` Returns a promise. The promise is fulfilled once the listener has been registered, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object. ## Publish an annotation `annotations.publish(message: Message, annotation: OutboundAnnotation): Promise` Publish an annotation to a message identified by a `Message` object. `annotations.publish(messageSerial: string, annotation: OutboundAnnotation): Promise` Publish an annotation to a message identified by its serial string. The `action` is set automatically to `annotation.create`. If a `clientId` is set on the client, it is associated with the annotation; some annotation summarization methods require an [identified client](https://ably.com/docs/auth/identified-clients.md). ### Parameters | Parameter | Required | Description | Type | | --- | --- | --- | --- | | message | Required | A `Message` object identifying the message to annotate. Provide either `message` or `messageSerial`. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) | | messageSerial | Required | The serial string of the message to annotate. Provide either `message` or `messageSerial`. | String | | annotation | Required | The annotation to publish. Must include at least a `type`; other required fields depend on the annotation type. |
|
### Returns `Promise` Returns a promise. The promise is fulfilled when the annotation has been published to Ably, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object. ## Delete an annotation `annotations.delete(message: Message, annotation: OutboundAnnotation): Promise` Remove an annotation contribution from a message identified by a `Message` object. `annotations.delete(messageSerial: string, annotation: OutboundAnnotation): Promise` Remove an annotation contribution from a message identified by its serial string. This removes the contribution this `clientId` previously made to the annotation summary for the message. The exact [behaviour depends on the annotation type](https://ably.com/docs/messages/annotations.md#delete). The `action` is set automatically to `annotation.delete`. The annotation must include a `type` and may include a `name`. ### Parameters | Parameter | Required | Description | Type | | --- | --- | --- | --- | | message | Required | A `Message` object identifying the message whose annotation you want to delete. Provide either `message` or `messageSerial`. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) | | messageSerial | Required | The serial string of the message whose annotation you want to delete. Provide either `message` or `messageSerial`. | String | | annotation | Required | The annotation deletion request. Must include at least a `type`; other required fields depend on the annotation type. |
|
### Returns `Promise` Returns a promise. The promise is fulfilled when the deletion request has been published to Ably, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object. ## Get annotations for a message `annotations.get(message: Message, params: GetAnnotationsParams | null): Promise>` Retrieve all annotations for a message identified by a `Message` object. `annotations.get(messageSerial: string, params: GetAnnotationsParams | null): Promise>` Retrieve all annotations for a message identified by its serial string. Annotations are returned ordered from earliest to most recent. If you only need the latest summary, prefer [`channel.getMessage()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md#get-message); use `annotations.get()` only when you need the full list of raw annotations. ### Parameters | Parameter | Required | Description | Type | | --- | --- | --- | --- | | message | Required | A `Message` object identifying the message to get annotations for. Provide either `message` or `messageSerial`. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) | | messageSerial | Required | The serial string of the message to get annotations for. Provide either `message` or `messageSerial`. | String | | params | Required | Restrictions on which annotations to return, in particular a limit. Pass `null` to apply no restrictions; the argument cannot be omitted. |
or Null |
### Returns `Promise>` Returns a promise, fulfilled with a [`PaginatedResult`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#PaginatedResult) containing an array of `Annotation` objects, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object. | Property | Description | Type | | --- | --- | --- | | id | Unique ID assigned by Ably to this annotation. | String | | clientId | The client ID of the publisher of this annotation, if any. | String | | name | The name of the annotation. This is the field that most annotation aggregations operate on. | String | | count | An optional count, only relevant to the `multiple.v1` annotation type. | Number | | data | An optional publisher-provided payload. Available on individual annotations but not aggregated or included in [annotation summaries](https://ably.com/docs/messages/annotations.md#annotation-summaries). | Any | | encoding | The encoding of the payload; typically empty as annotations received from Ably are automatically decoded client-side using this value. However, if the annotation encoding cannot be processed, this attribute contains the remaining transformations not applied to the `data` payload. | String | | timestamp | Timestamp of when the annotation was received by Ably, as milliseconds since the Unix epoch. | Number | | action | The action, whether this is an annotation being added or removed. |
| | serial | This annotation's unique serial, lexicographically totally ordered. | String | | messageSerial | The serial of the message that this annotation is annotating. | String | | type | The annotation type, typically a name together with an aggregation method, for example `emoji:distinct.v1`. | String | | extras | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish.md#payload), `headers` (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced.md#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/skip-integrations.md) objects. | Any |
## Unsubscribe from annotations `annotations.unsubscribe(type: string | string[], listener: messageCallback): void` Remove the given listener for the specified annotation type or types. `annotations.unsubscribe(type: string | string[]): void` Remove all listeners registered for the specified annotation type or types. `annotations.unsubscribe(listener: messageCallback): void` Remove the given listener from all annotation types. `annotations.unsubscribe(): void` Remove all annotation listeners on the channel. ### Parameters | Parameter | Required | Description | Type | | --- | --- | --- | --- | | type | Optional | A specific annotation type, or an array of types, to deregister listeners for. | String or `String[]` | | listener | Optional | The specific listener function to deregister. | `messageCallback` |
| Property | Required | Description | Type | | --- | --- | --- | --- | | type | Required | The annotation type, typically a name together with an aggregation method, for example `emoji:distinct.v1`. Handled opaquely by the SDK and validated server-side. | String | | name | Optional | The name of the annotation. This is the field that most annotation aggregations operate on. | String | | count | Optional | An optional count, only relevant to the `multiple.v1` annotation type. | Number | | data | Optional | An optional publisher-provided payload. Available on individual annotations but not aggregated or included in [annotation summaries](https://ably.com/docs/messages/annotations.md#annotation-summaries). | Any | | encoding | Optional | The encoding of the payload. | String | | extras | Optional | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish.md#payload), `headers` (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced.md#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/skip-integrations.md) objects. | Any |
| Property | Required | Description | Type | | --- | --- | --- | --- | | limit | Optional | An upper limit on the number of annotations returned. The default is 100, and the maximum is 1000. | Number |
| Value | Description | | --- | --- | | annotation.create | The annotation is being added. | | annotation.delete | The annotation is being removed. |
## Create an annotation from an encoded object `Annotation.fromEncoded(encodedAnnotation: Object, channelOptions?: ChannelOptions): Promise` A static factory method to create an `Annotation` from a deserialized `Annotation`-like object encoded using Ably's wire protocol. Accessed on the class as `Ably.Realtime.Annotation`. The returned promise resolves with the decoded annotation. ### Javascript ``` const annotation = await Ably.Realtime.Annotation.fromEncoded(encodedAnnotation); ``` ### Parameters The `Annotation.fromEncoded()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | encodedAnnotation | Required | An `Annotation`-like deserialized object. | Object | | channelOptions | Optional | If you have an encrypted channel, use this to allow the SDK to decrypt the data. | [ChannelOptions](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) |
### Returns `Promise` Returns a promise that resolves with an `Annotation` object decoded from the supplied object. ## Create annotations from an encoded array `Annotation.fromEncodedArray(encodedAnnotations: Object[], channelOptions?: ChannelOptions): Promise` A static factory method to create an array of `Annotation` objects from an array of deserialized `Annotation`-like objects encoded using Ably's wire protocol. The returned promise resolves with the decoded annotations. ### Javascript ``` const annotations = await Ably.Realtime.Annotation.fromEncodedArray(encodedAnnotations); ``` ### Parameters The `Annotation.fromEncodedArray()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | encodedAnnotations | Required | An array of `Annotation`-like deserialized objects. | `Array` | | channelOptions | Optional | If you have an encrypted channel, use this to allow the SDK to decrypt the data. | [ChannelOptions](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) |
### Returns `Promise` Returns a promise that resolves with an array of `Annotation` objects decoded from the supplied array. ## Related Topics - [Channels](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md): API reference for the Channels interface in the Ably Pub/Sub JavaScript Realtime SDK. - [RealtimeChannel](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md): API reference for the Channel (RealtimeChannel) interface in the Ably Pub/Sub JavaScript Realtime SDK. - [ChannelDetails](https://ably.com/docs/pub-sub/api/javascript/realtime/channel-details.md): API reference for channel metadata (ChannelDetails) in the Ably Pub/Sub JavaScript Realtime SDK. - [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md): API reference for the Message interface in the Ably Pub/Sub JavaScript Realtime SDK. ## Documentation Index To discover additional Ably documentation: 1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages. 2. Identify relevant URLs from that index. 3. Fetch target pages as needed. Avoid using assumed or outdated documentation paths.