# RestAnnotations
The `RestAnnotations` object lets you publish, delete, and retrieve [annotations](https://ably.com/docs/messages/annotations.md) on messages. Access it via the `annotations` property of a [`Channel`](https://ably.com/docs/pub-sub/api/javascript/rest/channel.md).
Subscribing to individual annotations in realtime requires the [realtime SDK's `RealtimeAnnotations`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-annotations.md) interface.
#### Javascript
```
const annotations = channel.annotations;
```
## 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/rest/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/rest/rest-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/rest/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/rest/rest-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/rest/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/rest/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/rest/rest-client.md#PaginatedResult) containing an array of `Annotation` objects, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/rest/rest-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 |
| 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.Rest.Annotation`. The returned promise resolves with the decoded annotation.
### Javascript
```
const annotation = await Ably.Rest.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/rest/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.Rest.Annotation.fromEncodedArray(encodedAnnotations);
```
### Parameters
The `Annotation.fromEncodedArray()` method takes the following parameters:
### 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/rest/channels.md): API reference for the Channels interface in the Ably Pub/Sub JavaScript REST SDK.
- [Channel](https://ably.com/docs/pub-sub/api/javascript/rest/channel.md): API reference for the Channel interface in the Ably Pub/Sub JavaScript REST SDK.
- [ChannelDetails](https://ably.com/docs/pub-sub/api/javascript/rest/channel-details.md): API reference for channel metadata (ChannelDetails) in the Ably Pub/Sub JavaScript REST SDK.
- [Message](https://ably.com/docs/pub-sub/api/javascript/rest/message.md): API reference for the Message interface in the Ably Pub/Sub JavaScript REST 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.