# History
## Channel object
The [Rest `Channel` object](https://ably.com/docs/channels.md) exposes the following public method to obtain [`Message`](#message) history.
### Methods
### historyHistory
`history(Object params?): Promise>`
`PaginatedResult history(Hash option)`
`PaginatedResult history(kwargs_options)`
`PaginatedResult history(Array option)`
`PaginatedResult history(Param[] option)`
`Task> HistoryAsync(PaginatedRequestParams query);`
`history(query: ARTDataQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void) throws`
`(c *RestChannel) History(option *PaginateParams) (*PaginatedResult, error)`
Gets a [paginated](#paginated-result) set of historical messages for this channel.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsqueryoptionoption | an optional object containing the query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing the query parametersan Associate Array containing the query parametersan optional object containing the query parameters, as specified below. | Object[`Param[]`](#param)[`PaginatedRequestParams`](#paginated-request-params)Object |
| Parameter | Description | Type |
|-----------|-------------|------|
| query | an optional object containing the query parameters, as specified below. | ARTDataQuery |
| callback | called with a [`ARTPaginatedResult`](#paginated-result)[``](#message) object or an error | Callback |
#### `params` parameters`ARTDataQuery` properties[`PaginatedRequestParams`](#paginated-request-params) properties`options` parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| start:startStartstart | _beginning of time_ earliest `DateTimeOffset` or `Time` or time in milliseconds since the epoch for any messages retrieved | `Number``Int` or `Time``DateTimeOffset``Long`Long |
| end:endEndend | _current time_ latest `DateTimeOffset` or `Time` or time in milliseconds since the epoch for any messages retrieved | `Number``Int` or `Time``DateTimeOffset``Long`Long |
| direction:directionDirectiondirection | _backwards_ `:forwards` or `:backwards``forwards` or `backwards`forwards or backwards | `String``Symbol``Direction` enum |
| limit:limitLimitlimit | _100_ maximum number of messages to retrieve per page, up to 1,000 | `Number``Integer` |
#### 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.md#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/rest-sdk/types.md#ably-exception)
#### 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 mean `error` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### Returns
This method returns a `Task` and 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/rest-sdk/types.md#ably-exception)
## Presence object
[Rest `Presence` object](https://ably.com/docs/presence-occupancy/presence.md) 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>`
`PaginatedResult history(Hash option)`
`PaginatedResult history(kwargs_options)`
`PaginatedResult history(Array option)`
`PaginatedResult history(Param[] option)`
`Task> HistoryAsync(PaginatedRequestParams query);`
`history(query: ARTDataQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void) throws`
`(p *RestPresence) History(option *PaginateParams) (*PaginatedResult, error)`
Gets a [paginated](#paginated-result) set of historical presence events for this channel.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsoption[`PaginatedRequestParams`](#paginated-request-params) queryoption | an optional object containing the query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing the query parametersan Associate Array containing the query parameters, as specified below. | Object[`Param[]`](#param)[`PaginatedRequestParams`](#paginated-request-params)Object |
| Parameter | Description | Type |
|-----------|-------------|------|
| query | an optional object containing query parameters, as specified below. | ARTDataQuery |
| callback | called with a [`ARTPaginatedResult`](#paginated-result)[``](#presence-message) object or an error | Callback |
#### `params` parameters`ARTDataQuery` properties[`PaginatedRequestParams`](#paginated-request-params) properties`options` parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| start:startStartstart | _beginning of time_ earliest `DateTimeOffset` or `Time` or time in milliseconds since the epoch for any presence events retrieved | `Number``Int` or `Time``DateTimeOffset``Long`Long |
| end:endEndend | _current time_ latest `DateTimeOffset` or `Time` or time in milliseconds since the epoch for any presence events retrieved | `Number``Int` or `Time``DateTimeOffset``Long`Long |
| direction:directionDirectiondirection | _backwards_ `:forwards` or `:backwards``forwards` or `backwards`forwards or backwards | `String``Symbol``Direction` enum |
| limit:limitLimitlimit | _100_ maximum number of presence events to retrieve up to 1,000 | `Number``Integer` |
#### 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.md#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/rest-sdk/types.md#ably-exception)
#### 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 message history will mean `error` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### Returns
This method returns a `Task` and 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/rest-sdk/types.md#ably-exception)
## 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.
### nameName
The event name, if provided.
_Type: `String`_
### dataData
The message payload, if provided.
_Type: `String`, `StringBuffer`, `JSON Object``String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, `plain C# object that can be serialized to JSON``String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``String`, `Bytearray`, `Dict`, `List``String`, `Binary String`, `Associative Array`, `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.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/webhooks.md#skipping) objects.
_Type: `JSONObject`, `JSONArray`plain C# object that can be converted to JSON`JSON Object``Hash`, `Array``Dict`, `List``Dictionary`, `Array``NSDictionary *`, `NSArray *``Associative Array`, `Array``String`, `[]byte`_
### idId
A Unique ID assigned by Ably to this message.
_Type: `String`_
### clientIdclient_idClientId
The client ID of the publisher of this message.
_Type: `String`_
### connectionIdconnection_idConnectionId
The connection ID of the publisher of this message.
_Type: `String`_
### connectionKeyConnectionKeyconnection_key
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.md#publish-on-behalf).
_Type: `String`_
### timestampTimestamp
Timestamp when the message was first received by the Ably, as milliseconds since the epocha `Time` object.
_Type: `Integer``Long Integer``DateTimeOffset``Time``NSDate`Integer_
### 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.
_Type: `String`_
### action
The action type of the message, one of the [`MessageAction`](https://ably.com/docs/api/realtime-sdk/types.md#message-action) enum values.
_Type: `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.md#rules).
_Type: `String`_
### annotations
An object containing information about annotations that have been made to the object.
_Type: [`MessageAnnotations`](https://ably.com/docs/api/realtime-sdk/types.md#message-annotations)_
### 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.md#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.md#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.md#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.md#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.md#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.md#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.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|-------------|------|
| actionActionAction | the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`Presence action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceAction`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action)the event signified by a PresenceMessage. See [`PresenceMessage::action`](https://ably.com/docs/api/realtime-sdk/types.md#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { Absent, Present, Enter, Leave, Update }``int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { :absent, :present, :enter, :leave, :update }``const PresenceMessage::ABSENT,PRESENT,ENTER,LEAVE,UPDATE``ARTPresenceAction``const PresenceMessage::PresenceAbsent,PresencePresent,PresenceEnter,PresenceLeave,PresenceUpdate` |
| 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`, `[]byte``String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``String`, `Bytearray`, `Dict`, `List``String`, `NSData`, `Dictionary`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *``String`, `Binary String`, `Associative Array`, `Array` |
| extrasExtras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](https://ably.com/docs/push/publish.md#sub-channels), [`ref`](https://ably.com/docs/channels/messages.md#interactions) and [`privileged`](https://ably.com/docs/platform/integrations/webhooks.md#skipping) objects. | `JSONObject`, `JSONArray`plain C# object that can be converted to Json`String`, `[]byte``JSON Object``Hash`, `Array``Dict`, `List``Dictionary`, `Array``NSDictionary *`, `NSArray *``Associative Array`, `Array` |
| idId | Unique ID assigned by Ably to this presence update | `String` |
| clientIdclient_idClientId | The client ID of the publisher of this presence update | `String` |
| connectionIdconnection_idConnectionId | 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`Integer |
| 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.md#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.md#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.md#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.md#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.md#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.md#presence-message) objects
### Presence actionPresenceActionARTPresenceActionio.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.md#trigger-events).
```javascript
var PresenceActions = [
'absent', // (reserved for internal use)
'present',
'enter',
'leave',
'update'
]
```
```nodejs
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.md#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.md#trigger-events).
```csharp
public enum Action {
Absent, // 0 (reserved for internal use)
Present, // 1
Enter, // 2
Leave, // 3
Update // 4
}
```
`PresenceAction` is an enum-like class representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```python
class PresenceAction(object):
ABSENT = 0 # (reserved for internal use)
PRESENT = 1
ENTER = 2
LEAVE = 3
UPDATE = 4
```
`PresenceMessage Action` is one of the class constants representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```php
namespace Ably\Models;
class PresenceMessages {
const ABSENT = 0; /* (reserved for internal use) */
const PRESENT = 1;
const ENTER = 2;
const LEAVE = 3;
const UPDATE = 4;
}
```
#### Example usage
```php
if ($presenceMessage->action == Ably\Models\PresenceMesage::ENTER) {
/* do something */
}
```
`Ably::Models::PresenceMessage::ACTION` is an enum-like value representing all the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#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.md#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
}
```
`Presence` `action` is a String with a value matching any of the [`Realtime Presence` states & events](https://ably.com/docs/presence-occupancy/presence.md#trigger-events).
```go
const (
PresenceAbsent = 0
PresencePresent = 1
PresenceEnter = 2
PresenceLeave = 3
PresenceUpdate = 4
)
```
### 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.md#channel-history).
#### Members
| Member | Description | Type |
|--------|-------------|------|
| Start | The start of the queried interval | `DateTimeOffset` |
| End | The end of the queried interval | `DateTimeOffset` |
| Limit | By default it is null. Limits the number of items returned by history or stats | `Integer` |
| Direction | _Backwards_ Enum which is either `Forwards` or `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.md#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|-------------|------|
| itemsItemsItemsitems | 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 ``Array ``List ` |
#### Methods
##### firstFirst
`first(): Promise`
`PaginatedResult first`
`PaginatedResult first()`
`PaginatedResult first()`
`PaginatedResult first()`
`Task> FirstAsync()`
`first(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
`First() (PaginatedResult, error)`
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.md#deferrable) and yields a [PaginatedResult](#paginated-result).The method is asynchronous and returns a Task which needs to be awaited to get the [PaginatedResult](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` for the first page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### hasNextHasNexthas_next?has_next
`Boolean hasNext()`
`Boolean has_next?`
`Boolean has_next()`
`Boolean HasNext()`
`HasNext() (bool)`
Returns `true` if there are more pages available by calling `next``Next` and returns `false` if this page is the last page available.
##### isLastIsLastlast?is_last
`Boolean isLast()`
`Boolean last?`
`Boolean is_last()`
`Boolean IsLast()`
`IsLast() (bool)`
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`
`PaginatedResult next`
`PaginatedResult next()`
`PaginatedResult next()`
`PaginatedResult next()`
`Task> NextAsync()`
`next(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
`Next() (PaginatedResult, error)`
Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null`a blank PaginatedResult will be returned`Null``None``nil` is returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult`When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and yields a [PaginatedResult](#paginated-result).
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.md#error-info) object that details the reason why it was rejected.
##### 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.md#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
```
```python
result_page = channel.history()
print 'Page 0 item 0: ' + str(result_page.items[0].data)
if result_page.has_next():
next_page = result_page.next()
print 'Page 1 item 1: ' + str(next_page.items[1].data)
print 'Last page?: ' + str(next_page.is_last())
```
```php
$firstPage = $channel.history();
echo("Page 0 item 0: " . $firstPage->items[0]->data);
if ($firstPage->hasNext()) {
$nextPage = $firstPage->next();
echo("Page 1 item 1: " . $nextPage->items[1]->data);
echo("Last page?: " . $nextPage->isLast());
}
```
```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())")
}
}
```
```go
page0, err := channel.History(nil)
fmt.Println("Page. 0 item 0: %s\n", page0.Messages[0].Data)
page1, err := page0.Next()
fmt.Println("Page. 1 item 1: %s\n", page1.Messages[1].Data)
fmt.Println("Last page? %s\n", page1.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.md#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
| Name | Description | Type |
|------|-------------|------|
| key | The key value | `String` |
| value | The value associated with the `key` | `String` |