diff --git a/content/api/realtime-sdk/push-admin.textile b/content/api/realtime-sdk/push-admin.textile
deleted file mode 100644
index c1cdb6584c..0000000000
--- a/content/api/realtime-sdk/push-admin.textile
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: Push Notifications - Admin
-meta_description: "Realtime Client Library SDK API reference section for push notifications admin."
-meta_keywords: "Ably, Ably realtime, API Reference, Realtime SDK, push, push notification, notification, push notifications, notifications, admin, push admin"
-section: api
-index: 45
-languages:
- - javascript
- - nodejs
- - ruby
- - php
- - python
- - swift
- - objc
- - java
- - android
-jump_to:
- API reference:
- - publish#publish
- - DeviceRegistrations#device-registrations-object
- - PushChannelSubscriptions#push-channel-subscriptions
- Types:
- - Related Types#related-types
-redirect_from:
- - /docs/api/versions/v1.1/realtime-sdk/push-admin
----
-
-<%= partial partial_version('types/_push_admin') %>
-
-h2(#related-types). Related types
-
-h3(#device-details).
- default: DeviceDetails
- ruby: Ably::Models::DeviceDetails
- swift,objc: ARTDeviceDetails
-
-<%= partial partial_version('types/_device_details') %>
-
-h3(#push-channel).
- default: PushChannel
- ruby: Ably::Models::PushChannel
-
-<%= partial partial_version('types/_push_channel') %>
-
-h3(#push-channel-subscription).
- default: PushChannelSubscription
- ruby: Ably::Models::PushChannelSubscription
- java,android: ChannelSubscription
- swift,objc: ARTPushChannelSubscription
-
-<%= partial partial_version('types/_push_channel_subscription') %>
-
-h3(#paginated-result).
- default: PaginatedResult
- swift,objc: ARTPaginatedResult
- ruby: Ably::Models::PaginatedResult
- java,android: io.ably.lib.types.PaginatedResult
- csharp: IO.Ably.PaginatedResult
-
-<%= partial partial_version('types/_paginated_result') %>
diff --git a/src/pages/docs/api/realtime-sdk/push-admin.mdx b/src/pages/docs/api/realtime-sdk/push-admin.mdx
new file mode 100644
index 0000000000..53b8b171dd
--- /dev/null
+++ b/src/pages/docs/api/realtime-sdk/push-admin.mdx
@@ -0,0 +1,1473 @@
+---
+title: Push Notifications - Admin
+meta_description: "Realtime Client Library SDK API reference section for push notifications admin."
+meta_keywords: "Ably, Ably realtime, API Reference, Realtime SDK, push, push notification, notification, push notifications, notifications, admin, push admin"
+jump_to:
+ API reference:
+ - publish#publish
+ - DeviceRegistrations#device-registrations-object
+ - PushChannelSubscriptions#push-channel-subscriptions
+ Types:
+ - Related Types#related-types
+redirect_from:
+ - /docs/api/versions/v1.1/realtime-sdk/push-admin
+---
+
+## Push Admin object
+
+This object is accessible through `client.push.admin` and provides:
+
+### Push Admin PropertiesPush::Admin Properties
+
+The push admin object exposes the following public propertiesattributesmembers:
+
+#### deviceRegistrationsdevice_registrations
+
+The returned [`DeviceRegistrations`](#device-registrations-object) object provides functionality for registering, updating, listing and de-registering push devices.
+
+#### channelSubscriptionschannel_subscriptions
+
+The returned [`PushChannelSubscriptions`](#push-channel-subscriptions) object provides functionality for subscribing, listing and unsubscribing individual devices or groups of [identified devices](/docs/auth/identified-clients) to push notifications published on channels.
+
+### Methods
+
+#### publish
+
+
+
+`publish(Object recipient, Object payload): Promise`
+
+
+
+
+`Deferrable publish(Hash recipient, Hash data) → yield`
+
+
+
+
+`publish(recipient=Object, data=Object)`
+
+
+
+
+`publish(recipient: ARTPushRecipient, data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?)`
+
+
+
+
+`void publish(String recipient, Object data, CompletionListener listener)`
+
+
+
+Publishes a push notification directly to a device or group of devices sharing a [client identifier](/docs/auth/identified-clients). See the [push notification direct publishing documentation](/docs/push/publish#direct-publishing) for more information.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](/docs/api/rest-api#push-publish) for details on the supported recipient fields | `Object` |
+| payloaddata | Contains the push notification data. See the [push admin payload structure](/docs/push/publish#payload) for details on the supported push payload fields | `Object` |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](/docs/api/rest-api#push-publish) for details on the supported recipient fields | `Hash` |
+| data | Contains the push notification data. See the [push admin payload structure](/docs/push/publish#payload) for details on the supported push payload fields | `Hash` |
+| &block | Yielded upon success | |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](/docs/api/rest-api#push-publish) for details on the supported recipient fields | `Object` |
+| data | Contains the push notification data. See the [push admin payload structure](/docs/push/publish#payload) for details on the supported push payload fields | `Object` |
+| listener | Listener to be notified on completion | [`CompletionListener`](#completion-listener) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](/docs/api/rest-api#push-publish) for details on the supported recipient fields | `Object` |
+| data | Contains the push notification data. See the [push admin payload structure](/docs/push/publish#payload) for details on the supported push payload fields | `Object` |
+| callback | Called upon publishing the message, or with an error | |
+
+
+
+
+
+##### Returns
+
+Returns a promise. On success to publish the push notification, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+The callback is called upon success or failure to publish the push notification. When this operation fails, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method are yielded to.
+
+Failure to publish the push notification will trigger the `errback` callback of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Listener result
+
+On successful publish of the message, the `onSuccess` method of the [CompletionListener](#completion-listener) is called. On failure to publish the message, the `onError` method is called with an [`ErrorInfo`](#error-info) argument describing the failure reason.
+
+
+
+## PushDeviceRegistrations objectDeviceRegistrations object
+
+This object is accessible through `client.push.admin.deviceRegistrations``client.push.admin.device_registrations` and provides an API to register new push notification devices, update existing devices, deregister old devices, and retrieve or list devices registered to an app.
+
+### Methods
+
+#### get
+
+
+
+`get(String deviceId): Promise`
+
+`get(DeviceDetails deviceDetails): Promise`
+
+
+
+
+`get(String deviceId) -> yields DeviceDetails`
+
+`get(DeviceDetails device) -> yields DeviceDetails`
+
+
+
+
+`DeviceDetails get(device_id=String)`
+
+`get(DeviceDetails device, callback(ErrorInfo err, DeviceDetails device))`
+
+
+
+
+`get(deviceId: ArtDeviceId, callback: ((ARTDeviceDetails?, ARTErrorInfo?) -> Void))`
+
+`get(DeviceDetails device, callback(ErrorInfo err, DeviceDetails device))`
+
+
+
+
+`DeviceDetails get(String deviceId)`
+
+`getAsync(String deviceId, Callback callback)`
+
+`get(DeviceDetails device, callback(ErrorInfo err, DeviceDetails device))`
+
+
+
+Obtain the `DeviceDetails` for a device registered for receiving push registrations matching the `deviceId` argument, or the `id` attribute of the provided `DeviceDetails` object. Requires `push-admin` permission or `push-subscribe` permission together with device authentication matching the requested `deviceId`.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceId | The unique device ID String for the requested device | `String` |
+| deviceDetailsdevice | A `DeviceDetails` object containing at a minimum the `deviceId` of the requested device | [`DeviceDetails`](#device-details) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceId | The unique device ID String for the requested device | `String` |
+| device | A `DeviceDetails` object containing at a minimum the `deviceId` of the requested device | [`DeviceDetails`](#device-details) |
+| &block | Yields a `DeviceDetails` object upon success | |
+
+
+
+
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with a [`DeviceDetails`](#device-details) object representing the device registered for push notifications. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+On success, `device` contains the device registered for push notifications as a [`DeviceDetails`](#device-details) object.
+
+On failure to retrieve the device, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield the device registered for push notifications as a [`DeviceDetails`](#device-details) object.
+
+Failure to retrieve the device will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Listener result
+
+On successful publish of the message, the `onSuccess` method of the [CompletionListener](#completion-listener) is called. On failure to get the device, the `onError` method is called with an [`ErrorInfo`](#error-info) argument describing the failure reason.
+
+
+
+#### list
+
+
+
+`list(Object params): Promise>`
+
+
+
+
+`Deferrable list(Hash params) → yields PaginatedResult`
+
+
+
+
+`PaginatedResult list(params=Object)`
+
+
+
+
+`list(params: NSDictionary *, callback: ((ARTPaginatedResult?, ARTErrorInfo?) -> Void))`
+
+
+
+
+
+`PaginatedResult list(Param[] params)`
+
+
+
+Retrieve all devices matching the params filter as a paginated list of [`DeviceDetails`](#device-details) objects. Requires `push-admin` permission.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the query parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the query parameters as key value pairs as specified below | `Object` |
+| &block | | Yields a `PaginatedResult` object |
+
+
+
+##### `params` properties
+
+
+
+| Property | Description | Type |
+|----------|------|-------------|
+| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a deviceId:device_id param | `String` |
+| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a `clientId``:client_id` param | `String` |
+| limit:limit | _100_ maximum number of devices per page to retrieve, up to 1,000 | `Integer` |
+
+
+
+
+
+| Property | Description | Type |
+|----------|------|-------------|
+| clientId | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a `deviceId` param | `String` |
+| deviceId | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a `clientId` param | `String` |
+| limit | _100_ maximum number of devices per page to retrieve, up to 1,000 | `Integer` |
+| state | Optional filter by the state of the device. Must be one of `ACTIVE`, `FAILING` or `FAILED` | `String` |
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) encapsulating an array of [`DeviceDetails`](#device-details) objects corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+
+##### Callback result
+
+On success, `resultPage` contains a [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) encapsulating an array of [`DeviceDetails`](#device-details) objects corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+On failure to retrieve the devices, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](/docs/api/realtime-sdk/types#paginated-result) that encapsulates an array of [`DeviceDetails`](#device-details) corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+Failure to retrieve the devices will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### save
+
+
+
+`save(DeviceDetails deviceDetails): Promise`
+
+
+
+
+`Deferrable save(DeviceDetails device) → yields DeviceDetails`
+
+
+
+
+`DeviceDetails save(DeviceDetails device_details)`
+
+
+
+
+`save(deviceDetails: DeviceDetails, callback: ((DeviceDetails?, ARTErrorInfo?) -> Void))`
+
+
+
+
+`DeviceDetails save(DeviceDetails deviceDetails)`
+
+
+
+Register a new `DeviceDetails` object, or update an existing `DeviceDetails` object with the Ably service. Requires `push-admin` permission or `push-subscribe` permission together with device authentication matching the requested `deviceId`.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceDetailsdevice | A `DeviceDetails` object | [`DeviceDetails`](#device-details) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| `device` | A `DeviceDetails` object | [`DeviceDetails`](#device-details) |
+| `&block` | Yields the new `DeviceDetails` object upon success | |
+
+
+
+
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with a [`DeviceDetails`](#device-details) object representing the newly registered or updated device. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+On success, `device` contains the newly registered or updated device as a [`DeviceDetails`](#device-details) object.
+
+On failure to create or update the device, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield the newly registered or updated device as a [`DeviceDetails`](#device-details) object.
+
+Failure to create or update the device will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### remove
+
+
+
+`remove(String deviceId): Promise`
+
+`remove(DeviceDetails deviceDetails): Promise`
+
+
+
+
+`remove(String deviceId)`
+
+`remove(DeviceDetails device) -> yield`
+
+
+
+
+`remove(String device_id)`
+
+`remove(DeviceDetails device_details)`
+
+
+
+
+`remove(deviceDetails: DeviceDetails, callback: ((DeviceDetails?, ARTErrorInfo?) -> Void))`
+
+`remove(deviceDetails: DeviceDetails, callback: ((ARTErrorInfo?) -> Void))`
+
+
+
+
+`DeviceDetails save(DeviceDetails deviceDetails)`
+
+`DeviceDetails save(DeviceDetails deviceDetails)`
+
+
+
+Remove a device registered for receiving push registrations that matches the `deviceId` argument, or the `id` attribute of the provided [`DeviceDetails`](#device-details) object. Requires `push-admin` permission or `push-subscribe` permission together with device authentication matching the requested `deviceId`.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceId | The unique device ID String for the device | `String` |
+| deviceDetailsdevice | A `DeviceDetails` object containing at a minimum the `deviceId` of the device | [`DeviceDetails`](#device-details) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceId | The unique device ID String for the device | `String` |
+| device | A `DeviceDetails` object containing at a minimum the `deviceId` of the device | [`DeviceDetails`](#device-details) |
+| &block | Yields upon success | |
+
+
+
+
+
+##### Returns
+
+Returns a promise. On success to delete the device, the promise resolves. Note that a request to delete a device that does not exist will result in a successful operation. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+The callback is called upon success or failure to delete the device. Note that a request to delete a device that does not exist will result in a successful operation.
+
+When this operation fails, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method are yielded to. Note that a request to delete a device that does not exist will result in a successful operation.
+
+Failure to delete the device will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### removeWhereremove_where
+
+
+
+`removeWhere(Object params): Promise`
+
+
+
+
+`remove_where(Hash params) -> yield`
+
+
+
+
+`remove_where(params=Object)`
+
+
+
+
+`removeWhere(params: NSDictionary *, callback: (ARTErrorInfo?) -> Void)`
+
+
+
+
+`removeWhere(Param[] params)`
+
+
+
+Delete all devices matching the params filter. Requires `push-admin` permission.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the filter parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the filter parameters as key value pairs as specified below | `Object` |
+| &block | Yields upon success | |
+
+
+
+##### `params` properties
+
+| Property | Description | Type |
+|----------|------|-------------|
+| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a `deviceId``:device_id` param | `String` |
+| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a `clientId``:client_id` param | `String` |
+
+
+
+##### Returns
+
+Returns a promise. On success to delete the device, the promise resolves. Note that a request that does match any existing devices will result in a successful operation. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+The callback is called upon success or failure to delete the device. Note that a request that does match any existing devices will result in a successful operation.
+
+When this operation fails, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method are yielded to. Note that a request that does match any existing devices will result in a successful operation.
+
+Failure to delete the device will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+## PushChannelSubscriptions object
+
+This object is accessible through `client.push.admin.channelSubscriptions``client.push.admin.channel_subscriptions` and provides an API to subscribe a push notification device to a channel ensuring it receives any push notifications published in the future on that channel. Additionally, this object allows these subscriptions to be retrieved, listed, updated or removed.
+
+### Methods
+
+#### list
+
+
+
+`list(Object params): Promise>`
+
+
+
+
+`Deferrable list(Hash params) -> yields PaginatedResult`
+
+
+
+
+`PaginatedResult list(params=Object)`
+
+
+
+
+`list(params: NSDictionary *, callback: ((ARTPaginatedResult?, ARTErrorInfo?) -> Void))`
+
+
+
+
+`PaginatedResult list(Param[] params)`
+
+
+
+Retrieve all push channel subscriptions that match the provided params filter as a paginated list of [`PushChannelSubscription`](#push-channel-subscription) objects. Each [`PushChannelSubscription`](#push-channel-subscription) represents a device or set of devices sharing the same [client identifier](/docs/auth/identified-clients) registered to a channel to receive push notifications.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the query parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the query parameters as key value pairs as specified below | `Object` |
+| &block | Yields a `PaginatedResult` object | |
+
+
+
+##### `params` properties
+
+| Property | Description | Type |
+|----------|------|-------------|
+| channel:channel | Filter to restrict to subscriptions associated with that `channel` | `String` |
+| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a deviceId:device_id param | `String` |
+| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a clientId:client_id param | `String` |
+| limit:limit | _100_ maximum number of channel subscriptions per page to retrieve, up to 1,000 | `Integer` |
+
+
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) encapsulating an array of [`PushChannelSubscription`](#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+On success, `resultPage` contains a [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) encapsulating an array of [`PushChannelSubscription`](#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+On failure to retrieve the channel subscriptions, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object which contains the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](/docs/api/realtime-sdk/types#paginated-result) that encapsulates an array of [`PushChannelSubscription`](#push-channel-subscription) corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+Failure to retrieve the channel subscriptions will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### listChannelslist_channels
+
+
+
+`listChannels(Object params): Promise>`
+
+
+
+
+`Deferrable list_channels(Hash params) -> yields PaginatedResult`
+
+
+
+
+`PaginatedResult list_channels(params=Object)`
+
+
+
+
+`listChannels(params: NSDictionary *, callback: ((ARTPaginatedResult?, ARTErrorInfo?) -> Void))`
+
+
+
+
+`PaginatedResult listChannels(Param[] params)`
+
+
+
+Retrieve a list of channels that have at least one device [subscribed to push notifications](/docs/push/publish#sub-channels) as a paginated list of channel name `String` objects. Requires `push-admin` permission.
+
+##### Parameters
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the query parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
+
+
+
+
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the query parameters as key value pairs as specified below | `Object` |
+| &block | Yields a `PaginatedResult` object | |
+
+
+
+##### `params` properties
+
+| Property | Description | Type |
+|----------|------|-------------|
+| limit:limit | _100_ maximum number of channels per page to retrieve, up to 1,000 | `Integer` |
+
+
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) encapsulating an array of channel name `String` values corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+On success, `resultPage` contains a [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) encapsulating an array of channel name `String` values corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+On failure to retrieve the channels, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+A [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) object is returned from the method.
+
+On success, the registered success blocks for the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](/docs/api/realtime-sdk/types#paginated-result) that encapsulates an array of channel name `String` values corresponding to the current page of results. [`PaginatedResult`](/docs/api/realtime-sdk/types#paginated-result) supports pagination using [`next()`](/docs/api/realtime-sdk/types#paginated-result) and [`first()`](/docs/api/realtime-sdk/types#paginated-result) methods.
+
+Failure to retrieve the channels will trigger the `errback` callbacks of the [`Deferrable`](/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### save
+
+
+
+`save(PushChannelSubscription subscription): Promise`
+
+
+
+
+`save(PushChannelSubscription channel_subscription)`
+
+
+
+
+`PushChannelSubscription save(PushChannelSubscription channel_subscription)`
+
+
+
+
+`save(channelSubscription: PushChannelSubscription, callback: ((PushChannelSubscription?, ARTErrorInfo?) -> Void))`
+
+
+
+
+`PushChannelSubscription save(PushChannelSubscription channelSubscription)`
+
+
+
+Subscribe a device or group of devices sharing a [client identifier](/docs/auth/identified-clients) for push notifications published on a channel.
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| channelSubscriptionsubscriptionchannel_subscription | A `PushChannelSubscription` object | [`PushChannelSubscription`](#push-channel-subscription) |
+
+
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with a [`PushChannelSubscription`](#push-channel-subscription) object representing the newly subscribed or updated push channel subscription. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+On success, `channelSubscription` contains the newly subscribed or updated push channel subscription as a [`PushChannelSubscription`](#push-channel-subscription) object.
+
+On failure to create or update the channel subscription, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### remove
+
+
+
+`remove(PushChannelSubscription subscription): Promise`
+
+
+
+
+`remove(PushChannelSubscription channel_subscription)`
+
+
+
+
+`remove(PushChannelSubscription channel_subscription)`
+
+
+
+
+`remove(channelSubscription: PushChannelSubscription, callback: ((ARTErrorInfo?) -> Void))`
+
+
+
+
+`void remove(PushChannelSubscription channelSubscription)`
+
+
+
+Unsubscribe a device or group of devices sharing a [client identifier](/docs/auth/identified-clients) from push notifications on a channel. Requires `push-admin` permission or, in the case of a subscription associated with a given `deviceId`, `push-subscribe` permission together with device authentication matching that `deviceId`.
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| channelSubscriptionsubscription`channel_subscription` | A `PushChannelSubscription` object | [`PushChannelSubscription`](#push-channel-subscription) |
+
+
+
+##### Returns
+
+Returns a promise. On success to unsubscribe, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+The callback is called upon success or failure to unsubscribe. Note that a request to unsubscribe or remove a subscription that does not exist will result in a successful operation.
+
+When this operation fails, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+#### removeWhereremove_where
+
+
+
+`removeWhere(Object params): Promise`
+
+
+
+
+`remove_where(Hash params)`
+
+
+
+
+`remove_where(params=Object)`
+
+
+
+
+`removeWhere(params: NSDictionary *, callback: (ARTErrorInfo?) -> Void)`
+
+
+
+
+`removeWhere(Param[] params)`
+
+
+
+Delete all push channel subscriptions matching the `params` filter. Requires `push-admin` permission.
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| params | An object containing the filter parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
+
+##### `params` properties
+
+| Property | Description | Type |
+|----------|------|-------------|
+| channel:channel | Filter to restrict to subscriptions associated with that `channel` | `String` |
+| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with `deviceId``:device_id` param | `String` |
+| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with `clientId``:client_id` param | `String` |
+
+
+
+##### Returns
+
+Returns a promise. On success to unsubscribe, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+
+##### Callback result
+
+The callback is called upon success or failure to unsubscribe. Note that a request to unsubscribe or remove a subscription that does not exist will result in a successful operation.
+
+When this operation fails, `err` contains an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+## Related types
+
+### DeviceDetailsAbly::Models::DeviceDetails
+
+A `DeviceDetails` is a type encapsulating attributes of a device registered for push notifications.
+
+#### Properties
+
+| Property | Description | Type |
+|----------|------|-------------|
+| id | Unique identifier for the device generated by the device itself | `String` |
+| clientIdclient_id | Optional trusted [client identifier](/docs/auth/identified-clients) for the device | `String` |
+| formFactorform_factor | Form factor of the push device. Must be one of `phone`, `tablet`, `desktop`, `tv`, `watch`, `car` or `embedded``embedded` or `other` | `String` |
+| metadata | Optional metadata object for this device. The metadata for a device may only be set by clients with `push-admin` privileges | `Object``Hash` |
+| platform | Platform of the push device. Must be one of `ios` or `android``android` or `browser` | `String` |
+| deviceSecret | Secret value for the device | `String` |
+| push.recipient | Push recipient details for this device. See the [REST API push publish documentation](/docs/api/rest-api#message-extras-push) for more details | `Object``Hash` |
+| push.state | The current state of the push device being either `Active`, `Failing` or `Failed``ACTIVE`, `FAILING` or `FAILED` | `String` |
+| push.errorReasonpush.errorpush.error_reason | When the device's state is failing or failed, this attribute contains the reason for the most recent failure | [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) |
+
+### PushChannelAbly::Models::PushChannel
+
+A `PushChannel` is a property of a [`RealtimeChannel`](/docs/api/realtime-sdk/channels#properties) or [`RestChannel`](/docs/api/rest-sdk/channels#properties). It provides [push devices](/docs/push) the ability to subscribe and unsubscribe to push notifications on channels.
+
+#### Methods
+
+##### subscribeDevice
+
+
+
+`subscribeDevice(): Promise`
+
+
+
+
+`subscribeDevice()`
+
+
+
+Subscribe your device to the channel's push notifications.
+
+
+
+###### Returns
+
+Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+##### subscribeClient
+
+
+
+`subscribeClient(): Promise`
+
+
+
+
+`subscribeClient()`
+
+
+
+[Subscribe all devices associated with your device's clientId](/docs/push/publish#sub-channels) to the channel's push notifications.
+
+
+
+###### Returns
+
+Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+##### unsubscribeDevice
+
+
+
+`unsubscribeDevice(): Promise`
+
+
+
+
+
+`unsubscribeDevice()`
+
+
+
+Unsubscribe your device from the channel's push notifications.
+
+
+
+###### Returns
+
+Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+##### unsubscribeClient
+
+
+
+`unsubscribeClient(): Promise`
+
+
+
+
+`unsubscribeClient()`
+
+
+
+[Unsubscribe all devices associated with your device's clientId](/docs/push/publish#sub-channels) from the channel's push notifications.
+
+
+
+###### Returns
+
+Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+##### listSubscriptions
+
+
+
+`listSubscriptions(Record params?): Promise>`
+
+
+
+
+`PaginatedResult listSubscriptions(String deviceId, String clientId, String deviceClientId, String channel)`
+
+
+
+
+`listSubscriptions(deviceId: String?, clientId: String?, deviceClientId: String?, channel: String?, callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
+
+
+
+Lists push subscriptions on a channel specified by its channel name (`channel`). These subscriptions can be either be a list of client (`clientId`) subscriptions, device (`deviceId`) subscriptions, or if `concatFilters` is set to `true`, a list of both. This method requires clients to have the [Push Admin capability](push#push-admin). For more information, see `GET main.realtime.ably.net/push/channelSubscriptions` [Rest API](/docs/api/rest-api).
+
+
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceId | A deviceId to filter by | `String` |
+| clientId | A clientId to filter by | `String` |
+| deviceClientId | A client ID associated with a device to filter by | `String` |
+| params | An optional object containing key-value pairs to filter subscriptions by. Can contain `clientId`, `deviceId` or a combination of both, and a `limit` on the number of subscriptions returned, up to 1,000 | `Record` |
+
+
+
+
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| deviceId | A deviceId to filter by | `String` |
+| clientId | A clientId to filter by | `String` |
+| deviceClientId | A client ID associated with a device to filter by | `String` |
+| callback | Called with a [`ARTPaginatedResult`](#paginated-result) object containing [`PushChannelSubscription`](/docs/api/realtime-sdk/push-admin#push-channel-subscription) objects or an error | Callback |
+
+
+
+
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|-------------|------|
+| deviceId | A deviceId to filter by | `String` |
+| clientId | A clientId to filter by | `String` |
+| deviceClientId | A client ID associated with a device to filter by | `String` |
+
+
+
+
+
+##### Returns
+
+Returns a promise. On success, the promise is fulfilled with [`PaginatedResult`](#paginated-result) which encapsulates an array of [PushChannelSubscription](#push-channel-subscription) 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`](/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 [PushChannelSubscription](/docs/api/realtime-sdk/push-admin#push-channel-subscription) 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`](/docs/api/realtime-sdk/types#error-info) object with the failure reason.
+
+
+
+
+##### Returns
+
+On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [PushChannelSubscription](#push-channel-subscription) 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`](/docs/api/realtime-sdk/types#ably-exception)
+
+
+
+### PushChannelSubscriptionARTPushChannelSubscriptionChannelSubscriptionArt::Models::PushChannelSubscription
+
+An `PushChannelSubscription` is a type encapsulating the subscription of a device or group of devices sharing a [client identifier](/docs/auth/identified-clients) to a channel in order to receive push notifications.
+
+#### PropertiesMembersAttributes
+
+| Property | Description | Type |
+|----------|------|-------------|
+| channel | The channel that this push notification subscription is associated with | `String` |
+| deviceIddevice_id | The device with this identifier is linked to this channel subscription. When present, `clientId``client_id` is never present | `String` |
+| clientIdclient_id | Devices with this [client identifier](/docs/auth/identified-clients) are included in this channel subscription. When present, `deviceId``device_id` is never present | `String` |
+
+
+
+### PushChannelSubscription constructors
+
+#### PushChannelSubscription.forDevicePushChannelSubscription.for_client
+
+
+
+`PushChannelSubscription.forDevice(String channel, String deviceId) -> PushChannelSubscription`
+
+
+
+
+`PushChannelSubscription.for_device(String channel, String device_id) -> PushChannelSubscription`
+
+
+
+A static factory method to create a `PushChannelSubscription` object for a channel and single device.
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| channel | Channel name linked to this push channel subscription | `String` |
+| deviceIddevice_id | The device with this identifier will be linked with this push channel subscription | `String` |
+
+##### Returns
+
+A [`PushChannelSubscription`](/docs/api/realtime-sdk/types#push-channel-subscription) object
+
+#### PushChannelSubscription.forClientPushChannelSubscription.for_client
+
+
+
+`PushChannelSubscription.forClient(String channel, String clientId) -> PushChannelSubscription`
+
+
+
+
+`PushChannelSubscription.for_client(String channel, String client_id) -> PushChannelSubscription`
+
+
+
+A static factory method to create a `PushChannelSubscription` object for a channel and group of devices sharing a [client identifier](/docs/auth/identified-clients).
+
+##### Parameters
+
+| Parameter | Description | Type |
+|-----------|------|-------------|
+| channel | Channel name linked to this push channel subscription | `String` |
+| clientIdclient_id | Devices with this [client identifier](/docs/auth/identified-clients) are included in the new push channel subscription | `String` |
+
+##### Returns
+
+A `PushChannelSubscription` object
+
+
+
+### PaginatedResultARTPaginatedResultio.ably.lib.types.PaginatedResultAbly::Models::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](/docs/api/rest-api/#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object.
+
+#### PropertiesMembersAttributes
+
+| Property | Description | Type |
+|----------|------|-------------|
+| items | 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
+
+##### first
+
+
+
+`first(): Promise`
+
+
+
+
+`PaginatedResult first`
+
+
+
+
+`PaginatedResult first()`
+
+
+
+
+`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](/docs/api/realtime-sdk/types#deferrable) and yields a [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`](/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
+
+
+
+##### hasNext
+
+
+
+`Boolean hasNext()`
+
+
+
+
+`Boolean has_next?`
+
+
+
+
+`Boolean has_next()`
+
+
+
+Returns `true` if there are more pages available by calling `next` and returns `false` if this page is the last page available.
+
+##### isLast
+
+
+
+`Boolean isLast()`
+
+
+
+
+`Boolean last?`
+
+
+
+
+`Boolean is_last()`
+
+
+
+Returns `true` if this page is the last page and returns `false` if there are more pages available by calling `next` available.
+
+##### next
+
+
+
+`next(): Promise`
+
+
+
+
+`PaginatedResult next`
+
+
+
+
+`PaginatedResult next()`
+
+
+
+
+`PaginatedResult next()`
+
+
+
+
+`next(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
+
+
+
+
+Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null``Null``None``nil` is returned. When using the Realtime library, the `first` method returns a [Deferrable](/docs/api/realtime-sdk/types#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`](/docs/api/realtime-sdk/types#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`](/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()));
+};
+```
+
+
+
+
+
+
+```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())
+```
+
+
+
+
+
+
+```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())")
+ }
+}
+```
+
+
+