# RealtimeChannel
A `RealtimeChannel` represents a single channel, obtained via the [`channels.get()`](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) method. Use it to publish and subscribe to messages, manage channel state, and access channel features such as presence, push notifications, and annotations.
#### Javascript
```
const channel = realtime.channels.get('your-channel-name');
```
## Properties
The `RealtimeChannel` interface has the following properties:
| Property | Description | Type |
| --- | --- | --- |
| name | The name of this channel. | String |
| state | The current [channel state](https://ably.com/docs/channels/states.md). | |
| errorReason | When a channel failure occurs, this property contains the error. | [ErrorInfo](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) or Undefined |
| presence | Access the [`RealtimePresence`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md) object for this channel. | [RealtimePresence](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md) |
| push | Access the [`PushChannel`](https://ably.com/docs/pub-sub/api/javascript/realtime/push.md) object for this channel. | [PushChannel](https://ably.com/docs/pub-sub/api/javascript/realtime/push.md) |
| annotations | Access the `RealtimeAnnotations` object for this channel, used to publish, delete, retrieve, and subscribe to [annotations](https://ably.com/docs/messages/annotations.md) on messages. | [RealtimeAnnotations](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-annotations.md) |
| params | The current [channel parameters](https://ably.com/docs/channels/options.md#params) in effect for this channel. | `Record` |
| modes | The current [channel modes](https://ably.com/docs/channels/options.md#modes) in effect for this channel. | `ResolvedChannelMode[]` |
| Value | Description |
| --- | --- |
| initialized | The channel has been initialized but no attach has yet been attempted. |
| attaching | An attach has been initiated by sending a request to Ably. This is a transient state and will be followed by `attached` or `failed`. |
| attached | The attach has succeeded. In the `attached` state, a client may publish, subscribe to, and be present in the channel. |
| detaching | A detach has been initiated on an `attached` channel by sending a request to Ably. |
| detached | The channel has been detached or the channel has not been attached. |
| suspended | The channel was previously attached, but the client is now disconnected and the SDK is unable to communicate with the Ably service. Any messages published while in this state are buffered for delivery once the channel becomes attached again. |
| failed | An indefinite failure condition. This state is entered if a channel error has been received from the Ably service, such as an attempt to attach without the necessary access rights. |
## Subscribe to messages
`channel.subscribe(listener: messageCallback): Promise`
Subscribe to all messages on this channel. The listener is called for every message received.
`channel.subscribe(event: string, listener?: messageCallback): Promise`
Subscribe only to messages with a specific event name (client-side filter).
`channel.subscribe(events: string[], listener?: messageCallback): Promise`
Subscribe to messages matching any event name in the array (client-side filter).
`channel.subscribe(filter: MessageFilter, listener?: messageCallback): Promise`
Register a listener for messages on this channel that match the supplied filter. Filtering happens server-side as part of [filtered subscriptions](https://ably.com/docs/pub-sub/advanced.md#subscription-filters).
### Javascript
```
// All messages
await channel.subscribe((message) => {
console.log(message.name, message.data);
});
// Specific event
await channel.subscribe('greeting', (message) => {
console.log('Hi:', message.data);
});
// Server-side filter (filtered subscription)
await channel.subscribe({ name: 'click', clientId: 'user-123' }, (message) => {
console.log('Filtered:', message.data);
});
```
If the channel is `initialized`, calling `subscribe()` implicitly attaches the channel.
Calling `subscribe()` with an event name is a client-side filter. All messages are still sent over the wire, regardless of name. To filter messages server-side, use [filtered subscriptions](https://ably.com/docs/pub-sub/advanced.md#subscription-filters) with a `filter` argument.
When subscribing, keep the following behaviours in mind:
* If `subscribe()` is called more than once with the same listener, duplicates are registered. If you subscribe twice with the same listener and a message is later received, that listener is invoked twice.
* A registered listener remains active on the channel regardless of the current channel state. If you subscribe when a channel is `attached` and it later becomes `detached` or `failed`, the listener is still invoked when the channel reattaches and a message is received. Listeners are only removed by calling [`unsubscribe()`](#unsubscribe) or when the channel is released using [`channels.release()`](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#release).
* If an exception is thrown in a listener and bubbles up to the event emitter, it is caught and logged at `error` level, so as not to affect other listeners for the same event.
### Parameters
The `subscribe()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| event | Optional | The event name to subscribe to. | String |
| events | Optional | An array of event names to subscribe to. | `String[]` |
| filter | Optional | A filter object used to filter messages server-side. | |
| listener | Optional | A function called with each matching [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md). Required when subscribing to all messages; with an `event`, `events`, or `filter` argument it may be omitted to attach the channel without registering a listener. | Function |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| name | Optional | A regular expression to match against the message name. | String |
| refTimeserial | Optional | A reference timeserial to match against. Useful for filtering message updates or annotations against the original message. | String |
| refType | Optional | A reference type to match against (for example `com.ably.reaction` for reactions). | String |
| isRef | Optional | Whether to match only messages that have a ref (`true`), only those that don't (`false`), or both (omitted). | Boolean |
| clientId | Optional | A `clientId` to match against. | String |
### Returns
`Promise`
Returns a promise. On successful channel attachment, the promise is fulfilled with a `ChannelStateChange`. If the channel was already attached, the promise resolves with `null`. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Publish a message
`channel.publish(name: string, data: any, options?: PublishOptions): Promise`
Publish a single message on the channel based on a given event name and payload.
`channel.publish(message: Message, options?: PublishOptions): Promise`
Publish a single message object on the channel.
`channel.publish(messages: Message[], options?: PublishOptions): Promise`
Publish multiple messages atomically on the channel. This means that:
* Either all messages will be successfully published or none of them will.
* The [max message size](https://ably.com/docs/platform/pricing/limits.md#message) limit applies to the total size of all messages in the array.
* The publish counts as a single message for the purpose of [per-channel rate limit](https://ably.com/docs/platform/pricing/limits.md#message).
* If you are using client-specified message IDs, they must conform to certain restrictions.
When `publish()` is called, the SDK will not implicitly attach to the channel so long as [transient publishing](https://ably.com/docs/pub-sub/advanced.md#transient-publish) is available. Otherwise, it will implicitly attach.
### Javascript
```
await channel.publish('greeting', 'Hello, World!');
// Or with a Message object
await channel.publish({ name: 'greeting', data: 'Hello' });
// Or atomic batch
await channel.publish([
{ name: 'event1', data: 'one' },
{ name: 'event2', data: 'two' }
]);
```
### Parameters
The `publish()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| name | Required | The event name. | String |
| data | Required | The data payload for the message. Supported payload types are strings, JSON-serializable objects and arrays, buffers containing arbitrary binary data, and `null`. If sending binary data, that binary should be the entire payload; an object with a binary field within it may not be correctly encoded. | Any |
| message | Required | A single [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) object to publish. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) |
| messages | Required | An array of [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) objects to publish atomically. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md)[] |
| options | Optional | An open map of server-defined publish options (string, number, or boolean values). The SDK passes these through as publish parameters; the set of valid options is defined by the Ably service, not the SDK. | Object |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with a `PublishResult` when the message(s) have been delivered to Ably, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
| Property | Description | Type |
| --- | --- | --- |
| serials | An array of message serials corresponding 1:1 to the messages that were published. A serial may be `null` if the message was discarded due to a [message conflation](https://ably.com/docs/messages.md#conflation). | Array of String or Null |
## Update a message
`channel.updateMessage(message: Message, operation?: MessageOperation, options?: PublishOptions): Promise`
Publish an [update](https://ably.com/docs/messages/updates-deletes.md#update) to an existing message using shallow mixin semantics. Non-null `name`, `data`, and `extras` fields in the provided message replace the corresponding fields in the existing message; null fields are left unchanged. Requires the `message-update-own` or `message-update-any` [capability](https://ably.com/docs/auth/capabilities.md).
### Parameters
The `updateMessage()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| message | Required | The message to update. Must include the `serial` of the message being updated. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) |
| operation | Optional | Metadata about the update operation. | |
| options | Optional | Server-defined options affecting the publish of the update. | Object |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| clientId | Optional | The client ID performing the operation. | String |
| description | Optional | A human-readable description of why the operation was performed. | String |
| metadata | Optional | Additional metadata associated with the operation. | `Record` |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with an `UpdateDeleteResult` containing the updated version metadata, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
| Property | Description | Type |
| --- | --- | --- |
| versionSerial | The serial of the new version of the message produced by the update, delete, or append operation. `null` if the message was superseded by a subsequent update before it could be published. | String or Null |
## Append to a message
`channel.appendMessage(message: Message, operation?: MessageOperation, options?: PublishOptions): Promise`
[Append](https://ably.com/docs/messages/updates-deletes.md#append) data to an existing message on the channel. The supplied `data` is appended to the previous message's data, while `name` and `extras` replace the previous values if provided. Subscribers receive a `message.append` action. Requires the `message-update-own` or `message-update-any` [capability](https://ably.com/docs/auth/capabilities.md).
### Parameters
The `appendMessage()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| message | Required | The message to append data to. Must include the `serial` of the target message. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) |
| operation | Optional | Metadata about the append operation. | |
| options | Optional | Server-defined options affecting the publish of the append. | Object |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with an `UpdateDeleteResult`, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Delete a message
`channel.deleteMessage(message: Message, operation?: MessageOperation, options?: PublishOptions): Promise`
Mark a message as [deleted](https://ably.com/docs/messages/updates-deletes.md#delete) by publishing an update with an action of `MESSAGE_DELETE`. This does not remove the message from the server, and the full message history remains accessible. Uses shallow mixin semantics: non-null `name`, `data`, and `extras` fields in the provided message replace the corresponding fields in the existing message; null fields are left unchanged. Subscribers receive a `message.delete` action. Requires the `message-delete-own` or `message-delete-any` [capability](https://ably.com/docs/auth/capabilities.md).
### Parameters
The `deleteMessage()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| message | Required | The message to delete. Must include the `serial` of the message being deleted. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) |
| operation | Optional | Metadata about the delete operation. | |
| options | Optional | Server-defined options affecting the publish of the delete. | Object |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with an `UpdateDeleteResult`, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Get a single message by serial
`channel.getMessage(serialOrMessage: string | Message): Promise`
Retrieve the [latest version](https://ably.com/docs/messages/updates-deletes.md#get) of a message by its serial. Requires the `history` [capability](https://ably.com/docs/auth/capabilities.md).
### Parameters
The `getMessage()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| serialOrMessage | Required | Either the serial identifier string of the message to retrieve, or a [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) object containing a populated `serial` field. | String or [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with the [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md), or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Unsubscribe from messages
`channel.unsubscribe(event: string, listener: messageCallback): void`
Remove the given listener for the specified event.
`channel.unsubscribe(events: string[], listener: messageCallback): void`
Remove the given listener from all events in the array.
`channel.unsubscribe(event: string): void`
Remove all listeners registered for the specified event.
`channel.unsubscribe(events: string[]): void`
Remove all listeners registered for any event in the array.
`channel.unsubscribe(filter: MessageFilter, listener?: messageCallback): void`
Remove the listener registered for the specified filter, or all listeners for the filter if `listener` is omitted.
`channel.unsubscribe(listener: messageCallback): void`
Remove the given listener from all events.
`channel.unsubscribe(): void`
Remove all message listeners on this channel.
### Javascript
```
channel.unsubscribe();
```
### Parameters
The `unsubscribe()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| event | Optional | A single event name to stop listening to. | String |
| events | Optional | An array of event names to stop listening to. | `String[]` |
| filter | Optional | The message filter whose listener should be removed. | |
| listener | Optional | The listener to remove. If omitted, all listeners matching the supplied event(s) or filter are removed; if no arguments are given, all message listeners on the channel are removed. | Function |
## Attach to the channel
`channel.attach(): Promise`
Attach to the channel. This first attempts to connect to Ably if not already connected, then sends an attach message for this channel. If the channel is already attached, this is a no-op and the promise resolves with `null`.
As a convenience, `attach()` is called implicitly if [`subscribe()`](#subscribe) is called on the channel, or if [`presence.enter()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md#enter) or [`presence.subscribe()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md#subscribe) is called on the channel's presence.
### Javascript
```
await channel.attach();
```
### Returns
`Promise`
Returns a promise. The promise is fulfilled with a `ChannelStateChange` describing the transition to `attached`, or `null` if the channel was already attached. Rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object if the attach fails.
## Detach from the channel
`channel.detach(): Promise`
Detach from the channel. Any resulting channel state change is emitted to listeners registered using [`on()`](#on) or [`once()`](#once). Once all clients globally have detached from the channel, the channel is released in the Ably service within two minutes.
### Javascript
```
await channel.detach();
```
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the channel has been detached, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Set channel options
`channel.setOptions(options: ChannelOptions): Promise`
Configure the channel with new `ChannelOptions`. If the channel is already attached and the new options require a re-attach (for example, new channel modes or new params), the channel will be re-attached with the new options.
### Javascript
```
await channel.setOptions({ cipher: { key } });
```
### Parameters
The `setOptions()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| options | Required | The new channel options. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| cipher | Optional | Requests [encryption](https://ably.com/docs/channels/options/encryption.md) for this channel when not null, and specifies encryption-related parameters (such as algorithm, chaining mode, key length, and key). | or |
| params | Optional | [Channel parameters](https://ably.com/docs/channels/options.md) that configure the behavior of the channel. | `Record` |
| modes | Optional | An array of channel mode values that restrict the operations a client can perform on a channel. | Array of |
| attachOnSubscribe | Optional | Whether calling [`subscribe()`](#subscribe) on a channel or presence object should trigger an implicit attach. Default: `true`. | Boolean |
| Property | Description | Type |
| --- | --- | --- |
| key | The private key used for encryption and decryption. Do not set this value directly; pass a key to [`Crypto.getDefaultParams()`](https://ably.com/docs/pub-sub/api/javascript/realtime/crypto.md#get-default-params) instead. | `unknown` |
| algorithm | The name of the algorithm. Default: `AES`. | String |
| keyLength | The key length in bits of the cipher. Either 128 or 256. Default: 256. | Number |
| mode | The cipher mode. Default: `CBC`. | String |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| key | Required | The private key used for encryption and decryption. Can be binary or base64-encoded. | `ArrayBuffer`, `Uint8Array`, or String |
| algorithm | Optional | The name of the algorithm. Default: `AES`. | String |
| keyLength | Optional | The key length in bits. Either 128 or 256. Default: 256. | Number |
| mode | Optional | The cipher mode. Default: `CBC`. | String |
| Value | Description |
| --- | --- |
| PUBLISH | The client can publish messages to the channel. |
| SUBSCRIBE | The client can subscribe to messages on the channel. |
| PRESENCE | The client can enter the presence set on the channel. |
| PRESENCE_SUBSCRIBE | The client can subscribe to presence events on the channel. |
| OBJECT_PUBLISH | The client can publish LiveObjects messages on the channel. |
| OBJECT_SUBSCRIBE | The client can subscribe to LiveObjects messages on the channel. |
| ANNOTATION_PUBLISH | The client can publish annotations on the channel. |
| ANNOTATION_SUBSCRIBE | The client can subscribe to annotations on the channel. |
### Returns
`Promise`
Returns a promise. The promise is fulfilled once the options have been applied (and the channel re-attached if required), or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Register a channel state listener
`channel.on(event: ChannelEvent, listener: channelEventCallback): void`
Register a listener for a single channel event.
`channel.on(events: ChannelEvent[], listener: channelEventCallback): void`
Register a listener for any of an array of channel events.
`channel.on(listener: channelEventCallback): void`
Register a listener for all channel events.
In every form the listener receives a `ChannelStateChange` object describing the transition.
If an exception is thrown in the listener and bubbles up to the event emitter, it is caught and logged at `error` level, so as not to affect other listeners.
### Javascript
```
channel.on('attached', (stateChange) => {
console.log('Now attached');
});
```
### Parameters
The `on()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| event | Optional | A single channel event to listen for. | |
| events | Optional | An array of channel events to listen for. | [] |
| listener | Required | A function invoked for each matching event. If neither `event` nor `events` is supplied, it fires for every event. | |
| Value | Description |
| --- | --- |
| initialized | The channel has been initialized but no attach has yet been attempted. |
| attaching | An attach has been initiated by sending a request to Ably. |
| attached | The attach has succeeded. |
| detaching | A detach has been initiated. |
| detached | The channel has been detached. |
| suspended | The channel has been suspended. |
| failed | The channel has entered a failed state. |
| update | An update to the channel has occurred (typically a re-attach with updated capability or channel options) while the channel state remains `attached`. |
| Parameter | Description | Type |
| --- | --- | --- |
| stateChange | The channel state change that occurred. | |
| Property | Description | Type |
| --- | --- | --- |
| current | The new channel state. | |
| previous | The previous channel state. For the `update` event, this will be equal to the `current` state. | |
| event | The event that triggered this state change. | |
| reason | An `ErrorInfo` containing any information relating to the transition. | [ErrorInfo](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) or Undefined |
| resumed | When the channel has reattached after a loss of connection, `resumed` is `true` if message continuity is preserved (no missed messages), or `false` if it was not. | Boolean |
| hasBacklog | Indicates whether the client can expect a backlog of messages from a [rewind](https://ably.com/docs/channels/options/rewind.md) or resume. | Boolean or Undefined |
## Register a one-time channel state listener
`channel.once(event: ChannelEvent, listener: channelEventCallback): void`
Register a one-time listener for a single channel event. It is invoked the next time that event occurs, then removed.
`channel.once(listener: channelEventCallback): void`
Register a one-time listener for the next channel event of any type.
`channel.once(event: ChannelEvent): Promise`
Return a promise that resolves the next time the specified event occurs.
`channel.once(): Promise`
Return a promise that resolves the next time any event occurs.
The callback-based forms return `void`; the promise-based forms return a promise that resolves with the next matching `ChannelStateChange`.
If an exception is thrown in the listener and bubbles up to the event emitter, it is caught and logged at `error` level, so as not to affect other listeners.
### Javascript
```
await channel.once('attached');
```
### Parameters
The `once()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| event | Optional | The channel event to listen for. If omitted, the listener fires for any event. | |
| listener | Optional | A function invoked once with the next matching event. Omit to return a promise instead. | |
### Returns
The callback-based overloads return `void`.
The promise-based overloads return `Promise`, fulfilled with a `ChannelStateChange` the next time a matching event occurs.
## Remove a channel state listener
`channel.off(event: ChannelEvent, listener: channelEventCallback): void`
Remove the given listener for a specific channel event.
`channel.off(listener: channelEventCallback): void`
Remove the given listener from all channel events.
`channel.off(): void`
Remove all channel state listeners.
### Javascript
```
channel.off();
```
### Parameters
The `off()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| event | Optional | The channel event to stop listening to. If omitted, the listener is removed from all events. | |
| listener | Optional | The listener to remove. If omitted, all listeners (for the given event, or for the whole channel) are removed. | |
## Get registered listeners
`channel.listeners(eventName?: ChannelEvent): null | channelEventCallback[]`
Returns the channel state listeners registered for the specified `ChannelEvent`. If `eventName` is omitted, returns all registered listeners. Returns `null` if there are no matching listeners.
### Parameters
The `listeners()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| eventName | Optional | The channel event to filter listeners by. | |
### Returns
`null | channelEventCallback[]`
Returns an array of the registered listener functions, or `null` if there are none.
## Wait for a channel state
`channel.whenState(targetState: ChannelState): Promise`
If the channel is already in the given state, returns a promise which immediately resolves to `null`. Otherwise calls [`once()`](#once) to return a promise which resolves the next time the channel transitions to the given state.
### Parameters
The `whenState()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| targetState | Required | The channel state to wait for. | |
### Returns
`Promise`
Returns a promise. If the channel is already in the given state, resolves to `null`. Otherwise resolves with the `ChannelStateChange` when the channel next transitions to that state.
## Get message history
`channel.history(params?: RealtimeHistoryParams): Promise>`
Retrieve a [`PaginatedResult`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#PaginatedResult) of historical messages for this channel. If the channel is [configured to persist messages](https://ably.com/docs/storage-history/storage.md), message history is available for the persistence duration configured for your account. If not, messages are only retained in memory by the Ably service for two minutes.
### Javascript
```
const page = await channel.history({ limit: 50, direction: 'backwards' });
page.items.forEach((message) => console.log(message.data));
```
### Parameters
The `history()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| params | Optional | Query parameters to filter and control retrieval. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| start | Optional | The time from which messages are retrieved, as milliseconds since the Unix epoch. Default: the beginning of time. | Number |
| end | Optional | The time until which messages are retrieved, as milliseconds since the Unix epoch. Default: current time. | Number |
| direction | Optional | The order of returned messages. `'backwards'` orders from most recent to oldest; `'forwards'` orders from oldest to most recent. Default: `'backwards'`. | String |
| limit | Optional | An upper limit on the number of messages returned. Default: 100. Maximum: 1000. | Number |
| untilAttach | Optional | When `true`, retrieves [continuous history](https://ably.com/docs/storage-history/history.md#continuous-history) up until the point of the channel being attached. Requires `direction` to be `'backwards'` (the default). If the channel is not attached, or if `direction` is set to `'forwards'`, this option results in an error. Default: `false`. | Boolean |
### Returns
`Promise>`
Returns a promise. The promise is fulfilled with a [`PaginatedResult`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#PaginatedResult) containing an array of [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) objects, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Get all versions of a message
`channel.getMessageVersions(serialOrMessage: string | Message, params?: RealtimeHistoryParams): Promise>`
Retrieve all historical [versions](https://ably.com/docs/messages/updates-deletes.md#versions) of a message identified by its serial, ordered by version. This includes the original message and all subsequent updates and delete operations. Requires the `history` [capability](https://ably.com/docs/auth/capabilities.md).
### Parameters
The `getMessageVersions()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| serialOrMessage | Required | Either the serial identifier string of the message whose versions are to be retrieved, or a [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) object containing a populated `serial` field. | String or [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) |
| params | Optional | Query parameters to filter and control retrieval. | |
### Returns
`Promise>`
Returns a promise. The promise is fulfilled with a [`PaginatedResult`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#PaginatedResult) of message versions, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## 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.
- [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.
- [RealtimeAnnotations](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-annotations.md): API reference for message annotations (the RealtimeAnnotations 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.