# Realtime client The `Realtime` class is the main entry point for using the Ably Pub/Sub JavaScript SDK in realtime mode. It maintains a persistent connection to Ably and provides access to channels, presence, push notifications, and authentication. #### Javascript ``` const realtime = new Ably.Realtime({ authCallback: async (tokenParams, callback) => { try { // Request an Ably-compatible JWT from your own server const response = await fetch('https://your-server.example.com/ably-jwt'); const jwt = await response.text(); callback(null, jwt); } catch (error) { callback(error, null); } }, }); ``` This example uses [token authentication](https://ably.com/docs/auth/token.md): the [`authCallback`](#constructor) requests an [Ably-compatible JWT](https://ably.com/docs/auth/token/jwt.md) from your server whenever a token is needed, which keeps your API key off the client. This is the recommended approach for browsers and other untrusted clients. For trusted, server-side environments you can instead pass a `key` directly to use [basic authentication](https://ably.com/docs/auth/basic.md). ## Properties The `Realtime` interface has the following properties: | Property | Description | Type | | --- | --- | --- | | auth | The [`Auth`](https://ably.com/docs/pub-sub/api/javascript/realtime/auth.md) object for this client. Manages tokens and authentication. | [Auth](https://ably.com/docs/pub-sub/api/javascript/realtime/auth.md) | | channels | The [`Channels`](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md) collection for this client. Used to obtain `RealtimeChannel` instances. | [Channels](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md) | | connection | The [`Connection`](https://ably.com/docs/pub-sub/api/javascript/realtime/connection.md) object for this client. Use this to inspect or subscribe to the connection state. | [Connection](https://ably.com/docs/pub-sub/api/javascript/realtime/connection.md) | | push | The [`Push`](https://ably.com/docs/pub-sub/api/javascript/realtime/push.md) object for this client. Used for push notification device activation and admin operations. | [Push](https://ably.com/docs/pub-sub/api/javascript/realtime/push.md) | | clientId | The client ID this client is identified as. `null` if anonymous. | String or Null | | Crypto | Static access to the [`Crypto`](https://ably.com/docs/pub-sub/api/javascript/realtime/crypto.md) utility. Accessed on the class: `Ably.Realtime.Crypto`. | [Crypto](https://ably.com/docs/pub-sub/api/javascript/realtime/crypto.md) | | Message | Static access to the [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) class for `fromEncoded()` factory methods. Accessed on the class: `Ably.Realtime.Message`. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) | | PresenceMessage | Static access to the [`PresenceMessage`](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) class for `fromEncoded()` factory methods. Accessed on the class: `Ably.Realtime.PresenceMessage`. | [PresenceMessage](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) | | Annotation | Static access to the [`Annotation`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-annotations.md) type for `fromEncoded()` factory methods. Accessed on the class: `Ably.Realtime.Annotation`. | [Annotation](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-annotations.md) |
## Create a new Realtime client `new Ably.Realtime(options: ClientOptions)` Construct a client with a `ClientOptions` object. This is the most common form, allowing all available client options to be configured. `new Ably.Realtime(keyOrToken: string)` A convenience constructor that takes a single API key or token string. Equivalent to passing `{ key: '' }` or `{ token: '' }` as `ClientOptions`. Useful for simple basic-authenticated or test setups. ### Javascript ``` // With ClientOptions const realtime = new Ably.Realtime({ key: 'your-api-key', clientId: 'user-123', logLevel: 3 }); // Or with just a key string const realtime = new Ably.Realtime('your-api-key'); ``` ### Parameters The `Realtime()` constructor takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | options | Required | Configuration options for the client. All properties are optional unless noted. |
| | keyOrToken | Required | A full API key string for basic authentication, or a token string. | String |
| Property | Required | Description | Type | | --- | --- | --- | --- | | key | Optional | The full API key string, as obtained from the [Ably dashboard](https://ably.com/dashboard). Use this option to use [basic authentication](https://ably.com/docs/auth/basic.md), or to issue Ably Tokens without deferring to a separate entity to sign Ably `TokenRequest`s. Initializing with a `key` does not necessarily mean the client uses basic auth: it can also create and sign Ably `TokenRequest`s, and can use token authentication itself if it needs to or if `useTokenAuth` is enabled. | String | | token | Optional | An authenticated token (string) or `TokenDetails` for Token authentication. This option is mostly useful for testing: since tokens are short-lived, in production you almost always want to use an authentication method that lets the SDK renew the token automatically when the previous one expires, such as `authUrl` or `authCallback`. | String or
| | tokenDetails | Optional | A `TokenDetails` object. Used primarily for testing. |
| | authCallback | Optional | A function called when a new token is required. The role of the callback is to obtain a fresh token, one of: an Ably Token string (in plain text format), a signed `TokenRequest`, a `TokenDetails` (in JSON format), or an [Ably JWT](https://ably.com/docs/auth/token/jwt.md), per the [`AuthOptions`](https://ably.com/docs/pub-sub/api/javascript/realtime/auth.md#authorize) contract. | Function | | authUrl | Optional | URL the SDK may call to obtain a token string, `TokenRequest`, or `TokenDetails`. | String | | authMethod | Optional | HTTP verb (`GET` or `POST`) for `authUrl` requests. Default: `GET`. | String | | authHeaders | Optional | Key-value headers added to `authUrl` requests. If the `authHeaders` object contains an `authorization` key, then `withCredentials` is set on the XHR request. | Object | | authParams | Optional | Key-value parameters added to `authUrl` requests as query string (GET) or form data (POST). | Object | | useTokenAuth | Optional | When `true`, forces token authentication. If no `clientId` is specified, the issued token is anonymous. | Boolean | | queryTime | Optional | When `true`, queries Ably for the current time when issuing `TokenRequest`s rather than using the local clock. Knowing the time accurately is needed to create valid signed Ably `TokenRequest`s, so this option is useful for SDK instances on auth servers whose clock cannot be kept synchronized through normal means, such as an NTP daemon. The server is queried once per client instance, which stores the offset from the local clock, so you should avoid instancing a new SDK instance per request. Default: `false`. | Boolean | | defaultTokenParams | Optional | The default `TokenParams` used when issuing tokens. |
| | clientId | Optional | A non-empty client ID for this client. Cannot contain `*`. Used for publishing and presence. A `clientId` may also be implicit in a token used to instantiate the SDK; an error is raised if a `clientId` specified here conflicts with the `clientId` implicit in the token. Find out more about [identified clients](https://ably.com/docs/auth/identified-clients.md). | String | | autoConnect | Optional | Whether to connect to Ably as soon as the client is instantiated. Default: `true`. | Boolean | | closeOnUnload | Optional | Whether to send a close request on the browser `unload` event. Enabling this causes presence leave events to fire immediately when a user navigates away or closes the browser. Without it, an abruptly disconnected client is removed from presence after around 15 seconds and the connection state is retained for around two minutes. Default: `true`. | Boolean | | echoMessages | Optional | Whether messages published from this connection are also received back. Default: `true`. | Boolean | | queueMessages | Optional | Whether messages published while in the disconnected or connecting states are queued for delivery once reconnected. The default behaviour lets applications publish immediately on instancing the SDK without waiting for the connection to be established. Disable this option to take application-level control over queueing. Default: `true`. | Boolean | | strictMode | Optional | When `true`, operations that would otherwise fail silently, such as those gated on a channel mode, reject with an `ErrorInfo` whose `remediation` describes the cause and how to fix it. When `false`, the same paths emit a warning log and return their legacy silent value. A future major version will make the strict behaviour unconditional. Default: `false`. | Boolean | | recover | Optional | A recovery key string, or a callback that enables [connection state recovery](https://ably.com/docs/connect/states.md#connection-state-recover-options). When a callback is provided, the SDK persists the recovery key between page reloads and calls the callback so it can decide whether to recover the connection. | String or
| | recoveryKeyStorageName | Optional | The storage key used for persisting the recovery key. | String | | endpoint | Optional | A custom routing policy or fully-qualified host name for the Ably service. Enables [enterprise customers](https://ably.com/docs/platform/account/enterprise-customization.md) to use their own custom endpoints, which support dedicated, isolated clusters and regional message routing and storage constraints. | String | | environment | Optional | Deprecated, use `endpoint` instead. Enables [enterprise customers](https://ably.com/docs/platform/account/enterprise-customization.md) to use their own custom environments, which support dedicated, isolated clusters and regional message routing and storage constraints. | String | | port | Optional | A non-default port for non-TLS connections. Default: `80`. | Number | | tls | Optional | Whether to use a secure TLS connection. An insecure connection cannot be used with basic authentication, as it could compromise the private API key in transit. Default: `true`. | Boolean | | tlsPort | Optional | A non-default port for TLS connections. Default: `443`. | Number | | fallbackHosts | Optional | An array of alternative hosts used for failover. When a custom environment or endpoint is specified, fallback host functionality is disabled; in that case, use any custom fallback hosts provided by your customer success manager. Default: the five `a`–`e` `.ably-realtime.com` hosts. | `String[]` | | transports | Optional | Preferred transports for the realtime connection, in descending order of preference. In the browser the available transports are `web_socket` and `xhr_polling`. In Node.js they are `web_socket`, `xhr_polling`, and `comet`. | `String[]` | | transportParams | Optional | Arbitrary parameters appended to the connection URL, such as `heartbeatInterval` and `remainPresentFor`. | Object | | logLevel | Optional | Logging verbosity: `0` (no logs), `1` (errors only), `2` (errors plus connection and channel state changes), `3` (high-level debug output), and `4` (full debug output). | Number | | logHandler | Optional | A custom log handler function. Default: `console.log`. | Function | | disconnectedRetryTimeout | Optional | The delay before retrying a disconnected connection, in milliseconds. Default: 15000. | Number | | suspendedRetryTimeout | Optional | The delay between reconnection attempts when in the `suspended` state, in milliseconds. Default: 30000. | Number | | realtimeRequestTimeout | Optional | The acknowledgement timeout for realtime operations, in milliseconds. Default: 10000. | Number | | httpOpenTimeout | Optional | Timeout for opening an HTTP connection, in milliseconds. Default: 4000. | Number | | httpRequestTimeout | Optional | Timeout for an entire HTTP request, in milliseconds. Default: 10000. | Number | | httpMaxRetryCount | Optional | Maximum number of fallback host attempts for HTTP requests. Default: 3. | Number | | httpMaxRetryDuration | Optional | Maximum elapsed time for HTTP retries, in milliseconds. Default: 15000. | Number | | connectivityCheckUrl | Optional | A custom URL used to check internet availability. | String | | disableConnectivityCheck | Optional | When `true`, disables the internet connectivity check. Default: `false`. | Boolean | | wsConnectivityCheckUrl | Optional | A custom URL used for WebSocket connectivity checking. | String | | idempotentRestPublishing | Optional | Whether to enable client-side message ID assignment for idempotent REST publishing. Default: `true`. | Boolean | | useBinaryProtocol | Optional | Whether to use the binary MsgPack protocol. Disabled by default in browsers because browsers are optimized for decoding JSON. Default: `true` in Node.js, `false` elsewhere. | Boolean | | maxMessageSize | Optional | Maximum payload size in bytes. Default: 65536. | Number | | pushServiceWorkerUrl | Optional | The service worker URL used for push notifications. | String | | plugins | Optional | A map of plugin types to plugin instances. Used to load optional modular features like LiveObjects. | Object | | restAgentOptions | Optional | Node.js HTTP/HTTPS agent configuration. | Object |
| Property | Required | Description | Type | | --- | --- | --- | --- | | ttl | Optional | Requested time to live for the token in milliseconds. When omitted, the Ably REST API default of 60 minutes is applied. Default: 1 hour. | Number | | capability | Optional | The capabilities associated with this token. A JSON-encoded representation of the resource paths and associated operations. If the `TokenRequest` is successful, the capability of the returned token is the intersection of this capability with the capability of the issuing key. [Read more about capabilities](https://ably.com/docs/auth/capabilities.md). Default: `{"*":["*"]}`. | String or Object | | clientId | Optional | A client ID, used for identifying this client when publishing messages or for presence purposes. The `clientId` can be any non-empty string, except it cannot contain a `*`. | String | | timestamp | Optional | The timestamp of this request as milliseconds since the Unix epoch. `timestamp`, in conjunction with the `nonce`, is used to prevent token requests being replayed. It is a one-time value and is not valid as a member of any default token params, such as `defaultTokenParams`. | Number | | nonce | Optional | A cryptographically secure random string of at least 16 characters, used to ensure the `TokenRequest` cannot be reused. | String |
| Property | Description | Type | | --- | --- | --- | | token | The Ably Token itself. A typical Ably Token string appears with the form `xVLyHw.A-pwh7wicf3afTfgiw4k2Ku33kcnSA7z6y8FjuYpe3QaNRTEo4`. | String | | issued | The timestamp at which this token was issued as milliseconds since the Unix epoch. | Number | | expires | The timestamp at which this token expires as milliseconds since the Unix epoch. | Number | | capability | The capabilities associated with this token. A JSON-encoded representation of the resource paths and associated operations. | String | | clientId | The client ID, if any, bound to this token. If a client ID is included, the token may only be used to perform operations on behalf of that client ID. | String |
| Parameter | Description | Type | | --- | --- | --- | | lastConnectionDetails | Details of the previous connection, used to decide whether to recover it. |
| | callback | Call with `true` to recover the connection, or `false` to establish a fresh connection. | `recoverConnectionCompletionCallback` |
| Property | Description | Type | | --- | --- | --- | | recoveryKey | An opaque string obtained from the [`recoveryKey`](https://ably.com/docs/pub-sub/api/javascript/realtime/connection.md) of the connection before the page was unloaded, used to recover the connection. | String | | disconnectedAt | The time at which the previous client was abruptly disconnected before the page was unloaded, as milliseconds since the Unix epoch. | Number | | location | A clone of the `location` object of the previous page's `document` object before the page was unloaded. A common use is to confirm the previous page URL matches the current URL before allowing recovery. | String | | clientId | The `clientId` of the client's `Auth` object before the page was unloaded. A common use is to confirm the current user's `clientId` matches the previous connection's `clientId` before allowing recovery. | String or Null |
## Open the connection `realtime.connect(): void` Calls [`connection.connect()`](https://ably.com/docs/pub-sub/api/javascript/realtime/connection.md#connect), explicitly initiating the connection if [`clientOptions.autoConnect`](#constructor-params) was set to `false`. ### Javascript ``` realtime.connect(); ``` ## Close the connection `realtime.close(): void` Calls [`connection.close()`](https://ably.com/docs/pub-sub/api/javascript/realtime/connection.md#close), causing the connection to close and entering the `closing` state. Once `closed`, the SDK will not attempt to reconnect. ### Javascript ``` realtime.close(); ``` ## Get server time `realtime.time(): Promise` Returns the time from the Ably service as milliseconds since the Unix epoch. Clients that do not have access to a sufficiently well-maintained time source and wish to issue Ably `TokenRequest`s with a more accurate timestamp should use the [`clientOptions.queryTime`](#constructor-params) client option instead of this method. ### Javascript ``` const now = await realtime.time(); ``` ### Returns `Promise` Returns a promise. The promise is fulfilled with the server time as milliseconds since the Unix epoch, or rejected with an [`ErrorInfo`](#errorinfo) object. ## Get account stats `realtime.stats(params?: StatsParams): Promise>` Retrieves usage statistics for the account, filtered by the supplied query parameters. Returns a paginated set of `Stats` objects, each containing usage [metrics](https://ably.com/docs/metadata-stats/stats.md#metrics). ### Javascript ``` const page = await realtime.stats({ unit: 'hour', limit: 24 }); ``` ### Parameters The `stats()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | params | Optional | Query parameters for the stats request. |
|
| Property | Required | Description | Type | | --- | --- | --- | --- | | start | Optional | The start time for the query, in milliseconds since the Unix epoch. Default: the beginning of time. | Number | | end | Optional | The end time for the query, in milliseconds since the Unix epoch. Default: current time. | Number | | direction | Optional | The order of returned stats. `'backwards'` or `'forwards'`. Default: `'backwards'`. | String | | limit | Optional | An upper limit on the number of stats records returned. Default: 100. Maximum: 1000. | Number | | unit | Optional | The granularity of the returned stats: `'minute'`, `'hour'`, `'day'`, or `'month'`. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval. Default: `'minute'`. | String |
### Returns `Promise>` Returns a promise. The promise is fulfilled with a [`PaginatedResult`](#PaginatedResult) of `Stats` objects, or rejected with an [`ErrorInfo`](#errorinfo) object. #### Stats Each `Stats` entry contains the following properties: | Property | Description | Type | | --- | --- | --- | | appId | The Ably application ID. | String | | intervalId | The UTC time period that this stats entry refers to. If `unit` was requested as `minute` this is in the format `YYYY-mm-dd:HH:MM`, if `hour` it is `YYYY-mm-dd:HH`, if `day` it is `YYYY-mm-dd:00`, and if `month` it is `YYYY-mm-01:00`. | String | | inProgress | For entries that are still in progress, such as the current month, the last sub-interval included in this stats entry, in the format `yyyy-mm-dd:hh:mm:ss`. | String | | entries | A map of statistics entries (for example `messages.all.count`, `messages.inbound.realtime.count`) to their values. The `schema` property provides further information. | `Record` | | schema | A URL to the JSON Schema describing the structure of this object. | String |
## Make a REST request `realtime.request(method: string, path: string, version: number, params?: any, body?: any, headers?: any): Promise` Makes a REST request to a provided path. Useful for accessing Ably APIs that do not have a dedicated method in the SDK, without having to handle authentication, paging, fallback hosts, and MsgPack or JSON support yourself. ### Javascript ``` const response = await realtime.request( 'GET', '/channels/your-channel-name/messages', 3, { limit: 10 } ); ``` ### Parameters The `request()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | method | Required | The HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). | String | | path | Required | The path of the API endpoint to call. | String | | version | Required | The API version (e.g. `3`). | Number | | params | Optional | Query parameters. | Object | | body | Optional | The request body, for `POST`, `PUT`, and `PATCH` methods only. Must be anything that can be serialized into JSON, such as an object or array. | Any | | headers | Optional | Custom HTTP headers. | Object |
### Returns `Promise` Returns a promise. The promise is fulfilled with an `HttpPaginatedResponse`, or rejected with an [`ErrorInfo`](#errorinfo) object. Note that if a response is obtained, any response, even one with a non-2xx status code, resolves as an `HttpPaginatedResponse` rather than rejecting. #### HttpPaginatedResponse `HttpPaginatedResponse` contains the following properties: | Property | Description | Type | | --- | --- | --- | | statusCode | The HTTP status code of the response. | Number | | success | `true` if the status code is in the 200-299 range. | Boolean | | errorCode | The error code, derived from the `X-Ably-Errorcode` HTTP header, if sent in the response. | Number | | errorMessage | The error message, derived from the `X-Ably-Errormessage` HTTP header, if sent in the response. | String | | errorDetail | A map of structured error metadata. | Object or Undefined | | headers | The response headers. | Object | | items | The current page of results. | `Array` |
`HttpPaginatedResponse` also contains the following methods to handle pagination: ##### Check for more pages `hasNext(): boolean` Returns `true` if there are more pages available by calling `next()`. ##### Check if last page `isLast(): boolean` Returns `true` if this is the last page of results. ##### Get next page `next(): Promise` Returns a promise. The promise is fulfilled with the next page of results as a [`PaginatedResult`](#PaginatedResult), or `null` if there are no more pages. Rejected with an [`ErrorInfo`](#errorinfo) object on failure. ##### Get first page `first(): Promise` Returns a promise. The promise is fulfilled with the first page of results as a [`PaginatedResult`](#PaginatedResult), or rejected with an [`ErrorInfo`](#errorinfo) object. ##### Get current page `current(): Promise` Returns a promise. The promise is fulfilled with the current page of results as a [`PaginatedResult`](#PaginatedResult), or rejected with an [`ErrorInfo`](#errorinfo) object. ## Batch publish to multiple channels `realtime.batchPublish(spec: BatchPublishSpec): Promise` Publish using a single `BatchPublishSpec`, fulfilled with a single `BatchResult`. `realtime.batchPublish(specs: BatchPublishSpec[]): Promise` Publish using an array of `BatchPublishSpec` objects, fulfilled with one `BatchResult` per spec. Each spec publishes one or more messages to up to 100 channels in a single [batch publish](https://ably.com/docs/messages/batch.md) request. ### Javascript ``` const result = await realtime.batchPublish({ channels: ['channel1', 'channel2'], messages: [{ name: 'event', data: 'hello' }] }); ``` ### Parameters The `batchPublish()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | spec | Required | A single batch publish spec. |
| | specs | Required | An array of batch publish specs. |
[] |
| Property | Required | Description | Type | | --- | --- | --- | --- | | channels | Required | The names of the channels to publish the messages to. | `String[]` | | messages | Required | An array of [`Message`](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md) objects. | [Message](https://ably.com/docs/pub-sub/api/javascript/realtime/message.md)[] |
### Returns `Promise` Returns a promise. For a single spec, the promise is fulfilled with a `BatchResult`. For an array of specs, the promise is fulfilled with an array of `BatchResult`s. Rejected with an [`ErrorInfo`](#errorinfo) object on failure. | Property | Description | Type | | --- | --- | --- | | successCount | The number of successful operations in the request. | Number | | failureCount | The number of unsuccessful operations in the request. | Number | | results | The per-channel results, one entry per channel. | Array of
or
|
| Property | Description | Type | | --- | --- | --- | | channel | The channel name. | String | | messageId | A unique ID prefixed to the `Message.id` of each published message. | String | | serials | An array of message serials corresponding 1:1 to the messages that were published. A serial may be `null` if the message was discarded due to [message conflation](https://ably.com/docs/messages.md#conflation). | Array of String or Null |
| Property | Description | Type | | --- | --- | --- | | channel | The channel name. | String | | error | The error describing why the publish to this channel failed. | [ErrorInfo](#errorinfo) |
## Batch presence query `realtime.batchPresence(channels: string[]): Promise` Retrieves the presence set for up to 100 channels in a single REST request. The presence state includes the `clientId` of members and their current [`PresenceAction`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md). ### Parameters The `batchPresence()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | channels | Required | The names of the channels to query. | `String[]` |
### Returns `Promise` Returns a promise. The promise is fulfilled with an array of `BatchResult` objects, one per channel, where each `results` entry is a `BatchPresenceSuccessResult` or a `BatchPresenceFailureResult`. Rejected with an [`ErrorInfo`](#errorinfo) object on failure. | Property | Description | Type | | --- | --- | --- | | successCount | The number of successful operations in the request. | Number | | failureCount | The number of unsuccessful operations in the request. | Number | | results | The per-channel results, one entry per channel. | Array of
or
|
| Property | Description | Type | | --- | --- | --- | | channel | The channel name the presence state was retrieved for. | String | | presence | An array of [`PresenceMessage`](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) objects describing the members present on the channel. | [PresenceMessage](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md)[] |
| Property | Description | Type | | --- | --- | --- | | channel | The channel name the presence state failed to be retrieved for. | String | | error | The error describing why the presence query for this channel failed. | [ErrorInfo](#errorinfo) |
## Get the local device `realtime.getDevice(): Promise` Retrieves a [`LocalDevice`](https://ably.com/docs/pub-sub/api/javascript/realtime/push.md#LocalDevice) object representing the current device as a push notification target, loading its state from persistent storage if necessary. ### Returns `Promise` Returns a promise. The promise is fulfilled with the [`LocalDevice`](https://ably.com/docs/pub-sub/api/javascript/realtime/push.md#LocalDevice), or rejected with an [`ErrorInfo`](#errorinfo) object. ## PaginatedResult A `PaginatedResult` represents a page of results from a paginated query such as [`stats()`](#stats), [`channel.history()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md#history), [`presence.history()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md#history), or [`channel.getMessageVersions()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md#get-message-versions). ### Properties `PaginatedResult` contains the following properties: | Property | Description | Type | | --- | --- | --- | | items | The current page of results. | `Array` |
`PaginatedResult` also contains the following methods to handle pagination: ### Check for more pages `hasNext(): boolean` Returns `true` if there are more pages available. ### Check if last page `isLast(): boolean` Returns `true` if this is the last page of results. ### Get next page `next(): Promise` Returns a promise fulfilled with the next page of results, or `null` if there are no more pages. Rejected with an [`ErrorInfo`](#errorinfo) object on failure. ### Get first page `first(): Promise` Returns a promise fulfilled with the first page of results, or rejected with an [`ErrorInfo`](#errorinfo) object. ### Get current page `current(): Promise` Returns a promise fulfilled with the current page of results, or rejected with an [`ErrorInfo`](#errorinfo) object. ## ErrorInfo A standardized, generic Ably error object that contains an Ably-specific error code, a generic HTTP status code, and a human-readable message. All errors emitted by Ably are `ErrorInfo` instances. | Property | Description | Type | | --- | --- | --- | | code | The Ably-specific error code. | Number | | statusCode | The HTTP status code corresponding to this error, where applicable. | Number | | message | A human-readable description of what went wrong. | String | | cause | The underlying error that caused this error, where applicable. | ErrorInfo or Undefined | | detail | An optional map of string key-value pairs containing structured metadata associated with the error. | Object or Undefined | | remediation | Actionable guidance describing how to fix the error, as distinct from `message`, which describes what went wrong. Present only on SDK-originating errors with meaningful remediation steps. | String or Undefined |
## Related Topics - [Auth](https://ably.com/docs/pub-sub/api/javascript/realtime/auth.md): API reference for the Authentication (Auth) interface in the Ably Pub/Sub JavaScript Realtime SDK. - [Connection](https://ably.com/docs/pub-sub/api/javascript/realtime/connection.md): API reference for the Connection interface in the Ably Pub/Sub JavaScript Realtime SDK. - [Crypto](https://ably.com/docs/pub-sub/api/javascript/realtime/crypto.md): API reference for the Encryption (Crypto) utility in the Ably Pub/Sub JavaScript Realtime SDK. ## Documentation Index To discover additional Ably documentation: 1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages. 2. Identify relevant URLs from that index. 3. Fetch target pages as needed. Avoid using assumed or outdated documentation paths.