# History
## Channel object
The [Realtime `Channel` object](https://ably.com/docs/channels) exposes the following public method to obtain [`Message`](#message) history.
### Methods
### historyHistory
`history(Object params?): Promise>`
`Task> HistoryAsync(PaginatedRequestParams dataQuery, bool untilAttach = false);`
`PaginatedResult history(Param option)`
`history(query: ARTRealtimeHistoryQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void) throws`
`Deferrable history(Hash option) → yields PaginatedResult`
Gets a [paginated](#paginated-result) set of historical messages for this channel.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsoptionquery | an optional object containing the query parametersan optional array containing the query parametersan optional object containing the query parameters | `Object`[`Param[]`](#param)[`PaginatedRequestParams`](#paginated-request-params) |
| Parameter | Description | Type |
|-----------|-------------|------|
| optionquery | an optional set of key value pairs containing the query parametersan optional object containing the query parameters | `Hash``ARTRealtimeHistoryQuery` |
| &blockcallback | yields a `PaginatedResult` objectcalled with a [ARTPaginatedResult](#paginated-result)<[ARTMessage](#message)> object or an error | `Block``Callback` |
#### `params` parameters`options` parameters`options` parameters`ARTRealtimeHistoryQuery` properties`PaginatedRequestParams` properties
| Property | Description | Type |
|----------|-------------|------|
| start:startstart | Earliest time in milliseconds since the epoch for any messages retrieved.Earliest `Time` or time in milliseconds since the epoch for any messages retrieved.Earliest time in milliseconds since the epoch for any messages retrieved.
_Default: beginning of time_ | `Number``Int` or `Time``Long` |
| end:endend | Latest time in milliseconds since the epoch for any messages retrieved.Latest `Time` or time in milliseconds since the epoch for any messages retrieved.Latest time in milliseconds since the epoch for any messages retrieved.
_Default: current time_ | `Number``Int` or `Time``Long` |
| direction:directiondirection | `forwards` or `backwards`.`:forwards` or `:backwards`.`forwards` or `backwards`.
_Default: `backwards``:backwards`_ | `String``Symbol` |
| limit:limitlimit | Maximum number of messages to retrieve per page, up to 1,000.
_Default: `100`_ | `Number``Integer` |
| untilAttach:until_attach | when true, ensures message history is up until the point of the channel being attached. See [continuous history](https://ably.com/docs/storage-history/history#continuous-history) for more info. Requires the `direction` to be `backwards` (the default). If the `Channel` is not attached, or if `direction` is set to `forwards`, this option will result in an error.
_Default: `false`_ | `Boolean` |
| Property | Description | Type |
|----------|-------------|------|
| Start | Earliest `DateTimeOffset` or time in milliseconds since the epoch for any messages retrieved.
_Default: beginning of time_ | `DateTimeOffset` |
| End | Latest `DateTimeOffset` or time in milliseconds since the epoch for any messages retrieved.
_Default: current time_ | `DateTimeOffset` |
| Direction | `forwards` or `backwards`.
_Default: `backwards`_ | `Direction` enum |
| Limit | Maximum number of messages to retrieve per page, up to 1,000.
_Default: `100`_ | `Integer` |
| untilAttach | When true, ensures message history is up until the point of the channel being attached.
_Default: `false`_ | `Boolean` |
#### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginated-result) encapsulating an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
#### Callback result
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
On failure to retrieve message history, `err` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### Returns
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods.
Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
#### Returns
Returns a `Task` that needs to be awaited.
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`NextAsync`](#paginated-result) and [`FirstAsync`](#paginated-result) methods.
Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
#### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](#paginated-result) that encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
Failure to retrieve the message history will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](#error-info) object with the failure reason.
## Presence object
[Realtime `Presence` object](https://ably.com/docs/presence-occupancy/presence) exposes the following public method to obtain presence event history such as enter, update and leave events. These events are represented as [`PresenceMessage`](#presence-message) objects.
### Methods
### historyHistory
`history(Object params?): Promise>`
`Task> HistoryAsync(PaginatedRequestParams query, bool untilAttach = false [deprecated])`
`PaginatedResult history(Param[] option)`
`history(query: ARTRealtimeHistoryQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void) throws`
`Deferrable history(Hash option) → yields PaginatedResult`
Gets a [paginated](#paginated-result) set of historical presence events for this channel.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsoptionquery | an optional object containing the query parameters, as specified below. | `Object`[`Param[]`](#param)[`PaginatedRequestParams`](https://ably.com/docs/api/realtime-sdk/history#paginated-request-params) |
| Parameter | Description | Type |
|-----------|-------------|------|
| optionquery | an optional set of key value pairs containing the query parametersan optional object containing the query parameters | `Hash``ARTRealtimeHistoryQuery`[`PaginatedRequestParams`](#paginated-request-params) |
| &blockcallback | yields a `PaginatedResult` objectcalled with a [ARTPaginatedResult](#paginated-result)<[ARTPresenceMessage](#presence-message)> object or an error | `Block``Callback` |
#### `params` parameters`options` parameters`options` parameters`ARTRealtimeHistoryQuery` properties`PaginatedRequestParams` properties
| Property | Description | Type |
|----------|-------------|------|
| start:startStart | Earliest time in milliseconds since the epoch for any presence events retrieved.Earliest `Time` or time in milliseconds since the epoch for any presence events retrieved.Earliest `DateTimeOffset` or time in milliseconds since the epoch for any presence events retrieved.
_Default: beginning of time_ | `Number``Int` or `Time``Long``DateTimeOffset` |
| end:endEnd | Latest time in milliseconds since the epoch for any presence events retrieved.Latest `Time` or time in milliseconds since the epoch for any presence events retrieved.Latest `DateTimeOffset` or time in milliseconds since the epoch for any presence events retrieved.
_Default: current time_ | `Number``Int` or `Time``Long``DateTimeOffset` |
| direction:directionDirection | `forwards` or `backwards`.`:forwards` or `:backwards`.
_Default: `backwards``:backwards`_ | `String``Symbol``Direction` enum |
| limit:limitLimit | Maximum number of presence events to retrieve up to 1,000.
_Default: `100`_ | `Number``Integer` |
| untilAttach:until_attach | when true, ensures presence message history is up until the point of the channel being attached. See [continuous history](https://ably.com/docs/storage-history/history#continuous-history) for more info. Requires the `direction` to be `backwards` (the default). If the `Channel` is not attached, or if `direction` is set to `forwards`, this option will result in an error.
_Default: `false`_ | `Boolean` |
#### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginated-result) encapsulating an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
#### Callback result
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
On failure to retrieve presence event history, `err` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### Returns
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods.
Failure to retrieve the presence event history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
#### Returns
Returns a `Task` that needs to be awaited.
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`NextAsync`](#paginated-result) and [`FirstAsync`](#paginated-result) methods.
Failure to retrieve the presence event history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
#### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](#paginated-result) that encapsulates an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
Failure to retrieve the presence event history will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](#error-info) object with the failure reason.
## Related types
### MessageARTMessageAbly::Models::Message Enumio.ably.lib.types.MessageIO.Ably.Message
A `Message` represents an individual message that is sent to or received from Ably.
#### Properties
| Property | Description | Type |
|----------|-------------|------|
| name | The event name, if provided. | `String` |
| data | The message payload, if provided. | `String`, `StringBuffer`, `JSON Object` |
| extras | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish#payload), `headers` (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects. | `JSON Object` |
| id | A Unique ID assigned by Ably to this message. | `String` |
| clientId | The client ID of the publisher of this message. | `String` |
| connectionId | The connection ID of the publisher of this message. | `String` |
| connectionKey | A connection key, which can optionally be included for a REST publish as part of the [publishing on behalf of a realtime client functionality](https://ably.com/docs/pub-sub/advanced#publish-on-behalf). | `String` |
| timestamp | Timestamp when the message was first received by the Ably, as milliseconds since the epoch. | `Integer` |
| encoding | This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload. | `String` |
| action | The action type of the message, one of the [`MessageAction`](https://ably.com/docs/api/realtime-sdk/types#message-action) enum values. | `int enum { MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, META, MESSAGE_SUMMARY }` |
| serial | A server-assigned identifier that will be the same in all future updates of this message. It can be used to add annotations to a message. Serial will only be set if you enable annotations in [channel rules](https://ably.com/docs/channels#rules). | `String` |
| annotations | An object containing information about annotations that have been made to the object. | [`MessageAnnotations`](https://ably.com/docs/api/realtime-sdk/types#message-annotations) |
| Property | Description | Type |
|----------|-------------|------|
| nameName | The event name, if provided. | `String` |
| dataData | The message payload, if provided. | `String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, plain C# object that can be serialized to JSON`String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *``String`, `NSData`, `Dictionary`, `Array` |
| extrasExtras | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish#payload), `headers` (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray`plain C# object that can be converted to JSON`Hash`, `Array``Dictionary`, `Array``NSDictionary *`, `NSArray *` |
| idId | A Unique ID assigned by Ably to this message. | `String` |
| client_idClientIdclientId | The client ID of the publisher of this message. | `String` |
| connection_idConnectionIdconnectionId | The connection ID of the publisher of this message. | `String` |
| connection_keyConnectionKeyconnectionKey | A connection key, which can optionally be included for a REST publish as part of the [publishing on behalf of a realtime client functionality](https://ably.com/docs/pub-sub/advanced#publish-on-behalf). | `String` |
| timestampTimestamp | Timestamp when the message was first received by the Ably, as milliseconds since the epocha `Time` objecta `DateTimeOffset``NSDate`. | `Long Integer``DateTimeOffset``Time``NSDate` |
| encodingEncoding | This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload. | `String` |
### Message constructors
#### Message.fromEncoded
`Message.fromEncoded(Object encodedMsg, ChannelOptions channelOptions?) → Message`
A static factory method to create a [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) from a deserialized `Message`-like object encoded using Ably's wire protocol.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedMsg | a `Message`-like deserialized object. | `Object` |
| channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` |
##### Returns
A [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) object
#### Message.fromEncodedArray
`Message.fromEncodedArray(Object[] encodedMsgs, ChannelOptions channelOptions?) → Message[]`
A static factory method to create an array of [`Messages`](https://ably.com/docs/api/realtime-sdk/types#message) from an array of deserialized `Message`-like object encoded using Ably's wire protocol.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedMsgs | an array of `Message`-like deserialized objects. | `Array` |
| channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` |
##### Returns
An `Array` of [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) objects
### PresenceMessageARTPresenceMessageAbly::Models::PresenceMessage Enumio.ably.lib.types.PresenceMessageIO.Ably.PresenceMessage
A `PresenceMessage` represents an individual presence update that is sent to or received from Ably.
#### Properties
| Property | Description | Type |
|----------|-------------|------|
| actionAction | the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { Absent, Present, Enter, Leave, Update }``int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { :absent, :present, :enter, :leave, :update }``ARTPresenceAction` |
| dataData | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, plain C# object that can be converted to Json`String`, `StringBuffer`, `JSON Object``String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``String`, `NSData`, `Dictionary`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` |
| extrasExtras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](https://ably.com/docs/push/publish#sub-channels), [`ref`](https://ably.com/docs/channels/messages#interactions) and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray`plain C# object that can be converted to Json`JSON Object``Hash`, `Array``Dictionary`, `Array``NSDictionary *`, `NSArray *` |
| idId | Unique ID assigned by Ably to this presence update | `String` |
| clientIdclient_idClientIdclientId | The client ID of the publisher of this presence update | `String` |
| connectionIdconnection_idConnectionIdconnectionId | The connection ID of the publisher of this presence update | `String` |
| timestampTimestamp | Timestamp when the presence update was received by Ably, as milliseconds since the epoch. | `Integer``Long Integer``DateTimeOffset``Time``NSDate` |
| encodingEncoding | This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload | `String` |
#### PresenceMessage constructors
#### PresenceMessage.fromEncoded
`PresenceMessage.fromEncoded(Object encodedPresMsg, ChannelOptions channelOptions?) → PresenceMessage`
A static factory method to create a [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types#presence-message) from a deserialized `PresenceMessage`-like object encoded using Ably's wire protocol.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedPresMsg | a `PresenceMessage`-like deserialized object. | `Object` |
| channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` |
##### Returns
A [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types#presence-message) object
#### PresenceMessage.fromEncodedArray
`PresenceMessage.fromEncodedArray(Object[] encodedPresMsgs, ChannelOptions channelOptions?) → PresenceMessage[]`
A static factory method to create an array of [`PresenceMessages`](https://ably.com/docs/api/realtime-sdk/types#presence-message) from an array of deserialized `PresenceMessage`-like object encoded using Ably's wire protocol.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedPresMsgs | an array of `PresenceMessage`-like deserialized objects. | `Array` |
| channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` |
##### Returns
An `Array` of [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types#presence-message) objects
### Presence actionARTPresenceActionio.ably.lib.types.PresenceMessage.ActionAbly::Models::PresenceMessage::ACTIONIO.Ably.PresenceAction
`Presence` `action` is a String with a value matching any of the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events).
```javascript
var PresenceActions = [
'absent', // (reserved for internal use)
'present',
'enter',
'leave',
'update'
]
```
`io.ably.lib.types.PresenceMessage.Action` is an enum representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events).
```java
public enum Action {
ABSENT, // 0 (reserved for internal use)
PRESENT, // 1
ENTER, // 2
LEAVE, // 3
UPDATE // 4
}
```
`IO.Ably.PresenceAction` is an enum representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events).
```csharp
public enum Action {
Absent, // 0 (reserved for internal use)
Present, // 1
Enter, // 2
Leave, // 3
Update // 4
}
```
`Ably::Models::PresenceMessage::ACTION` is an enum-like value representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events). `ACTION` can be represented interchangeably as either symbols or constants.
#### Symbol states
```ruby
:absent # => 0 (reserved for internal use)
:present # => 1
:enter # => 2
:leave # => 3
:update # => 4
```
#### Constant states
```ruby
PresenceMessage::ACTION.Absent # => 0 (internal use)
PresenceMessage::ACTION.Present # => 1
PresenceMessage::ACTION.Enter # => 2
PresenceMessage::ACTION.Leave # => 3
PresenceMessage::ACTION.Update # => 4
```
#### Example usage
```ruby
# Example with symbols
presence.on(:attached) { ... }
# Example with constants
presence.on(Ably::Models::PresenceMessage::ACTION.Enter) { ... }
# Interchangeable
Ably::Models::PresenceMessage::ACTION.Enter == :enter # => true
```
`ARTPresenceAction` is an enum representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events).
```objc
typedef NS_ENUM(NSUInteger, ARTPresenceAction) {
ARTPresenceAbsent, // reserved for internal use
ARTPresencePresent,
ARTPresenceEnter,
ARTPresenceLeave,
ARTPresenceUpdate
};
```
```swift
enum ARTPresenceAction : UInt {
case Absent // reserved for internal use
case Present
case Enter
case Leave
case Update
}
```
### IO.Ably.PaginatedRequestParams
`HistoryRequestParams` is a type that encapsulates the parameters for a history queries. For example usage see [`Channel#History`](https://ably.com/docs/api/realtime-sdk/history#channel-history).
#### Members
| Property | Description | Type |
|----------|-------------|------|
| Start | The start of the queried interval.
_Default: `null`_ | `DateTimeOffset` |
| End | The end of the queried interval.
_Default: `null`_ | `DateTimeOffset` |
| Limit | By default it is null. Limits the number of items returned by history or stats.
_Default: `null`_ | `Integer` |
| Direction | Enum which is either `Forwards` or `Backwards`.
_Default: `Backwards`_ | `Direction` enum |
| ExtraParameters | Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging. | `Dictionary` |
### PaginatedResultARTPaginatedResultAbly::Models::PaginatedResultio.ably.lib.types.PaginatedResultIO.Ably.PaginatedResult
A `PaginatedResult` is a type that represents a page of results for all message and presence history, stats and REST presence requests. The response from a [Ably REST API paginated query](https://ably.com/docs/api/rest-api/#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object.
#### Properties
| Property | Description | Type |
|----------|-------------|------|
| itemsItems | contains the current page of results (for example an Array of [`Message`](#message) or [`PresenceMessage`](#presence-message) objects for a channel history request) | `Array ``List ` |
#### Methods
#### firstFirst
`first(): Promise`
Returns a promise. On success, the promise is fulfilled with a new [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/history#paginated-result) for the first page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
`PaginatedResult first()`
`first(callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void)`
Returns a new `PaginatedResult` for the first page of results. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types#deferrable) and yields a [PaginatedResult](#paginated-result).
`Task> FirstAsync()`
Returns a new `PaginatedResult` for the first page of results. The method is asynchronous and returns a Task which needs to be awaited to get the [PaginatedResult](#paginated-result).
#### hasNextHasNexthas_next?
`Boolean hasNext()`
`Boolean HasNext()`
`Boolean hasNext()`
`Boolean has_next?`
Returns `true` if there are more pages available by calling `next``Next` and returns `false` if this page is the last page available.
#### isLastIsLastlast?
`Boolean isLast()`
`Boolean IsLast()`
`Boolean isLast()`
`Boolean last?`
Returns `true` if this page is the last page and returns `false` if there are more pages available by calling `next``Next` available.
#### nextNext
`next(): Promise`
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null` is returned. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
`next(callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void)`
`PaginatedResult next()`
Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `Null``nil``null` is returned. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types#deferrable) and yields a [PaginatedResult](#paginated-result).
`Task> NextAsync()`
Returns a new [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/historypaginated-result) loaded with the next page of results. If there are no further pages, then a blank PaginatedResult will be returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult`
#### current
`current(): Promise`
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the current page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
#### Example
```javascript
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```nodejs
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```java
PaginatedResult firstPage = channel.history();
System.out.println("Page 0 item 0:" + firstPage.items[0].data);
if (firstPage.hasNext) {
PaginatedResult nextPage = firstPage.next();
System.out.println("Page 1 item 1:" + nextPage.items[1].data);
System.out.println("More pages?:" + Strong.valueOf(nextPage.hasNext()));
};
```
```csharp
PaginatedResult firstPage = await channel.HistoryAsync(null);
Message firstMessage = firstPage.Items[0];
Console.WriteLine("Page 0 item 0: " + firstMessage.data);
if (firstPage.HasNext)
{
var nextPage = await firstPage.NextAsync();
Console.WriteLine("Page 1 item 1:" + nextPage.Items[1].data);
Console.WriteLine("More pages?: " + nextPage.HasNext());
}
```
```ruby
# When using the REST sync library
first_page = channel.history
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
next_page = first_page.next
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
# When using the Realtime EventMachine library
channel.history do |first_page|
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
first_page.next do |next_page|
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
end
end
```
```objc
[channel history:^(ARTPaginatedResult *paginatedResult, ARTErrorInfo *error) {
NSLog(@"Page 0 item 0: %@", paginatedResult.items[0].data);
[paginatedResult next:^(ARTPaginatedResult *nextPage, ARTErrorInfo *error) {
NSLog(@"Page 1 item 1: %@", nextPage.items[1].data);
NSLog(@"Last page?: %d", nextPage.isLast());
}];
}];
```
```swift
channel.history { paginatedResult, error in
guard let paginatedResult = paginatedResult else {
print("No results available")
return
}
print("Page 0 item 0: \((paginatedResult.items[0] as! ARTMessage).data)")
paginatedResult.next { nextPage, error in
guard let nextPage = nextPage else {
print("No next page available")
return
}
print("Page 1 item 1: \((nextPage.items[1] as! ARTMessage).data)")
print("Last page? \(nextPage.isLast())")
}
}
```
### io.ably.lib.types.Param
`Param` is a type encapsulating a key/value pair. This type is used frequently in method parameters allowing key/value pairs to be used more flexible, see [`Channel#history`](https://ably.com/docs/api/realtime-sdk/history#channel-history) for an example.
Please note that `key` and `value` attributes are always strings. If an `Integer` or other value type is expected, then you must coerce that type into a `String`.
#### Members
| Property | Description | Type |
|----------|-------------|------|
| key | The key value | `String` |
| value | The value associated with the `key` | `String` |