diff --git a/content/api/rest-api.textile b/content/api/rest-api.textile deleted file mode 100644 index 57854cbf6f..0000000000 --- a/content/api/rest-api.textile +++ /dev/null @@ -1,1512 +0,0 @@ ---- -title: REST API Reference -meta_description: "Ably provides the raw REST API for situations where an Ably client library SDK is not available on the platform of choice, or due to resource constraints." -meta_keywords: "REST API, REST, protocol, resource constraints" -section: api -index: 100 -jump_to: - Intro: - - Common API behavior#common - Authentication: - - Authentication - - Basic Authentication - - Token Authentication - Channel API: - - publish - - message history#message-history - - presence - - presence history - Push API: - - register device#post-device-registration - - update a device registration#update-device-registration - - get registered device#get-device-registration - - list registered devices#list-device-registrations - - reset a device's update token#reset-update-token - - unregister device#delete-device-registration - - unregister devices#delete-device-registrations - - subscribe to a channel#post-channel-subscription - - unsubscribe from channels#delete-channel-subscription - - list channel subscriptions#list-channel-subscriptions - - list channels#list-channels - - publish directly to device#push-publish - - publish via batch push API#push-publish-batch - Authentication API: - - requestToken#request-token - - revokeTokens#revoke-tokens - Application API: - - stats - Batch API: - - batch publish#batch-publish - - batch presence#batch-presence - Utilities API: - - time -redirect_from: - - /docs/api/versions/v1.1/rest-api - - /docs/api/versions/v1.0/rest-api - - /docs/api/versions/v0.8/rest-api - - /docs/api/versions/v1.1/beta - - /docs/rest-api - - /docs/rest-api/versions/v1.1 - - /docs/rest-api/versions/v1.0 - - /docs/rest-api/versions/v0.8 - - /docs/rest-api/versions/v1.1/beta ---- - -Welcome to the Ably REST API Reference documentation. - -The Ably REST API provides a way for a wide range of server and client devices to communicate with the Ably service over "REST":https://en.wikipedia.org/wiki/Representational_State_Transfer. The REST API does not provide a realtime long-lived connection to Ably, but in all other respects is a simple subset of the full "realtime messaging API":/docs/api/realtime-sdk. - -The primary use-case for the REST API is for servers that are part of the back-end of an application such as a web application, that publish messages, issue access tokens (temporary and client-specific) for its various clients, obtain message and presence history, and retrieve statistics. - -The functional scope of the REST API includes: - -* "Authentication":#authentication of the server with Ably, and creation of tokens for use by clients. -* "Publication of messages":#publish -* "Retrieval of message history":#message-history -* "Retrieval of presence state and presence":#presence -* "Retrieval of statistics for application usage":#stats - -Using the REST API directly is fully supported, Ably recommends that customers should use the Ably REST client libraries SDKs, that support a "range of platforms":https://ably.com/download, including the following examples: - -* "JavaScript":https://ably.com/download -* "iOS":https://ably.com/download -* "Android":https://ably.com/download -* "Java":https://ably.com/download -* "Python":https://ably.com/download -* "Ruby":https://ably.com/download -* ".NET":https://ably.com/download -* "Go":https://ably.com/download - -The "Ably client libraries SDKs are documented":https://ably.com/docs, and provide additional features that improve performance and resilience that the REST API cannot deliver on its own, such as automatic re-routing around network problems by using alternative datacenters. - -You can also use the "Rest#request()":/docs/api/rest-sdk#request method to make arbitrary API calls against Ably, to use endpoints that libraries do not yet have built-in support for. - -h2(#common). Common API behavior - -h3(#general). General - -The REST API defaults to returning results, and expects request bodies, in JSON format. An Accept header is used to specify a specific response format - JSON or an alternative - and the following formats are allowed: - -* @application/json@: JSON; -* @application/javascript@: for JSONP. A @callback@ query parameter is also expected, which defaults simply to "callback"; -* @application/x-msgpack@: for "MessagePack":https://msgpack.org/, the efficient binary serialization format that is similar to JSON, but faster and smaller; -* @text/html@: HTML - -It is also possible to specify the response format with the @format@ query parameter (with supported values being @json@, @jsonp@, @msgpack@, @html@). Any Accept header takes precedence over a @format@ parameter. - -Similarly, POST requests may contain a request body in JSON or other formats as indicated by a @Content-Type@ header. The supported content types are: - -* @application/json@: JSON; -* @application/x-msgpack@: "MessagePack":https://msgpack.org/, the efficient binary serialization format that is similar to JSON, but faster and smaller; -* @application/x-www-form-urlencoded@: Form-encoded. - -Specific request and response data types are documented in the context of each API or route. - -A response status code of 20X (200, 201 or 204) indicates success. A successful result will typically provide a response body but certain operations (such as DELETE) may respond with a 204 response and no response body. - -All other "standard HTTP statusCodes":https://en.wikipedia.org/wiki/List_of_HTTP_status_codes signify an error. Errors from all APIs are returned as an object of the form: - -bc[json]. { - error: { - code: , - message: , - statusCode: - } -} - -Additionally, when you may not have access to the response body due to limitations of your HTTP client, we include the following custom Ably headers to work around that problem: - -bc[text]. X-Ably-ErrorCode: -X-Ably-ErrorMessage: - -The properties of an Ably error are: - -- code := A specific reason code as defined in the "public errors definition":https://github.com/ably/ably-common/blob/main/protocol/errors.json, where one is known -- statusCode := Where a code is not available, the statusCode provides a generic indication of the nature of the failure and maps to "standard HTTP statusCodes":https://en.wikipedia.org/wiki/List_of_HTTP_status_codes -- message := The message string is an English language string that aims to provide useful information to the developer. It is not necessarily intended to be an informative string for the end user - -Wherever possible, success response bodies contain links, in "HATEOS":https://en.wikipedia.org/wiki/HATEOAS style, to other resources relevant to the response; where these are present these are included as @href@ attributes on the applicable part of the response object. - -@GET@, @PUT@, @POST@ and @DELETE@ are available in all contexts where they make sense. @GET@ is always idempotent. - -h3(#versioning). Versioning - -By default, all requests receive the latest version of the API, which is currently @1.1@. - -When we make backwards-incompatible API changes to the API, we release new versions. Therefore, we encourage you to explicitly request the version you are interfacing with in all requests using one of the following mechanisms: - -1. Include the @X-Ably-Version@ header. Example: - -bc[sh]. curl https://main.realtime.ably.net/time \ - -H "X-Ably-Version: 1.2" - -2. Include the version query string param @v@. Example: - -bc[sh]. curl https://main.realtime.ably.net/time?v=1.2 - -h3(#pagination). Pagination - -REST APIs whose responses may have unbounded size have paginated responses; that is, if a full response to the query could exceed a limit (a default or a @limit@ given as a parameter to the call) the first response contains a subset of the results, and further "pages" of the result are available on subsequent requests. Each response (the initial response and responses to each subsequent request) is accompanied by one or more relative links relating to the current query. - -Responses contain one or more of the following relative links: - -- @first@ := a link to the first page of results for this query. This link also makes the query repeatable; any params that are resolved at query time (for example default values for omitted time-related params) have their resolved values included explicitly in the @first@ link. - -- @current@ := a stable link to the current page of results. - -- @next@ := on each page except the last in a paginated result, the next link is a link to the next page of results. - -Relative links are presented by default as an "RFC 5988 Link HTTP response header":https://tools.ietf.org/html/rfc5988; there is a separate @Link@ header for each relative link accompanying the response. The rel types used are @first@, @next@ and @current@ as specified in the RFC. - -A @Link@ header has the format: - -pre. Link: <{url}>; rel="{rel}" - -where @{url}@ is the URL of the link and @{rel}@ is the relation type. - -For example: - -pre. Link: <./stats?start=1380794880000&end=1380794881058&limit=100&unit=minute&direction=forwards -&format=json&first_start=1380794880000>; rel="first" - -In principle the link URL might be any valid URL but in practice it will always be a relative URL, and it must be interpreted relative to the original query URL. Clients should treat link URLs opaquely; in particular, params (such as @first_start@ in the example above) may be undocumented and unsupported except where a client uses the link URL in its entirety. - -Clients that are unable to process response headers may also request an @envelope@ response type. - -h3(#control-response-content). Control of response content - -By default the response body of a query response will contain the requested resource, encoded in the requested format. However, there are also query params that allow the response body to be adjusted to contain only a subset of the representation, or a restructured representation. - -The following params are supported: - -h4(#control-response-content-fields). fields - -Specifying @?fields=[,, ...]@ returns the representation containing only the specified fields. A field spec is a specifier which is either a single field - in which case the representation contains only that fields's value - or a dot-separated sequence of fields, in which case the representation contains only the fields matching those given in the field spec at each level in the hierarchy. - -h5. Example - -```[sh] - curl https://main.realtime.ably.net/stats?fields=channels.peak,intervalId \ - -u "{{API_KEY}}" - - # Response - [{ - "channels": { "peak": 2 }, - "intervalId": "2015-11-20:15" - }] -``` - -h4(#flatten). flatten - -Specifying @?flatten=true@ will result in a flattened representation, with the returned object structure being flattened into one with a single level of long keys instead of a deep structure. When the results contain array elements, the array index of each element is included as the corresponding component of the result key. - -h5. Example - -```[sh] - curl https://main.realtime.ably.net/stats?flatten=true&fields=channels.peak,intervalId \ - -u "{{API_KEY}}" - - # Response - { - "0.channels.peak": 2, - "0.intervalId": "2015-11-20:15" - } -``` - -h4(#select). select - -Specifying @?select=@ returns a representation of the resource containing only the fields that match the given path specification. Like the fields param this permits only specific fields to be obtained, but the path spec may contain wildcard elements, and all matching fields in the representation are returned. - -The result is a partially-flattened representation, as a map whose keys are the long keys that match the path spec, and the values are the corresponding values. When the results contain array elements, the array index of each element is included as the corresponding component of the result key. - -h5. Example - -```[sh] - curl https://main.realtime.ably.net/stats?select=*.channels.* \ - -u "{{API_KEY}}" - - # Response - [{ - "0.channels.peak": 5, - "0.channels.min": 1, - "0.channels.mean": 3, - "0.channels.opened": 2 - }] -``` - -h3(#envelope-response-format). Envelope response format - -A client that is unable to access response headers or status code can request an @envelope@ response that contains the usual response, plus @Link@ header information and the response status code wrapped in an object as a single response body. This is useful for JSONP and may be useful in other environments. Envelope responses are only supported for JSON, JSONP and HTML formats. - -A client requests an envelope response by including an @envelope=@ param in the request. - -A JSON envelope response body response for a request with an @envelope=json@ param has the format: - -```[json] - { - "statusCode": , - "response": , - "rel": { - "first": , - ... - } - } -``` - -where the @response@ member references the API result in the usual format. The @rel@ member, present only in paginated responses, includes each of the rel links associated with the response. - -Envelope responses always are always made with a 200 status code; the status of the API request itself must be obtained from the @statusCode@ member of the response body. - -h2(#authentication). Authentication - -To understand the REST API it is easiest first to understand the various authentication methods that Ably supports. For a detailed explanation, view the "Authentication documentation":/docs/auth. - -Clients can access Ably, whether using REST or the Realtime service, by two methods: - -1. Basic authentication -2. Token authentication - -Each of these is explained in more detail in the following sections. - -h3(#basic-authentication). Basic Authentication - -Using one of the application keys created via the "application dashboard":https://ably.com/dashboard, basic authentication provides the simplest method to authenticate with Ably, but has two important limitations: - -* the application key is transmitted over the network as part of a request; therefore it may only be used over TLS (HTTPS or "SSL") connections. This can be a performance disadvantage in some network environments where long round-trip times are amplified by the SSL handshake. -* the client using the API must be in possession of the application key, which potentially exposes the key to compromise. For example, it is not advisable to simply embed the key in a script in a public web page. - -h4(#using-basic-auth). Usage in HTTP request header - -pre. Authorization: Basic - -where @@ is the full application key string obtained through the dashboard, encoded with "RFC 4648 Base64":https://datatracker.ietf.org/doc/html/rfc4648. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/channels/rest-example/messages \ - --header "Authorization: Basic {{API_KEY_BASE64}}" - -When using a generic HTTP client library that accepts separate username and password arguments for an HTTP request, the application key can be split at the first colon, with the initial segment being used as the username, and the remaining string (without the leading colon) used as the password. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/channels/rest-example/messages \ - --user "{{API_KEY}}" - -h3(#token-authentication). Token Authentication - -*Token Authentication* uses an Ably-compatible token to authenticate with Ably without sharing a private API key. This can be an "Ably Token":/docs/api/rest-sdk/authentication#tokens obtained via the REST API "@requestToken@":#request-token endpoint, an "Ably JWT":/docs/api/rest-sdk/authentication#ably-jwt signed by your API key, or an "External JWT":https://jwt.io object "with an embedded Ably-compatible token":/docs/auth/token#embedded. Tokens are authentication credentials that are short-lived, and therefore they may more readily be distributed to clients where there is a risk of compromise. Tokens may also be issued with a particular scope - such as a limited set of "access rights or capabilities":/docs/auth/capabilities or being limited to use by a specific "@clientId@ identity":#identified-clients - and therefore token-based authentication provides the flexibility to implement access and identity control policies in the application. See the "Token Authentication documentation":/docs/auth/token for more details. - -The construction of an Ably "@TokenRequest@":/docs/api/token-request-spec is described in the "Authentication Ably TokenRequest spec documentation":/docs/api/token-request-spec. The resulting @token response@ object contains the token properties as defined in "Ably TokenRequest spec":/docs/api/token-request-spec. - -h4(#using-token-auth). Usage in HTTP request header - -pre. Authorization: Bearer - -The @@ is either the @token@ attribute of the Ably Token generated by "@requestToken@":#request-token encoded with "RFC 4648 Base64":https://datatracker.ietf.org/doc/html/rfc4648, or an "Ably JWT":/docs/api/rest-sdk/authentication#ably-jwt. If using a generic HTTP client library it will probably be necessary to add the @Authorization@ header explicitly. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/channels/rest-example/messages \ - --header "Authorization: Bearer {{TOKEN_BASE64}}" - -h2(#channel). Channel routes - -Routes providing access to the messaging service within a channel scope. - -h3(#publish). Publish one or more messages on a channel - -h6. POST main.realtime.ably.net/channels/@@/messages - -Publish a message on a channel. Note that since the REST API is stateless, publication using this API is outside the context of any specific connection. - -The request body contains message details and is an object of the form: - -bc[json]. { - data: , - name: , - encoding: , - clientId: , - connectionKey: , - id: , - extras: -} - -In JSON format, the accepted types for the @data@ payload are: - -* string -* any JSON-encodable Array or Object. - -MessagePack additionally "supports byte arrays":https://github.com/msgpack/msgpack/blob/master/spec.md#formats-bin - -A message may be published over REST on behalf of an existing realtime connection when a valid @connectionKey@ is present. For example, if you want to publish a message using the REST API so that it appears to come from an existing connected realtime client, then the connection's "private (secret) connection key":/docs/api/realtime-sdk/connection#key must be included. - -Example request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/channels/rest-example/messages \ - -u "{{API_KEY}}" \ - -H "Content-Type: application/json" \ - --data '{ "name": "publish", "data": "example" }' - -If you're wanting to publish a message *idempotently* (multiple publishes of the same message are not duplicated), you should set the @id@ to be unique between each message. Only the first message received by Ably with a specific @id@ will then be sent to a channel and its subscribers. - -If you wish to publish a message to multiple channels at once, you should consider using our "batch publish functionality":#batch. - -h5(#idempotent-publish). Idempotent publishing - -It is possible for a client publishing through REST to not receive an acknowledgement of receipt from Ably for numerous reasons such as network failures outside of our control. In this scenario, you will likely wish to re-publish the message, but not risk duplicating it within the network. This is possible through the addition of an @id@ in the body of your POST, where the @id@ should uniquely identify the message. - -h5(#message-extras). Message extras - -Messages can include an optional @extras@ field, used by extensions to Ably's core realtime service. For example, @extras.ephemeral@ can be set to @true@ to "make an ephemeral publish":/docs/pub-sub/advanced#ephemeral. - -h5(#message-extras-push). Send push notification - -You can send a push notification to devices "subscribed to a channel":#post-channel-subscription by setting the @push@ field in the @extras@ object, like this: - -bc[json]. { - <... message fields ...> - extras: { - push: { - data: , - notification: { - title: , - body: , - icon: , - sound: , - collapseKey: - } - apns: , - fcm: , - web: , - } - } -} - -For each underlying transport service (like APNs, FCM, etc.) an object can be provided with the same shape as the parent object, plus any transport-specific field you may want to add (e. g. @content-available@ for APNs). - -Full example of a request publishing a message with a push payload: - -bc[sh]. curl -X POST https://main.realtime.ably.net/channels/push-enabled:rest-example/messages \ - -u "{{API_KEY}}" \ - -H "Content-Type: application/json" \ - --data \ - ' -{ - "name": "some event name for realtime receivers", - "data": "example non-push data for realtime receivers", - "extras": { - "push": { - "notification": { - "title": "Hello from Ably!", - "body": "Example push notification from Ably." - }, - "data": { - "foo": "bar", - "baz": "qux" - }, - "apns": { - "notification": { - "content-available": 1, - "sound": "ably-ios.wav" - } - } - } - } -} -' - -h5. Parameters - -- enveloped := if present and equal to @false@, does an "unenveloped publish":#unenveloped - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := @application/json@ (the default), @application/x-msgpack@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -When successful, returns status code 201 and an object with @channel@ and @messageId@ properties, in case you want to know the message ID assigned to correlate with messages received by realtime subscribers or Ably Integration recipients. When unsuccessful, returns an error as an "ErrorInfo":/docs/api/rest-sdk/types#error-info object. - -h3(#unenveloped). Unenveloped publish - -If the @enveloped@ parameter is present and set to @false@, the request body is interpreted as the data payload for a message to be published, rather than (as it would normally be) as a @Message@ object or array of @Message@ objects. This can be useful if, for example, you want an Ably publish to be triggered by a webhook from some third-party service where you cannot control the format of the request body. - -Example json request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/channels/rest-example/messages?enveloped=false \ --H 'content-type: application/json' --data '{"some":"json"}' \ --u "{{API_KEY}}" - -Example plain text request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/channels/rest-example/messages?enveloped=false \ --H 'content-type: text/plain' --data 'some plain text' \ --u "{{API_KEY}}" - -h5. Headers and parameters - -- @X-Ably-MessageId@ := Optional message ID, used for "idempotent publishing":#idempotent-publish. Can also be specified as a @messageId@ querystring parameter. Equivalent to @Message.id@ -- @X-Ably-Name@ := Optional message name. Can also be specified as a @name@ querystring parameter. Equivalent to @Message.name@ -- @X-Ably-ConnectionKey@ := Optional connection key, used to publish on behalf of a realtime connection, see "documentation above":#publish. Can also be specified as a @connectionKey@ querystring parameter. Equivalent to @Message.connectionKey@ -- @X-Ably-Encoding@ := Optional message encoding. Allows you to specify the encoding of the message to allow recipient client libraries to decode it. For example, an encoding of @json@ will instruct client libraries to automatically JSON-parse the message on receipt. Also useful if sending an encrypted message, to allow client libraries to decrypt it (assuming they have the correct key). Must be in the correct format per our "client lib development guide":https://sdk.ably.com/builds/ably/specification/main/features/#RSL4 ; if unsure, leave this unspecified. Can also be specified as an @encoding@ querystring parameter. Equivalent to @Message.encoding@ -- @X-Ably-ClientId@ := Optional client ID, base64-encoded (to allow arbitrary unicode). Can also be specified as a @clientId@ querystring parameter (_not_ base64-encoded). Equivalent to @Message.clientId@ - -h5. Options - -- Content-Type := @text/plain@ (for @utf-8@ text request bodies) or @application/octet-stream@ (for binary request bodies). @application/json@ will also work, and is equivalent to specifying a content-type of @text/plain@ together with @X-Ably-Encoding@ of @json@. -- Accept := @application/json@ (the default), @application/x-msgpack@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -When successful, returns an object with @channel@ and @messageId@ properties, in case you want to know the message ID assigned to correlate with messages received by realtime subscribers or integrations recipients. When unsuccessful, returns an error as an "ErrorInfo":/docs/api/rest-sdk/types#error-info object. - -h3(#message-history). Retrieve message history for a channel - -h6. GET main.realtime.ably.net/channels/@@/messages - -If a channel is "configured to persist messages":/docs/storage-history/storage, then all messages on that channel, within "your account retention period":https://faqs.ably.com/how-long-are-messages-stored-for, are available via this API endpoint. If persistence is not configured, then there are no guarantees as to how many historical messages will be available for the channel. "Find out more about message persistence":https://faqs.ably.com/how-long-are-messages-stored-for. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/channels/rest-example/messages \ - -u "{{API_KEY}}" - -h5. Parameters - -- start := _beginning of time_ The start of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or after this time. -- end := _now_ The end of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or before this time. -- limit := _100_ The maximum number of records to return. A limit greater than 1,000 is invalid. -- direction := _backwards_ The direction of this query. The direction determines the order of the returned result array, but also determines which end of the query interval is the start point for the search. For example, a forwards query uses @start@ as the start point, whereas a backwards query uses @end@ as the start point. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -In each case a successful result is a "paginated response":#pagination with an array containing the items that match the query (and it may be empty). - -bc[json]. [{ - id: - name: , - data: , - timestamp: -}] - -h3(#presence). Retrieve instantaneous presence status for a channel - -h6. GET main.realtime.ably.net/channels/@@/presence - -Obtain the set of members currently present for a channel. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/channels/rest-example/presence \ - -u "{{API_KEY}}" - -h5. Parameters - -- clientId := optional filter to restrict members present with that @clientId@ -- connectionId := optional filter to restrict members present with that @connectionId@ -- limit := _100_ The maximum number of records to return. A limit greater than 1,000 is invalid. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -A successful request returns a "paginated response":#pagination with an array containing the members that are currently present on the given channel. If there are no members present, an empty collection is returned. - -bc[json]. [{ - id: , - clientId: , - connectionId: - timestamp: - action: , - data: -}] - -h3(#presence-history). Retrieve presence state history for a channel - -h6. GET main.realtime.ably.net/channels/@@/presence/history - -Obtain the history of presence messages for a channel. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/channels/rest-example/presence/history \ - -u "{{API_KEY}}" - -h5. Parameters - -- start := _beginning of time_ The start of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or after this time. -- end := _now_ The end of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or before this time. -- limit := _100_ The maximum number of records to return. A limit greater than 1,000 is invalid. -- direction := _backwards_ The direction of this query. The direction determines the order of the returned result array, but also determines which end of the query interval is the start point for the search. For example, a forwards query uses @start@ as the start point, whereas a backwards query uses @end@ as the start point. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -A successful request returns a "paginated response":#pagination with an array containing the members that are currently present on the given channel. If there are no members present, an empty collection is returned. - -bc[json]. [{ - id: , - clientId: , - connectionId: - timestamp: - action: , - data: -}] - -h3(#metadata-rest). Retrieve metadata for a channel - -<%= partial partial_version('shared/_channel_metadata') %> - -h3(#enumeration-rest). Enumerate all active channels - -<%= partial partial_version('shared/_channel_enumeration') %> - -h2(#push). Push - -h3(#post-device-registration). Register a device for receiving push notifications - -Before registering a device to receive push notifications, ensure it has a @deviceId@ and a @deviceSecret@. If these are missing, follow these steps to generate them: - -1. Generate the @deviceId@ using a UUID (universally unique identifier) or GUID (globally unique identifier). -2. Generate the @deviceSecret@ using secure random data. The @deviceSecret@ should have sufficient entropy to allow for the creation of a digest using the SHA-256 algorithm. Encode the resultant hash in Base64. - -After generating these, update your local @DeviceDetails@ object with the new @deviceId@ and @deviceSecret@. If you ever lose either, you must generate a new pair. - -The following API endpoint provided is used to register a device for receiving push notifications: - -h6. POST main.realtime.ably.net/push/deviceRegistrations - -The request body contains device and push recipient details, and is an object of the form: - -bc[json]. { - id: , - clientId: , - platform: , - formFactor: , - metadata: , - push: { - recipient: { - transportType: , - - } - } -} - -The recipient address attributes are necessary and vary by underlying transport service. - -For APNs: - -bc[json]. { - deviceToken: -} - -For FCM: - -bc[json]. { - registrationToken: -} - -For web: - -bc[json]. { - targetUrl: , - publicVapidKey: , - encryptionKey: { - p256dh: , - auth: - } -} - -Example request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/push/deviceRegistrations \ - -u "{{API_KEY}}" - -H "Content-Type: application/json" \ - --data \ -'{ - "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV", - "platform": "ios", - "formFactor": "phone", - "push": { - "recipient": { - "transportType": "apns", - "deviceToken": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad" - } - } -}' - -h5. Parameters - -None - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-subscribe@ or @push-admin@ capability; when registering for a client ID with a @push-subscribe@ capability, the token must be associated with that client ID) - -A successful request returns the just-registered device details. It includes an @updateToken@, which is a token that can be used by typically a mobile device to "authenticate":#token-authentication with Ably later and "update an existing device registration":#update-device-registration (for example, for updating a FCM registration token). - -An unsuccessful request returns an error. - -h3(#update-device-registration). Update a device registration - -Device registrations can be either upserted (the existing registration is replaced entirely) with a "@PUT@":#put-device-registration operation, or specific attributes of an existing registration can be updated using a "@PATCH@":#patch-device-registration operation: - -h6(#put-device-registration). PUT main.realtime.ably.net/push/deviceRegistrations/@@ - -The body must have the same shape as when "registering the device":#post-device-registration. The @PUT@ operation will replace the existing device registration, however please bear in mind that a registered device in Ably is largely immutable. As such, only the following attributes are currently updatable and any attempt to modify other fields will result in the update failing: - -* @clientId@ -* @metadata@ -* @push.recipient@ - -Additionally, if the @push.state@ or @updateToken@ attributes are provided, they will be accepted if they match the existing value. However if they differ (and are not @null@ or @omitted@), then the update will fail. - -If you need to make changes to any other fields, you will have to "deregister the existing device":#delete-device-registration and then "register a new one":#post-device-registration. - -Example request: - -bc[sh]. curl -X PUT https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ - -u "{{API_KEY}}" - -H "Content-Type: application/json" \ - --data \ -'{ - "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV", - "platform": "ios", - "formFactor": "phone", - "metadata": { - "timezone": "PST" - }, - "push": { - "recipient": { - "transportType": "apns", - "deviceToken": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad" - } - } -}' - -h5. Parameters - -None - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -A successful request returns the updated device details. - -An unsuccessful request returns an error. - -h6(#patch-device-registration). PATCH main.realtime.ably.net/push/deviceRegistrations/@@ - -The body must have the same shape as when "registering the device":#post-device-registration, except only fields to be changed should be provided. Any fields provided replace existing values. Please bear in mind that fields whose values are structured (JSON-like arrays or objects) types will replace existing values as opposed to be merged into existing values. @metadata@ and @push.recipient@ are examples of these types. Currently only the following attributes are currently updatable and any attempt to modify other fields will result in the update failing: - -* @clientId@ (this field is only editable with a @push-admin@ capability) -* @metadata@ (this field is only editable with a @push-admin@ capability) -* @push.recipient@ - -If you need to make changes to any other fields, you will have to "deregister the existing device":#delete-device-registration and then "register a new one":#post-device-registration. - -Example request: - -bc[sh]. curl -X PATCH https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ - -u "{{API_KEY}}" - -H "Content-Type: application/json" \ - --data \ -'{ - "metadata": { - "myKey": "value" - } - }' - -h5. Parameters - -None - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability, or "token":#token-authentication authentication using the device's update token) - -A successful request returns the updated device details. - -An unsuccessful request returns an error. - -h3(#get-device-registration). Get details from a registered device - -h6. GET main.realtime.ably.net/push/deviceRegistrations/@@ - -Obtain the details for a device registered for receiving push registrations. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ - -u "{{API_KEY}}" - -h5. Parameters - -None. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -h5. Returns - -A JSON object like: - -bc[json]. { - id: , - clientId: - platform: - formFactor: , - metadata: , - updateToken: , - push: { - recipient: { - transportType: , - - }, - state: , - error: { - code: , - statusCode: , - message: - } - } -} - -or a 404 error if a device by that ID does not exist. - -If Ably could not register the device on behalf of the push notifications provider, then @push.error@ contains the relevant error information. - -h3(#list-device-registrations). List registered devices - -h6. GET main.realtime.ably.net/push/deviceRegistrations - -Obtain the details for devices registered for receiving push registrations. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/push/deviceRegistrations \ - -u "{{API_KEY}}" - -h5. Parameters - -- deviceId := optional filter to restrict to devices associated with that @deviceId@ -- clientId := optional filter to restrict to devices associated with that @clientId@ -- limit := _100_ The maximum number of records to return. A limit greater than 1,000 is invalid. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -h5. Returns - -A successful request returns a "paginated response":#pagination of: - -bc[json]. [{ - id: , - clientId: - platform: - formFactor: , - metadata: , - updateToken: , - push: { - recipient: { - transportType: , - - }, - state: - } -}] - -h3(#reset-update-token). Reset a registered device's update token - -h6. POST main.realtime.ably.net/push/deviceRegistrations/@@/resetUpdateToken - -Example request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/push/01ARZ3NDEKTSV4RRFFQ69G5FAV/resetUpdateToken \ - -u "{{API_KEY}}" - -h5. Parameters - -None - -h5. Options - -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability, or "token":#token-authentication authentication using the device's update token) - -A successful request returns the updated device details. - -A unsuccessful request returns an error. - -h3(#delete-device-registration). Unregister a single device for push notifications - -h6. DELETE main.realtime.ably.net/push/deviceRegistrations/@@ - -Unregisters a single device by its device ID. All its subscriptions for receiving push notifications through channels will also be deleted. - -Please note that this operation is done asynchronously so immediate requests subsequent to this delete request may briefly still return the device. - -Example request: - -bc[sh]. curl -X DELETE \ - https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ - -u "{{API_KEY}}" - -h5. Parameters - -None - -h5. Options - -- Content-Type := not applicable -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -h5. Returns - -A successful request returns an empty response. - -An unsuccessful request returns an error. - -h3(#delete-device-registrations). Unregister matching devices for push notifications - -h6. DELETE main.realtime.ably.net/push/deviceRegistrations - -Unregisters devices. All their subscriptions for receiving push notifications through channels will also be deleted. - -Please note that this operation is done asynchronously so immediate requests subsequent to this delete request may briefly still return the device. - -Example request: - -bc[sh]. curl -X DELETE \ - https://main.realtime.ably.net/push/deviceRegistrations?deviceId=01ARZ3NDEKTSV4RRFFQ69G5FAV \ - -u "{{API_KEY}}" - -h5. Parameters - -- deviceId := Filter to restrict to subscriptions for that @deviceId@. Cannot be used with @clientId@. -- clientId := Filter to restrict to subscriptions associated with that @clientId@. Cannot be used with @deviceId@. - -h5. Options - -- Content-Type := not applicable -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -h5. Returns - -A successful request returns an empty response. - -An unsuccessful request returns an error. - -h3(#post-channel-subscription). Subscribe to a channel - -Subscribe either a single device or all devices associated with a client ID to receive push notifications from messages sent to a channel. - -h6. POST main.realtime.ably.net/push/channelSubscriptions - -The request body contains subscription details and is an object of the form: - -bc[json]. { - channel: , - deviceId: , - clientId: -} - -bc[sh]. curl -X POST https://main.realtime.ably.net/push/channelSubscriptions \ - -u "{{API_KEY}}" - -H "Content-Type: application/json" \ - --data \ - ' -{ - "channel": "rest-example", - "deviceId": "01ARZ3NDEKTSV4RRFFQ69G5FAV" -} -' - -h5. Parameters - -None - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-subscribe@ or @push-admin@ capability; when subscribing for a client ID with a @push-subscribe@ capability, the token must be associated with that client ID) - -A successful request returns an empty object. - -A unsuccessful request returns an error. - -h3(#delete-channel-subscription). Unsubscribe from push notifications for channels - -h6. DELETE main.realtime.ably.net/push/channelSubscriptions - -Stop receiving push notifications when push messages are published on the specified channels. - -Please note that this operation is done asynchronously so immediate requests subsequent to this delete request may briefly still return the subscription. - -Example request: - -bc[sh]. curl -X DELETE \ - https://main.realtime.ably.net/push/channelSubscriptions?deviceId=01ARZ3NDEKTSV4RRFFQ69G5FAV \ - -u "{{API_KEY}}" - -h5. Parameters - -- channel := string, optional. If not set, all subscriptions on all channels will be deleted. -- deviceId := Filter to restrict to subscriptions for that @deviceId@. Cannot be used with @clientId@. -- clientId := Filter to restrict to subscriptions associated with that @clientId@. Cannot be used with @deviceId@. - -h5. Options - -- Content-Type := not applicable -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-subscribe@ or @push-admin@capability; when deleting by client ID with a @push-subscribe@ capability, the token must be associated with that client ID) - -h5. Returns - -A successful request returns an empty response. - -An unsuccessful request returns an error. - -h3(#list-channel-subscriptions). List channel subscriptions - -h6. GET main.realtime.ably.net/push/channelSubscriptions - -Get a list of push notification subscriptions to channels. - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/push/channelSubscriptions \ - -u "{{API_KEY}}" - -h5. Parameters - -- channel := Filter to restrict to subscriptions associated with that @channel@. -- clientId := Filter to restrict to subscriptions associated with that @clientId@. Cannot be used with @deviceId@, unless @concatFilters@ is set to @true@. -- deviceId := Filter to restrict to subscriptions for that @deviceId@. Cannot be used with @clientId@, unless @concatFilters@ is set to @true@. -- concatFilters := _false_ Find all device registrations which match either @clientId@ or @deviceId@. Set this to @true@ in order to set both @clientId@ and @deviceId@. -- limit := _100_ The maximum number of records to return. A limit greater than 1,000 is invalid. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -h5. Returns - -A successful request returns a "paginated response":#pagination of: - -bc[json]. [{ - channel: , - clientId: - deviceId: , -}] - -h3(#list-channels). List all channels with at least one subscribed device - -h6. GET main.realtime.ably.net/push/channels - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/push/channels \ - -u "{{API_KEY}}" - -h5. Parameters - -None - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -h5. Returns - -A successful request returns a "paginated response":#pagination of: - -bc[json]. [] - -h3(#push-publish). Publish directly to specific recipients - -Convenience endpoint to deliver a push notification payload to a single device or set of devices identified by their "client identifier":/docs/auth/identified-clients. - -If you want to send a push notification to subscribed clients without knowing about recipient devices' details, we recommend you look at "registering devices for push":#post-device-registration, then "subscribe them to channels":#post-channel-subscription, and then "send messages to the channels with push payloads":#message-extras-push. - -This direct publish endpoint is designed for use cases where there is a need to push directly to specified recipients, for example where the population of relevant devices is managed outside of Ably, or where it is not appropriate to create a durable association between the device and a channel or topic. - -h6. POST main.realtime.ably.net/push/publish - -The request body is an object of the form: - -bc[json]. { - recipient: - <... rest of the fields just like a normal push-enabled message's extras.push object ...> -} - -Example request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/push/publish \ - -u "{{API_KEY}}" \ - -H "Content-Type: application/json" \ - --data \ - ' -{ - "recipient": { - "clientId": "myClientId" - }, - "notification": { - "title": "Hello from Ably!", - "body": "Example push notification from Ably." - }, - "data": { - "foo": "bar", - "baz": "qux" - } -}' - -The @recipient@ field supports delivering either to devices "registered to Ably":#post-device-registration by device ID, by their associated client ID, or directly to devices using the underlying notifications service (FCM, APNs, etc.), thus bypassing registrations to Ably altogether. - -By device ID: - -bc[json]. { - deviceId: -} - -By client ID: - -bc[json]. { - clientId: -} - -For APNs devices: - -bc[json]. { - transportType: "apns", - deviceToken: -} - -For FCM devices: - -bc[json]. { - transportType: , - registrationToken: -} - -For web: - -bc[json]. { - transportType: "web", - targetUrl: , - publicVapidKey: , - encryptionKey: { - p256dh: , - auth: - } -} - -The rest of the fields are "normal push-enabled Ably message's @push.extras@ object":#message-extras-push. - -h5. Parameters - -None - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := not applicable -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication with @push-admin@ capability) - -A successful request returns an empty response. - -An unsuccessful request returns an error. - -h3(#push-publish-batch). Batch publish directly to specific recipients - -Convenience endpoint to deliver multiple push notification payloads to multiple devices or browsers in a single request by specifying a list of recipients and corresponding payloads. -Currently, the batch push endpoint allows a maximum of 10,000 notifications per request. Note that each recipient for a given payload counts as a separate notification. - -h6. POST main.realtime.ably.net/push/batch/publish - -The request body is an array of objects of the form: - -bc[json]. { - recipient: - payload: -} - -Where the recipient and payload fields are the same as those used in the "Publish a push notification to a single device":#push-publish endpoint. - -Example request: - -bc[sh]. curl -X POST https://main.realtime.ably.net/push/admin/batch/publish \ - -u "{{API_KEY}}" \ - -H "Content-Type: application/json" \ - --data \ - ' -[ - { - "recipient": { - "deviceId": "01ARZ3NDEKTSV4RRFFQ69G5FAV" - }, - "payload": { - "notification": { - "title": "Message 1", - "body": "Example push notification from Ably." - } - } - }, - { - "recipient": { - "clientId": "myClientId" - }, - "payload": { - "notification": { - "title": "Message 2", - "body": "Example push notification from Ably." - } - } - } -] -' - - -h2(#authentication). Authentication - -h3(#request-token). Request an access token - - - -h6. POST main.realtime.ably.net/keys/@@/requestToken - -This is the means by which clients obtain access tokens to use the service. The construction of an Ably "@TokenRequest@":/docs/api/token-request-spec is described in the "Authentication Ably TokenRequest spec documentation":/docs/api/token-request-spec. The resulting @token response@ object contains the token properties as defined in "Ably TokenRequest spec":/docs/api/token-request-spec. - -Example request: - -bc[sh]. curl -X POST "https://main.realtime.ably.net/keys/{{API_KEY_NAME}}/requestToken" \ - -u "{{API_KEY}}" \ - -H "Content-Type: application/json" \ - --data '{ "keyName": "{{API_KEY_NAME}}", "timestamp": {{MS_SINCE_EPOCH}} }' - -h5. Parameters - -None - -h5. Options - -- Request body := signed or unsigned Ably "@TokenRequest@":/docs/api/token-request-spec. All Ably "@TokenRequests@":/docs/api/token-request-spec require values for @keyName@ and @timestamp@ attributes. In addition, signed Ably "@TokenRequests@":/docs/api/token-request-spec require values for attributes @nonce@ and @mac@. -- Content-Type := @text/plain@ -- Accept := @application/json@ by default, or @application/x-msgpack@ -- Auth required := no (for signed Ably "@TokenRequests@":/docs/api/token-request-spec), yes (for unsigned Ably "@TokenRequests@":/docs/api/token-request-spec, "basic":#basic-authentication or "token":#token-authentication permitted) - -h5. Returns - -A successful request will return a "token details object":/docs/api/realtime-sdk/types#token-details containing the token string. - -bc[json]. { - "token": "xVLyHw.CLchevH3hF....MDh9ZC_Q", // token string - "keyName": "xVLyHw.mDYnFA", - "issued": 1428356667, - "expires": 1428360267, - "capability": "{\"*\":[\"*\"]}" -} - -h3(#revoke-tokens). Revoke tokens - -h6. POST main.realtime.ably.net/keys/@@/revokeTokens - -Provides a mechanism to revoke tokens, where @keyName@ is @appId.keyId@. - -Example request: - -bc[sh]. curl -u "{{API_KEY}}" -X POST https://main.realtime.ably.net/keys/{{API_KEY_NAME}}/revokeTokens \ - --header "Accept: application/json" \ - --header "Content-Type: application/json" \ - --data '{"targets": [ "clientId:client1@example.com" ]}' - - -h5. Parameters - -None - -h5. Options - -- Request body := A JSON object containing target specifiers identifying tokens to be revoked. -- Content-Type := @application/json@ -- Accept := @application/json@ -- Auth required := yes, basic authentication. - -The request body has the following properties: - -- targets := An array of "target specifier":/docs/auth/revocation#target-specifiers strings. -- issuedBefore := Optional number (Unix timestamp in milliseconds); if not specified it is set to the current time. The token revocation only applies to tokens issued before this timestamp. A request with an @issuedBefore@ in the future, or more than an hour in the past will be rejected. -- allowReauthMargin := The @allowReauthMargin@ bool permits a token renewal cycle to take place without needing established connections to be dropped, by postponing enforcement to 30 seconds in the future, and sending any existing connections a hint to obtain (and upgrade the connection to use) a new token. It defaults to @false@, meaning that the effect is near-immediate. - -h5. Returns - -A successful request returns status 201. An example response body is as follows: - -bc[json]. [ - { - "target": "clientId:foo", - "issuedBefore": 1636022994797, - "appliesAt": 1636022994797 - }, - { - "target": "clientId:bar", - "issuedBefore": 1636022994797, - "appliesAt": 1636022994797 - } -] - -In the response, @appliesAt@ is the time the revocation will take effect. This is the current time by default, or about 30s in the future if you specify @allowReauthMargin@ in the request. - -The response is comparable to that of "Batch publish":#batch. If some tokens can be revoked, and some can't, you receive a batch partial response. - -h5. See also - -See the "token revocation documentation":/docs/auth/revocation for further details. - -h2(#application). Application routes - -Routes providing access to the messaging service within an application scope. - -h3(#stats). Retrieve usage statistics for an application - -h6. GET main.realtime.ably.net/stats - -Example request: - -bc[sh]. curl https://main.realtime.ably.net/stats?unit=hour \ - -u "{{API_KEY}}" - -The Ably system can be queried to obtain usage statistics for a given application, and results are provided aggregated across all channels in use in the application in the specified period. Stats may be used to track usage against account quotas. - -Stats queries are made by specifying a query interval and the granularity expected in the results. The query interval is expressed as a start and end time, each being a timestamp in milliseconds since the epoch. Stats are aggregated by the system in 'sub-minute' intervals of 6s (ie 0.1m), so query interval start and end times are rounded down to the nearest sub-minute boundary. - -h5. Parameters - -- start := _beginning of time_ The start of the query interval as a time in milliseconds since the epoch. -- end := _now_ The end of the query interval as a time in milliseconds since the epoch. -- limit := _100_ The maximum number of records to return. A limit greater than 1,000 is invalid. -- direction := _backwards_ The direction of this query. The direction determines the order of the returned result array, but also determines which end of the query interval is the start point for the search. -- unit := _@minute@_ One of the values @minute@, @hour@, @day@ or @month@, specifying the unit of aggregation in the returned results. - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -In each case a successful result is a "paginated response":#pagination with an array containing the items that match the query (and it may be empty). - -Stats records contain a hierarchy of elements relating to messages, connections and other resources consumed in an interval. Any single record may contain a subset of the elements, omitting empty sections. - -"See a complete example of a statistics response":/docs/metadata-stats/stats#metrics. - -h2(#batch). Batch - -"Batch mode":/docs/messages/batch#batch-publish enables you to submit multiple API requests for certain operations in a single API call. The API processes all the requests in parallel. - -h3(#batch-publish). Batch publish - -h6. POST main.realtime.ably.net/messages - -Using this endpoint, you can publish messages to channels in parallel, by passing either a single @BatchSpec@ object or an array of @BatchSpec@ objects in the request body. - -A single @BatchSpec@ is an object of the form: - -bc[text]. { - channels: , - messages: -} - -* @@ is a single channel name, or an array of up to 100 channel names, expressed as strings. -* @@ is a single message, or an array of up to 1000 messages. - -The maximum size of each request body must be less than 2MiB and the total size of all messages in a @messages@ array must be less than the "message size limit":/docs/platform/pricing/limits#message (64kiB by default for paid accounts, 16kiB for free accounts). - -Sample request, containing multiple @BatchSpec@ objects in an array: - -bc[json]. [ - { - channels: ['channel1', 'channel2'], - messages: {data: 'My message'} - }, - { - channels: 'channel3', - messages: [ - {data: 'My message'}, - {name: 'An event', data: 'My event message contents'}, - ] - } -] - -h5. Parameters - -None - -h5. Options - -- Content-Type := @application/json@, @application/x-msgpack@ or @application/x-www-form-urlencoded@ -- Accept := @application/json@ (the default), @application/x-msgpack@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -*Success*: When the request is successful, the operation returns HTTP status @200@ and an array of objects with @channel@ and @messageId@ properties. For example, the following is returned if the sample request above completes successfully: - -bc[json]. [ - { - "channel": "channel1", - "messageId": "ClDn4dPtUL:0" - }, - { - "channel": "channel2", - "messageId": "3PodoYLYlR:0" - }, - { - "channel": "channel3", - "messageId": "TMefwp6-lP:0" - } -] - -*Failure*: If the batch publish request itself fails, the response includes an "ErrorInfo":/docs/api/rest-sdk/types#error-info object. - -*Partial success*: If the batch request itself succeeds, but one or more of the requests within the batch fails, then the response includes a top-level @error@ property with a status code of @400@ and an error code of @40020@. The @batchResponse@ object for the failed request includes the channel name and an "ErrorInfo":/docs/api/rest-sdk/types#error-info object that describes the error. The successful requests within the batch return a @batchResponse@ object for each channel, together with the @messageId@ of the published message. - -h3(#batch-presence). Batch presence - -h6. GET main.realtime.ably.net/presence - -This endpoint enables you to query the presence states of multiple channels in a single API request. The API retrieves the member presence details of the specified channels in parallel. - -h5. Parameters - -- channels := a list of channel names to retrieve the presence states for. Each name in the list should be separated by commas unless you specify an alternative @separator@
__Type: @string@__ -- separator := _,_ optionally, the character to use as a separator for the list of channel names in the @channels@ parameter
__Type: @string@__ - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := yes ("basic":#basic-authentication or "token":#token-authentication) - -h5. Returns - -*Success*: When successful, the operation returns HTTP status @200@ and an array of objects with @channel@ and @presence@ properties. - -bc[json]. [ - { - "channel":"channel1", - "presence":[ - { - "id":"JSjj6i27T0:0:0", - "clientId":"bob", - "connectionId":"JSjj6i27T0", - "timestamp":1633985256512, - "action":1 - } - ] - }, - { - "channel":"channel2", - "presence":[ - { - "id":"JSjj6i27T0:1:0", - "clientId":"bob", - "connectionId":"JSjj6i27T0", - "timestamp":1633985256517, - "action":1 - } - ] - }, - { - "channel":"channel3", - "presence":[ - { - "id":"JSjj6i27T0:2:0", - "clientId":"bob", - "connectionId":"JSjj6i27T0", - "timestamp":1633985256517, - "action":1 - } - ] - } -] - -Each object in the @presence@ array of each channel describes the presence state of one of that channel's members: - -bc[text]. [{ - id: , - clientId: , - connectionId: - timestamp: - action: , - data: -}] - -*Failure*: If the batch request itself fails the response body contains an "ErrorInfo":/docs/api/rest-sdk/types#error-info object. - -*Partial success*: If the batch request itself succeeds, but one or more of the requests within the batch fails, then the response for the failed request contains an error object with the error code @40020@ and a status code of @400@. Successful requests within the batch include a @presence@ array that describes the presence state of each of the channel members. - - -h2(#utilities). Utilities - -h3(#time). Get the service time - -h6. GET main.realtime.ably.net/time - -This returns the service time in milliseconds since the epoch. This may be used by clients that do not have local access to a sufficiently accurate time source when generating an Ably "@TokenRequest@":/docs/api/token-request-spec. (Ably "@TokenRequests@":/docs/api/token-request-spec include a timestamp and have a limited validity period to help defend against replay attacks.) - -The result is a JSON-encoded array of length 1 containing the time result as a number. - -bc[sh]. curl http://main.realtime.ably.net/time - -h5. Parameters - -None - -h5. Options - -- Content-Type := not applicable -- Accept := @application/json@ by default, or @application/x-msgpack@, @text/html@ -- Auth required := no - -h5. Returns - -bc[json]. [ {{MS_SINCE_EPOCH}} ] diff --git a/src/pages/docs/api/rest-api.mdx b/src/pages/docs/api/rest-api.mdx new file mode 100644 index 0000000000..30e3ba3e1b --- /dev/null +++ b/src/pages/docs/api/rest-api.mdx @@ -0,0 +1,1894 @@ +--- +title: REST API Reference +meta_description: "Ably provides the raw REST API for situations where an Ably client library SDK is not available on the platform of choice, or due to resource constraints." +meta_keywords: "REST API, REST, protocol, resource constraints" +jump_to: + Intro: + - Common API behavior#common + Authentication: + - Authentication + - Basic Authentication + - Token Authentication + Channel API: + - publish + - message history#message-history + - presence + - presence history + Push API: + - register device#post-device-registration + - update a device registration#update-device-registration + - get registered device#get-device-registration + - list registered devices#list-device-registrations + - reset a device's update token#reset-update-token + - unregister device#delete-device-registration + - unregister devices#delete-device-registrations + - subscribe to a channel#post-channel-subscription + - unsubscribe from channels#delete-channel-subscription + - list channel subscriptions#list-channel-subscriptions + - list channels#list-channels + - publish directly to device#push-publish + - publish via batch push API#push-publish-batch + Authentication API: + - requestToken#request-token + - revokeTokens#revoke-tokens + Application API: + - stats + Batch API: + - batch publish#batch-publish + - batch presence#batch-presence + Utilities API: + - time +redirect_from: + - /docs/api/versions/v1.1/rest-api + - /docs/api/versions/v1.0/rest-api + - /docs/api/versions/v0.8/rest-api + - /docs/api/versions/v1.1/beta + - /docs/rest-api + - /docs/rest-api/versions/v1.1 + - /docs/rest-api/versions/v1.0 + - /docs/rest-api/versions/v0.8 + - /docs/rest-api/versions/v1.1/beta +--- + +Welcome to the Ably REST API Reference documentation. + +The Ably REST API provides a way for a wide range of server and client devices to communicate with the Ably service over [REST](https://en.wikipedia.org/wiki/Representational_State_Transfer). The REST API does not provide a realtime long-lived connection to Ably, but in all other respects is a simple subset of the full [realtime messaging API](/docs/api/realtime-sdk). + +The primary use-case for the REST API is for servers that are part of the back-end of an application such as a web application, that publish messages, issue access tokens (temporary and client-specific) for its various clients, obtain message and presence history, and retrieve statistics. + +The functional scope of the REST API includes: + +* [Authentication](#authentication) of the server with Ably, and creation of tokens for use by clients. +* [Publication of messages](#publish) +* [Retrieval of message history](#message-history) +* [Retrieval of presence state and presence](#presence) +* [Retrieval of statistics for application usage](#stats) + +Using the REST API directly is fully supported, Ably recommends that customers should use the Ably REST client libraries SDKs, that support a [range of platforms](https://ably.com/download), including the following examples: + +* [JavaScript](https://ably.com/download) +* [iOS](https://ably.com/download) +* [Android](https://ably.com/download) +* [Java](https://ably.com/download) +* [Python](https://ably.com/download) +* [Ruby](https://ably.com/download) +* [.NET](https://ably.com/download) +* [Go](https://ably.com/download) + +The [Ably client libraries SDKs are documented](https://ably.com/docs), and provide additional features that improve performance and resilience that the REST API cannot deliver on its own, such as automatic re-routing around network problems by using alternative datacenters. + +You can also use the [Rest#request()](/docs/api/rest-sdk#request) method to make arbitrary API calls against Ably, to use endpoints that libraries do not yet have built-in support for. + +## Common API behavior + +### General + +The REST API defaults to returning results, and expects request bodies, in JSON format. An Accept header is used to specify a specific response format - JSON or an alternative - and the following formats are allowed: + +* `application/json`: JSON; +* `application/javascript`: for JSONP. A `callback` query parameter is also expected, which defaults simply to "callback"; +* `application/x-msgpack`: for [MessagePack](https://msgpack.org/), the efficient binary serialization format that is similar to JSON, but faster and smaller; +* `text/html`: HTML + +It is also possible to specify the response format with the `format` query parameter (with supported values being `json`, `jsonp`, `msgpack`, `html`). Any Accept header takes precedence over a `format` parameter. + +Similarly, POST requests may contain a request body in JSON or other formats as indicated by a `Content-Type` header. The supported content types are: + +* `application/json`: JSON; +* `application/x-msgpack`: [MessagePack](https://msgpack.org/), the efficient binary serialization format that is similar to JSON, but faster and smaller; +* `application/x-www-form-urlencoded`: Form-encoded. + +Specific request and response data types are documented in the context of each API or route. + +A response status code of 20X (200, 201 or 204) indicates success. A successful result will typically provide a response body but certain operations (such as DELETE) may respond with a 204 response and no response body. + +All other [standard HTTP statusCodes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) signify an error. Errors from all APIs are returned as an object of the form: + + +```json +{ + error: { + code: , + message: , + statusCode: + } +} +``` + + +Additionally, when you may not have access to the response body due to limitations of your HTTP client, we include the following custom Ably headers to work around that problem: + + +```text +X-Ably-ErrorCode: +X-Ably-ErrorMessage: +``` + + +The properties of an Ably error are: + +| Property | Description | +|----------|-------------| +| `code` | A specific reason code as defined in the [public errors definition](https://github.com/ably/ably-common/blob/main/protocol/errors.json), where one is known | +| `statusCode` | Where a code is not available, the statusCode provides a generic indication of the nature of the failure and maps to [standard HTTP statusCodes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) | +| `message` | The message string is an English language string that aims to provide useful information to the developer. It is not necessarily intended to be an informative string for the end user | + +Wherever possible, success response bodies contain links, in [HATEOS](https://en.wikipedia.org/wiki/HATEOAS) style, to other resources relevant to the response; where these are present these are included as `href` attributes on the applicable part of the response object. + +`GET`, `PUT`, `POST` and `DELETE` are available in all contexts where they make sense. `GET` is always idempotent. + +### Versioning + +By default, all requests receive the latest version of the API, which is currently `1.1`. + +When we make backwards-incompatible API changes to the API, we release new versions. Therefore, we encourage you to explicitly request the version you are interfacing with in all requests using one of the following mechanisms: + +1. Include the `X-Ably-Version` header. Example: + + +```bash +curl https://main.realtime.ably.net/time \ + -H "X-Ably-Version: 1.2" +``` + + +2. Include the version query string param `v`. Example: + + +```bash +curl https://main.realtime.ably.net/time?v=1.2 +``` + + +### Pagination + +By default the response body of a query response will contain the requested resource, encoded in the requested format. However, there are also query params that allow the response body to be adjusted to contain only a subset of the representation, or a restructured representation. + +The following params are supported: + +#### fields + +Specifying `?fields=[,, ...]` returns the representation containing only the specified fields. A field spec is a specifier which is either a single field - in which case the representation contains only that fields's value - or a dot-separated sequence of fields, in which case the representation contains only the fields matching those given in the field spec at each level in the hierarchy. + +##### Example + + +```bash + curl https://main.realtime.ably.net/stats?fields=channels.peak,intervalId \ + -u "{'{{API_KEY}}'}"{""} + + # Response + [{ + "channels": { "peak": 2 }, + "intervalId": "2015-11-20:15" + }] +``` + + +#### flatten + +Specifying `?flatten=true` will result in a flattened representation, with the returned object structure being flattened into one with a single level of long keys instead of a deep structure. When the results contain array elements, the array index of each element is included as the corresponding component of the result key. + +##### Example + + +```bash + curl https://main.realtime.ably.net/stats?flatten=true&fields=channels.peak,intervalId \ + -u "{'{{API_KEY}}'}"{""} + + # Response + { + "0.channels.peak": 2, + "0.intervalId": "2015-11-20:15" + } +``` + + +#### select + +Specifying `?select=` returns a representation of the resource containing only the fields that match the given path specification. Like the fields param this permits only specific fields to be obtained, but the path spec may contain wildcard elements, and all matching fields in the representation are returned. + +The result is a partially-flattened representation, as a map whose keys are the long keys that match the path spec, and the values are the corresponding values. When the results contain array elements, the array index of each element is included as the corresponding component of the result key. + +##### Example + + +```bash + curl https://main.realtime.ably.net/stats?select=*.channels.* \ + -u "{'{{API_KEY}}'}"{""} + + # Response + [{ + "0.channels.peak": 5, + "0.channels.min": 1, + "0.channels.mean": 3, + "0.channels.opened": 2 + }] +``` + + +### Envelope response format + +A client that is unable to access response headers or status code can request an `envelope` response that contains the usual response, plus `Link` header information and the response status code wrapped in an object as a single response body. This is useful for JSONP and may be useful in other environments. Envelope responses are only supported for JSON, JSONP and HTML formats. + +A client requests an envelope response by including an `envelope=` param in the request. + +A JSON envelope response body response for a request with an `envelope=json` param has the format: + + +```json + { + "statusCode": , + "response": , + "rel": { + "first": , + ... + } + } +``` + + +where the `response` member references the API result in the usual format. The `rel` member, present only in paginated responses, includes each of the rel links associated with the response. + +Envelope responses always are always made with a 200 status code; the status of the API request itself must be obtained from the `statusCode` member of the response body. + +## Authentication + +To understand the REST API it is easiest first to understand the various authentication methods that Ably supports. For a detailed explanation, view the [Authentication documentation](/docs/auth). + +Clients can access Ably, whether using REST or the Realtime service, by two methods: + +1. Basic authentication +2. Token authentication + +Each of these is explained in more detail in the following sections. + +### Basic Authentication + +Using one of the application keys created via the [application dashboard](https://ably.com/dashboard), basic authentication provides the simplest method to authenticate with Ably, but has two important limitations: + +* the application key is transmitted over the network as part of a request; therefore it may only be used over TLS (HTTPS or "SSL") connections. This can be a performance disadvantage in some network environments where long round-trip times are amplified by the SSL handshake. +* the client using the API must be in possession of the application key, which potentially exposes the key to compromise. For example, it is not advisable to simply embed the key in a script in a public web page. + +#### Usage in HTTP request header + + +```text +Authorization: Basic +``` + + +where `` is the full application key string obtained through the dashboard, encoded with [RFC 4648 Base64](https://datatracker.ietf.org/doc/html/rfc4648). + +Example request: + + +```bash +curl https://main.realtime.ably.net/channels/rest-example/messages \ + --header "Authorization: Basic {'{{API_KEY_BASE64}}'}" +``` + + +When using a generic HTTP client library that accepts separate username and password arguments for an HTTP request, the application key can be split at the first colon, with the initial segment being used as the username, and the remaining string (without the leading colon) used as the password. + +Example request: + + +```bash +curl https://main.realtime.ably.net/channels/rest-example/messages \ + --user "{'{{API_KEY}}'}"{""} +``` + + +### Token Authentication + +**Token Authentication** uses an Ably-compatible token to authenticate with Ably without sharing a private API key. This can be an [Ably Token](/docs/api/rest-sdk/authentication#tokens) obtained via the REST API [`requestToken`](#request-token) endpoint, an [Ably JWT](/docs/api/rest-sdk/authentication#ably-jwt) signed by your API key, or an [External JWT](https://jwt.io) object [with an embedded Ably-compatible token](/docs/auth/token#embedded). Tokens are authentication credentials that are short-lived, and therefore they may more readily be distributed to clients where there is a risk of compromise. Tokens may also be issued with a particular scope - such as a limited set of [access rights or capabilities](/docs/auth/capabilities) or being limited to use by a specific [`clientId` identity](#identified-clients) - and therefore token-based authentication provides the flexibility to implement access and identity control policies in the application. See the [Token Authentication documentation](/docs/auth/token) for more details. + +The construction of an Ably [`TokenRequest`](/docs/api/token-request-spec) is described in the [Authentication Ably TokenRequest spec documentation](/docs/api/token-request-spec). The resulting `token response` object contains the token properties as defined in [Ably TokenRequest spec](/docs/api/token-request-spec). + +#### Usage in HTTP request header + + +```text +Authorization: Bearer +``` + + +The `` is either the `token` attribute of the Ably Token generated by [`requestToken`](#request-token) encoded with [RFC 4648 Base64](https://datatracker.ietf.org/doc/html/rfc4648), or an [Ably JWT](/docs/api/rest-sdk/authentication#ably-jwt). If using a generic HTTP client library it will probably be necessary to add the `Authorization` header explicitly. + +Example request: + + +```bash +curl https://main.realtime.ably.net/channels/rest-example/messages \ + --header "Authorization: Bearer {'{{TOKEN_BASE64}}'}" +``` + + +## Channel routes + +Routes providing access to the messaging service within a channel scope. + +### Publish one or more messages on a channel + +#### POST main.realtime.ably.net/channels/\{channelId\}/messages + +Publish a message on a channel. Note that since the REST API is stateless, publication using this API is outside the context of any specific connection. + +The request body contains message details and is an object of the form: + + +```json +{ + data: , + name: , + encoding: , + clientId: , + connectionKey: , + id: , + extras: +} +``` + + +In JSON format, the accepted types for the `data` payload are: + +* string +* any JSON-encodable Array or Object. + +MessagePack additionally [supports byte arrays](https://github.com/msgpack/msgpack/blob/master/spec.md#formats-bin) + +A message may be published over REST on behalf of an existing realtime connection when a valid `connectionKey` is present. For example, if you want to publish a message using the REST API so that it appears to come from an existing connected realtime client, then the connection's [private (secret) connection key](/docs/api/realtime-sdk/connection#key) must be included. + +Example request: + + +```bash +curl -X POST https://main.realtime.ably.net/channels/rest-example/messages \ + -u "{'{{API_KEY}}'}"{""} \ + -H "Content-Type: application/json" \ + --data '{ "name": "publish", "data": "example" }' +``` + + +If you're wanting to publish a message **idempotently** (multiple publishes of the same message are not duplicated), you should set the `id` to be unique between each message. Only the first message received by Ably with a specific `id` will then be sent to a channel and its subscribers. + +If you wish to publish a message to multiple channels at once, you should consider using our [batch publish functionality](#batch). + +##### Idempotent publishing + +It is possible for a client publishing through REST to not receive an acknowledgement of receipt from Ably for numerous reasons such as network failures outside of our control. In this scenario, you will likely wish to re-publish the message, but not risk duplicating it within the network. This is possible through the addition of an `id` in the body of your POST, where the `id` should uniquely identify the message. + +##### Message extras + +Messages can include an optional `extras` field, used by extensions to Ably's core realtime service. For example, `extras.ephemeral` can be set to `true` to [make an ephemeral publish](/docs/pub-sub/advanced#ephemeral). + +##### Send push notification + +You can send a push notification to devices [subscribed to a channel](#post-channel-subscription) by setting the `push` field in the `extras` object, like this: + + +```json +{ + <... message fields ...> + extras: { + push: { + data: , + notification: { + title: , + body: , + icon: , + sound: , + collapseKey: + } + apns: , + fcm: , + web: , + } + } +} +``` + + +For each underlying transport service (like APNs, FCM, etc.) an object can be provided with the same shape as the parent object, plus any transport-specific field you may want to add (e. g. `content-available` for APNs). + +Full example of a request publishing a message with a push payload: + + +```bash +curl -X POST https://main.realtime.ably.net/channels/push-enabled:rest-example/messages \ + -u "{'{{API_KEY}}'}"{""} \ + -H "Content-Type: application/json" \ + --data \ + ' +{ + "name": "some event name for realtime receivers", + "data": "example non-push data for realtime receivers", + "extras": { + "push": { + "notification": { + "title": "Hello from Ably!", + "body": "Example push notification from Ably." + }, + "data": { + "foo": "bar", + "baz": "qux" + }, + "apns": { + "notification": { + "content-available": 1, + "sound": "ably-ios.wav" + } + } + } + } +} +' +``` + + +##### Parameters + +| Parameter | Description | +|-----------|-------------| +| `enveloped` | if present and equal to `false`, does an [unenveloped publish](#unenveloped) | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | `application/json` (the default), `application/x-msgpack` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +When successful, returns status code 201 and an object with `channel` and `messageId` properties, in case you want to know the message ID assigned to correlate with messages received by realtime subscribers or Ably Integration recipients. When unsuccessful, returns an error as an [ErrorInfo](/docs/api/rest-sdk/types#error-info) object. + +### Unenveloped publish + +If the `enveloped` parameter is present and set to `false`, the request body is interpreted as the data payload for a message to be published, rather than (as it would normally be) as a `Message` object or array of `Message` objects. This can be useful if, for example, you want an Ably publish to be triggered by a webhook from some third-party service where you cannot control the format of the request body. + +Example json request: + + +```bash +curl -X POST https://main.realtime.ably.net/channels/rest-example/messages?enveloped=false \ +-H 'content-type: application/json' --data '{"some":"json"}' \ +-u "{'{{API_KEY}}'}"{""} +``` + + +Example plain text request: + + +```bash +curl -X POST https://main.realtime.ably.net/channels/rest-example/messages?enveloped=false \ +-H 'content-type: text/plain' --data 'some plain text' \ +-u "{'{{API_KEY}}'}"{""} +``` + + +##### Headers and parameters + +| Parameter | Description | Type | +|-----------|-------------|------| +| `X-Ably-MessageId` | Optional message ID, used for [idempotent publishing](#idempotent-publish). Can also be specified as a `messageId` querystring parameter. Equivalent to `Message.id` | string | +| `X-Ably-Name` | Optional message name. Can also be specified as a `name` querystring parameter. Equivalent to `Message.name` | string | +| `X-Ably-ConnectionKey` | Optional connection key, used to publish on behalf of a realtime connection, see [documentation above](#publish). Can also be specified as a `connectionKey` querystring parameter. Equivalent to `Message.connectionKey` | string | +| `X-Ably-Encoding` | Optional message encoding. Allows you to specify the encoding of the message to allow recipient client libraries to decode it. For example, an encoding of `json` will instruct client libraries to automatically JSON-parse the message on receipt. Also useful if sending an encrypted message, to allow client libraries to decrypt it (assuming they have the correct key). Must be in the correct format per our [client lib development guide](https://sdk.ably.com/builds/ably/specification/main/features/#RSL4) ; if unsure, leave this unspecified. Can also be specified as an `encoding` querystring parameter. Equivalent to `Message.encoding` | string | +| `X-Ably-ClientId` | Optional client ID, base64-encoded (to allow arbitrary unicode). Can also be specified as a `clientId` querystring parameter (_not_ base64-encoded). Equivalent to `Message.clientId` | string | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `text/plain` (for `utf-8` text request bodies) or `application/octet-stream` (for binary request bodies). `application/json` will also work, and is equivalent to specifying a content-type of `text/plain` together with `X-Ably-Encoding` of `json`. | +| Accept | `application/json` (the default), `application/x-msgpack` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +When successful, returns an object with `channel` and `messageId` properties, in case you want to know the message ID assigned to correlate with messages received by realtime subscribers or integrations recipients. When unsuccessful, returns an error as an [ErrorInfo](/docs/api/rest-sdk/types#error-info) object. + +### Retrieve message history for a channel + +#### GET main.realtime.ably.net/channels/\{channelId\}/messages + +If a channel is [configured to persist messages](/docs/storage-history/storage), then all messages on that channel, within [your account retention period](https://faqs.ably.com/how-long-are-messages-stored-for), are available via this API endpoint. If persistence is not configured, then there are no guarantees as to how many historical messages will be available for the channel. [Find out more about message persistence](https://faqs.ably.com/how-long-are-messages-stored-for). + +Example request: + + +```bash +curl https://main.realtime.ably.net/channels/rest-example/messages \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `start` | _beginning of time_ | The start of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or after this time. | +| `end` | _now_ | The end of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or before this time. | +| `limit` | _100_ | The maximum number of records to return. A limit greater than 1,000 is invalid. | +| `direction` | _backwards_ | The direction of this query. The direction determines the order of the returned result array, but also determines which end of the query interval is the start point for the search. For example, a forwards query uses `start` as the start point, whereas a backwards query uses `end` as the start point. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +In each case a successful result is a [paginated response](#pagination) with an array containing the items that match the query (and it may be empty). + + +```json +[{ + id: + name: , + data: , + timestamp: +}] +``` + + +### Retrieve instantaneous presence status for a channel + +#### GET main.realtime.ably.net/channels/\{channelId\}/presence + +Obtain the set of members currently present for a channel. + +Example request: + + +```bash +curl https://main.realtime.ably.net/channels/rest-example/presence \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `clientId` | | optional filter to restrict members present with that `clientId` | +| `connectionId` | | optional filter to restrict members present with that `connectionId` | +| `limit` | _100_ | The maximum number of records to return. A limit greater than 1,000 is invalid. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +A successful request returns a [paginated response](#pagination) with an array containing the members that are currently present on the given channel. If there are no members present, an empty collection is returned. + + +```json +[{ + id: , + clientId: , + connectionId: + timestamp: + action: , + data: +}] +``` + + +### Retrieve presence state history for a channel + +#### GET main.realtime.ably.net/channels/\{channelId\}/presence/history + +Obtain the history of presence messages for a channel. + +Example request: + + +```bash +curl https://main.realtime.ably.net/channels/rest-example/presence/history \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `start` | _beginning of time_ | The start of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or after this time. | +| `end` | _now_ | The end of the query interval as a time in milliseconds since the epoch. A message qualifies as a member of the result set if it was received at or before this time. | +| `limit` | _100_ | The maximum number of records to return. A limit greater than 1,000 is invalid. | +| `direction` | _backwards_ | The direction of this query. The direction determines the order of the returned result array, but also determines which end of the query interval is the start point for the search. For example, a forwards query uses `start` as the start point, whereas a backwards query uses `end` as the start point. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +A successful request returns a [paginated response](#pagination) with an array containing the members that are currently present on the given channel. If there are no members present, an empty collection is returned. + + +```json +[{ + id: , + clientId: , + connectionId: + timestamp: + action: , + data: +}] +``` + + +### Retrieve metadata for a channel + +This returns a [ChannelDetails](/docs/api/realtime-sdk/channel-metadata#channel-details) for the given channel, indicating global [occupancy](/docs/api/rest-sdk/channel-status#occupancy). A side-effect of this request, in the current version of this API, is that it will cause the channel in question to become activated; therefore it is primarily intended to be used in conjunction with the [enumeration API](#enumeration-rest) or in situations where the application has another means to know whether or not a given channel is active. + +Example request: + + +curl https://main.realtime.ably.net/channels/\{channelId\} \ + -u "{'{{API_KEY}}'}"{""} + + +The credentials presented with the request must include the `channel-metadata` permission for the channel in question. + +Client libraries currently do not support this API, but it is usable via the generic [request API](/docs/api/rest-sdk#request). + +### Enumerate all active channels + +This enumerates all active channels in the application. This is a paginated API following the same API conventions as other paginated APIs in the [REST interface](/docs/api/rest-sdk). + +This API is intended for occasional use by your servers only; for example, to get an initial set of active channels to be kept up to date using the [channel lifecycle metachannel](/docs/metadata-stats/metadata/subscribe). It is heavily rate-limited: only a single in-flight channel enumeration call is permitted to execute at any one time. Further concurrent calls will be refused with an error with code `42912`. + +Example request: + + +curl https://main.realtime.ably.net/channels \ + -u "{'{{API_KEY}}'}" + + +This will return either a list of channel names, or a [ChannelDetails](/docs/api/realtime-sdk/channel-metadata#channel-details) object depending on what options you've specified. + +The following parameters are supported: + +| Parameter | Description | +|-----------|-------------| +| `limit` | _100_ optionally specifies the maximum number of results to return. A limit greater than 1000 is unsupported
**Type: `integer`** | +| `prefix` | optionally limits the query to only those channels whose name starts with the given prefix
**Type: `string`** | +| `by` | _id (≥ v3) or value (≤ v2)_ optionally specifies what to return. Use `by=id` to return only channel names or `by=value` to return [`ChannelDetails`](/docs/api/realtime-sdk/channel-metadata#channel-details). Using `by=id` will be much faster, and making very regular `by=value` enumeration queries can prevent channels from closing down from inactivity. | + +The credentials presented with the request must include the `channel-metadata` permission for the wildcard resource `'*'`. + +Client libraries do not provide a dedicated API to enumerate channels, but make this available using the [request](/docs/api/rest-sdk#request) method. When using this, you can simply iterate through the [PaginatedResults](/docs/api/rest-sdk/types#paginated-result) to enumerate through the results. + +`Enumeration` is possible of all channels in an app, by repeated calls to the API, following the `next` relative link on each successive call, until there is no `next` relative link. However, this is subject to several limitations: + +* Channels that become active, or become inactive, between the first and last request in the sequence, might or might not appear in the result. The API guarantees that if a channel is continuously active from the time that the first request is made until the time that the last request completes, then it is guaranteed to be present in the result. Similarly, if a channel is continuously inactive between those times then it is guaranteed not to be present in the result; +* Since the state of the cluster may change between successive calls, a pagination sequence may become invalid, in which case the request will respond with an error with code `40011`. In this case, to get a complete result, it is necessary to start the enumeration again from the beginning. Other API options to deal with this possibility maybe provided in later versions of this API. Enumerations that are satisfiable in the first response page do not have this issue. +* The API does not guarantee that the limit will be achieved even if that would be possible. For example, if you specify a limit of 100, the API may return only 37 results together with a `next` link to get the next page, even if you have more than 37 channels. In the extreme case, the API may return 0 results with a next link. In particular this may be the case if you have a large number of active channels but are specifying a `prefix` that excludes a significant proportion of them. +* The API does not guarantee that there will be no duplicated results between different pages, especially if a channel is alive in multiple regions. (It does not _currently_ do so, but it may begin to do so with no warning or deprecation period, so your implementation should be able to cope with duplication) +* If you use `by=value` (which until protocol v3 was the default), just enumerating channels can briefly keep them alive, meaning if you do very regular enumeration you can get a situation where channels never close. + +## Push
+ +### Register a device for receiving push notifications + +Before registering a device to receive push notifications, ensure it has a `deviceId` and a `deviceSecret`. If these are missing, follow these steps to generate them: + +1. Generate the `deviceId` using a UUID (universally unique identifier) or GUID (globally unique identifier). +2. Generate the `deviceSecret` using secure random data. The `deviceSecret` should have sufficient entropy to allow for the creation of a digest using the SHA-256 algorithm. Encode the resultant hash in Base64. + +After generating these, update your local `DeviceDetails` object with the new `deviceId` and `deviceSecret`. If you ever lose either, you must generate a new pair. + +The following API endpoint provided is used to register a device for receiving push notifications: + +#### POST main.realtime.ably.net/push/deviceRegistrations + +The request body contains device and push recipient details, and is an object of the form: + + +```json +{ + id: , + clientId: , + platform: , + formFactor: , + metadata: , + push: { + recipient: { + transportType: , + + } + } +} +``` + + +The recipient address attributes are necessary and vary by underlying transport service. + +For APNs: + + +```json +{ + deviceToken: +} +``` + + +For FCM: + + +```json +{ + registrationToken: +} +``` + + +For web: + + +```json +{ + targetUrl: , + publicVapidKey: , + encryptionKey: { + p256dh: , + auth: + } +} +``` + + +Example request: + + +```bash +curl -X POST https://main.realtime.ably.net/push/deviceRegistrations \ + -u "{'{{API_KEY}}'}"{""} + -H "Content-Type: application/json" \ + --data \ +'{ + "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV", + "platform": "ios", + "formFactor": "phone", + "push": { + "recipient": { + "transportType": "apns", + "deviceToken": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad" + } + } +}' +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-subscribe` or `push-admin` capability; when registering for a client ID with a `push-subscribe` capability, the token must be associated with that client ID) | + +A successful request returns the just-registered device details. It includes an `updateToken`, which is a token that can be used by typically a mobile device to [authenticate](#token-authentication) with Ably later and [update an existing device registration](#update-device-registration) (for example, for updating a FCM registration token). + +An unsuccessful request returns an error. + +### Update a device registration + +Device registrations can be either upserted (the existing registration is replaced entirely) with a [`PUT`](#put-device-registration) operation, or specific attributes of an existing registration can be updated using a [`PATCH`](#patch-device-registration) operation: + +#### PUT main.realtime.ably.net/push/deviceRegistrations/\{deviceId\} + +The body must have the same shape as when [registering the device](#post-device-registration). The `PUT` operation will replace the existing device registration, however please bear in mind that a registered device in Ably is largely immutable. As such, only the following attributes are currently updatable and any attempt to modify other fields will result in the update failing: + +* `clientId` +* `metadata` +* `push.recipient` + +Additionally, if the `push.state` or `updateToken` attributes are provided, they will be accepted if they match the existing value. However if they differ (and are not `null` or `omitted`), then the update will fail. + +If you need to make changes to any other fields, you will have to [deregister the existing device](#delete-device-registration) and then [register a new one](#post-device-registration). + +Example request: + + +```bash +curl -X PUT https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ + -u "{'{{API_KEY}}'}"{""} + -H "Content-Type: application/json" \ + --data \ +'{ + "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV", + "platform": "ios", + "formFactor": "phone", + "metadata": { + "timezone": "PST" + }, + "push": { + "recipient": { + "transportType": "apns", + "deviceToken": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad" + } + } +}' +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +A successful request returns the updated device details. + +An unsuccessful request returns an error. + +#### PATCH main.realtime.ably.net/push/deviceRegistrations/\{deviceId\} + +The body must have the same shape as when [registering the device](#post-device-registration), except only fields to be changed should be provided. Any fields provided replace existing values. Please bear in mind that fields whose values are structured (JSON-like arrays or objects) types will replace existing values as opposed to be merged into existing values. `metadata` and `push.recipient` are examples of these types. Currently only the following attributes are currently updatable and any attempt to modify other fields will result in the update failing: + +* `clientId` (this field is only editable with a `push-admin` capability) +* `metadata` (this field is only editable with a `push-admin` capability) +* `push.recipient` + +If you need to make changes to any other fields, you will have to [deregister the existing device](#delete-device-registration) and then [register a new one](#post-device-registration). + +Example request: + + +```bash +curl -X PATCH https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ + -u "{'{{API_KEY}}'}"{""} + -H "Content-Type: application/json" \ + --data \ +'{ + "metadata": { + "myKey": "value" + } + }' +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability, or [token](#token-authentication) authentication using the device's update token) | + +A successful request returns the updated device details. + +An unsuccessful request returns an error. + +### Get details from a registered device + +#### GET main.realtime.ably.net/push/deviceRegistrations/\{deviceId\} + +Obtain the details for a device registered for receiving push registrations. + +Example request: + + +```bash +curl https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +None. + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +##### Returns + +A JSON object like: + + +```json +{ + id: , + clientId: + platform: + formFactor: , + metadata: , + updateToken: , + push: { + recipient: { + transportType: , + + }, + state: , + error: { + code: , + statusCode: , + message: + } + } +} +``` + + +or a 404 error if a device by that ID does not exist. + +If Ably could not register the device on behalf of the push notifications provider, then `push.error` contains the relevant error information. + +### List registered devices + +#### GET main.realtime.ably.net/push/deviceRegistrations + +Obtain the details for devices registered for receiving push registrations. + +Example request: + + +```bash +curl https://main.realtime.ably.net/push/deviceRegistrations \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `deviceId` | | optional filter to restrict to devices associated with that `deviceId` | +| `clientId` | | optional filter to restrict to devices associated with that `clientId` | +| `limit` | _100_ | The maximum number of records to return. A limit greater than 1,000 is invalid. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +##### Returns + +A successful request returns a [paginated response](#pagination) of: + + +```json +[{ + id: , + clientId: + platform: + formFactor: , + metadata: , + updateToken: , + push: { + recipient: { + transportType: , + + }, + state: + } +}] +``` + + +### Reset a registered device's update token + +#### POST main.realtime.ably.net/push/deviceRegistrations/\{deviceId\}/resetUpdateToken + +Example request: + + +```bash +curl -X POST https://main.realtime.ably.net/push/01ARZ3NDEKTSV4RRFFQ69G5FAV/resetUpdateToken \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability, or [token](#token-authentication) authentication using the device's update token) | + +A successful request returns the updated device details. + +A unsuccessful request returns an error. + +### Unregister a single device for push notifications + +#### DELETE main.realtime.ably.net/push/deviceRegistrations/\{deviceId\} + +Unregisters a single device by its device ID. All its subscriptions for receiving push notifications through channels will also be deleted. + +Please note that this operation is done asynchronously so immediate requests subsequent to this delete request may briefly still return the device. + +Example request: + + +```bash +curl -X DELETE \ + https://main.realtime.ably.net/push/deviceRegistrations/01ARZ3NDEKTSV4RRFFQ69G5FAV \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +##### Returns + +A successful request returns an empty response. + +An unsuccessful request returns an error. + +### Unregister matching devices for push notifications + +#### DELETE main.realtime.ably.net/push/deviceRegistrations + +Unregisters devices. All their subscriptions for receiving push notifications through channels will also be deleted. + +Please note that this operation is done asynchronously so immediate requests subsequent to this delete request may briefly still return the device. + +Example request: + + +```bash +curl -X DELETE \ + https://main.realtime.ably.net/push/deviceRegistrations?deviceId=01ARZ3NDEKTSV4RRFFQ69G5FAV \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Description | +|-----------|-------------| +| `deviceId` | Filter to restrict to subscriptions for that `deviceId`. Cannot be used with `clientId`. | +| `clientId` | Filter to restrict to subscriptions associated with that `clientId`. Cannot be used with `deviceId`. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +##### Returns + +A successful request returns an empty response. + +An unsuccessful request returns an error. + +### Subscribe to a channel + +Subscribe either a single device or all devices associated with a client ID to receive push notifications from messages sent to a channel. + +#### POST main.realtime.ably.net/push/channelSubscriptions + +The request body contains subscription details and is an object of the form: + + +```json +{ + channel: , + deviceId: , + clientId: +} +``` + + + +```bash +curl -X POST https://main.realtime.ably.net/push/channelSubscriptions \ + -u "{'{{API_KEY}}'}"{""} + -H "Content-Type: application/json" \ + --data \ + ' +{ + "channel": "rest-example", + "deviceId": "01ARZ3NDEKTSV4RRFFQ69G5FAV" +} +' +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-subscribe` or `push-admin` capability; when subscribing for a client ID with a `push-subscribe` capability, the token must be associated with that client ID) | + +A successful request returns an empty object. + +A unsuccessful request returns an error. + +### Unsubscribe from push notifications for channels + +#### DELETE main.realtime.ably.net/push/channelSubscriptions + +Stop receiving push notifications when push messages are published on the specified channels. + +Please note that this operation is done asynchronously so immediate requests subsequent to this delete request may briefly still return the subscription. + +Example request: + + +```bash +curl -X DELETE \ + https://main.realtime.ably.net/push/channelSubscriptions?deviceId=01ARZ3NDEKTSV4RRFFQ69G5FAV \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Description | +|-----------|-------------| +| `channel` | string, optional. If not set, all subscriptions on all channels will be deleted. | +| `deviceId` | Filter to restrict to subscriptions for that `deviceId`. Cannot be used with `clientId`. | +| `clientId` | Filter to restrict to subscriptions associated with that `clientId`. Cannot be used with `deviceId`. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-subscribe` or `push-admin`capability; when deleting by client ID with a `push-subscribe` capability, the token must be associated with that client ID) | + +##### Returns + +A successful request returns an empty response. + +An unsuccessful request returns an error. + +### List channel subscriptions + +#### GET main.realtime.ably.net/push/channelSubscriptions + +Get a list of push notification subscriptions to channels. + +Example request: + + +```bash +curl https://main.realtime.ably.net/push/channelSubscriptions \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `channel` | | Filter to restrict to subscriptions associated with that `channel`. | +| `clientId` | | Filter to restrict to subscriptions associated with that `clientId`. Cannot be used with `deviceId`, unless `concatFilters` is set to `true`. | +| `deviceId` | | Filter to restrict to subscriptions for that `deviceId`. Cannot be used with `clientId`, unless `concatFilters` is set to `true`. | +| `concatFilters` | _false_ | Find all device registrations which match either `clientId` or `deviceId`. Set this to `true` in order to set both `clientId` and `deviceId`. | +| `limit` | _100_ | The maximum number of records to return. A limit greater than 1,000 is invalid. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +##### Returns + +A successful request returns a [paginated response](#pagination) of: + + +```json +[{ + channel: , + clientId: + deviceId: , +}] +``` + + +### List all channels with at least one subscribed device + +#### GET main.realtime.ably.net/push/channels + +Example request: + + +```bash +curl https://main.realtime.ably.net/push/channels \ + -u "{'{{API_KEY}}'}"{""} +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +##### Returns + +A successful request returns a [paginated response](#pagination) of: + + +```json +[] +``` + + +### Publish directly to specific recipients + +Convenience endpoint to deliver a push notification payload to a single device or set of devices identified by their [client identifier](/docs/auth/identified-clients). + +If you want to send a push notification to subscribed clients without knowing about recipient devices' details, we recommend you look at [registering devices for push](#post-device-registration), then [subscribe them to channels](#post-channel-subscription), and then [send messages to the channels with push payloads](#message-extras-push). + +This direct publish endpoint is designed for use cases where there is a need to push directly to specified recipients, for example where the population of relevant devices is managed outside of Ably, or where it is not appropriate to create a durable association between the device and a channel or topic. + +#### POST main.realtime.ably.net/push/publish + +The request body is an object of the form: + + +```json +{ + recipient: + <... rest of the fields just like a normal push-enabled message's extras.push object ...> +} +``` + + +Example request: + + +```bash +curl -X POST https://main.realtime.ably.net/push/publish \ + -u "{'{{API_KEY}}'}"{""} \ + -H "Content-Type: application/json" \ + --data \ + ' +{ + "recipient": { + "clientId": "myClientId" + }, + "notification": { + "title": "Hello from Ably!", + "body": "Example push notification from Ably." + }, + "data": { + "foo": "bar", + "baz": "qux" + } +}' +``` + + +The `recipient` field supports delivering either to devices [registered to Ably](#post-device-registration) by device ID, by their associated client ID, or directly to devices using the underlying notifications service (FCM, APNs, etc.), thus bypassing registrations to Ably altogether. + +By device ID: + + +```json +{ + deviceId: +} +``` + + +By client ID: + + +```json +{ + clientId: +} +``` + + +For APNs devices: + + +```json +{ + transportType: "apns", + deviceToken: +} +``` + + +For FCM devices: + + +```json +{ + transportType: , + registrationToken: +} +``` + + +For web: + + +```json +{ + transportType: "web", + targetUrl: , + publicVapidKey: , + encryptionKey: { + p256dh: , + auth: + } +} +``` + + +The rest of the fields are [normal push-enabled Ably message's `push.extras` object](#message-extras-push). + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | not applicable | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication) with `push-admin` capability) | + +A successful request returns an empty response. + +An unsuccessful request returns an error. + +### Batch publish directly to specific recipients + +Convenience endpoint to deliver multiple push notification payloads to multiple devices or browsers in a single request by specifying a list of recipients and corresponding payloads. +Currently, the batch push endpoint allows a maximum of 10,000 notifications per request. Note that each recipient for a given payload counts as a separate notification. + +#### POST main.realtime.ably.net/push/batch/publish + +The request body is an array of objects of the form: + + +```json +{ + recipient: + payload: +} +``` + + +Where the recipient and payload fields are the same as those used in the [Publish a push notification to a single device](#push-publish) endpoint. + +Example request: + + +```bash +curl -X POST https://main.realtime.ably.net/push/admin/batch/publish \ + -u "{'{{API_KEY}}'}"{""} \ + -H "Content-Type: application/json" \ + --data \ + ' +[ + { + "recipient": { + "deviceId": "01ARZ3NDEKTSV4RRFFQ69G5FAV" + }, + "payload": { + "notification": { + "title": "Message 1", + "body": "Example push notification from Ably." + } + } + }, + { + "recipient": { + "clientId": "myClientId" + }, + "payload": { + "notification": { + "title": "Message 2", + "body": "Example push notification from Ably." + } + } + } +] +' +``` + + + +## Authentication + +### Request an access token + +{/* TODO: Review the suitability of the documentation that describes the token request and the token body response and provide suitable links */} + +#### POST main.realtime.ably.net/keys/\{keyName\}/requestToken + +This is the means by which clients obtain access tokens to use the service. The construction of an Ably [`TokenRequest`](/docs/api/token-request-spec) is described in the [Authentication Ably TokenRequest spec documentation](/docs/api/token-request-spec). The resulting `token response` object contains the token properties as defined in [Ably TokenRequest spec](/docs/api/token-request-spec). + +Example request: + + +```bash +curl -X POST "https://main.realtime.ably.net/keys/{'{{API_KEY_NAME}}'}/requestToken" \ + -u "{'{{API_KEY}}'}"{""} \ + -H "Content-Type: application/json" \ + --data '{ "keyName": "{'{{API_KEY_NAME}}'}", "timestamp": {'{{MS_SINCE_EPOCH}}'} }' +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Request body | signed or unsigned Ably [`TokenRequest`](/docs/api/token-request-spec). All Ably [`TokenRequests`](/docs/api/token-request-spec) require values for `keyName` and `timestamp` attributes. In addition, signed Ably [`TokenRequests`](/docs/api/token-request-spec) require values for attributes `nonce` and `mac`. | +| Content-Type | `text/plain` | +| Accept | `application/json` by default, or `application/x-msgpack` | +| Auth required | no (for signed Ably [`TokenRequests`](/docs/api/token-request-spec)), yes (for unsigned Ably [`TokenRequests`](/docs/api/token-request-spec), [basic](#basic-authentication) or [token](#token-authentication) permitted) | + +##### Returns + +A successful request will return a [token details object](/docs/api/realtime-sdk/types#token-details) containing the token string. + + +```json +{ + "token": "xVLyHw.CLchevH3hF....MDh9ZC_Q", // token string + "keyName": "xVLyHw.mDYnFA", + "issued": 1428356667, + "expires": 1428360267, + "capability": "{\"*\":[\"*\"]}" +} +``` + + +### Revoke tokens + +#### POST main.realtime.ably.net/keys/\{keyName\}/revokeTokens + +Provides a mechanism to revoke tokens, where `keyName` is `appId.keyId`. + +Example request: + + +```bash +curl -u "{'{{API_KEY}}'}"{""} -X POST https://main.realtime.ably.net/keys/{'{{API_KEY_NAME}}'}/revokeTokens \ + --header "Accept: application/json" \ + --header "Content-Type: application/json" \ + --data '{"targets": [ "clientId:client1@example.com" ]}' +``` + + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Request body | A JSON object containing target specifiers identifying tokens to be revoked. | +| Content-Type | `application/json` | +| Accept | `application/json` | +| Auth required | yes, basic authentication. | + +The request body has the following properties: + +| Property | Description | +|----------|-------------| +| targets | An array of [target specifier](/docs/auth/revocation#target-specifiers) strings. | +| issuedBefore | Optional number (Unix timestamp in milliseconds); if not specified it is set to the current time. The token revocation only applies to tokens issued before this timestamp. A request with an `issuedBefore` in the future, or more than an hour in the past will be rejected. | +| allowReauthMargin | The `allowReauthMargin` bool permits a token renewal cycle to take place without needing established connections to be dropped, by postponing enforcement to 30 seconds in the future, and sending any existing connections a hint to obtain (and upgrade the connection to use) a new token. It defaults to `false`, meaning that the effect is near-immediate. | + +##### Returns + +A successful request returns status 201. An example response body is as follows: + + +```json +[ + { + "target": "clientId:foo", + "issuedBefore": 1636022994797, + "appliesAt": 1636022994797 + }, + { + "target": "clientId:bar", + "issuedBefore": 1636022994797, + "appliesAt": 1636022994797 + } +] +``` + + +In the response, `appliesAt` is the time the revocation will take effect. This is the current time by default, or about 30s in the future if you specify `allowReauthMargin` in the request. + +The response is comparable to that of [Batch publish](#batch). If some tokens can be revoked, and some can't, you receive a batch partial response. + +##### See also + +See the [token revocation documentation](/docs/auth/revocation) for further details. + +## Application routes + +Routes providing access to the messaging service within an application scope. + +### Retrieve usage statistics for an application + +#### GET main.realtime.ably.net/stats + +Example request: + + +```bash +curl https://main.realtime.ably.net/stats?unit=hour \ + -u "{'{{API_KEY}}'}"{""} +``` + + +The Ably system can be queried to obtain usage statistics for a given application, and results are provided aggregated across all channels in use in the application in the specified period. Stats may be used to track usage against account quotas. + +Stats queries are made by specifying a query interval and the granularity expected in the results. The query interval is expressed as a start and end time, each being a timestamp in milliseconds since the epoch. Stats are aggregated by the system in 'sub-minute' intervals of 6s (ie 0.1m), so query interval start and end times are rounded down to the nearest sub-minute boundary. + +##### Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| start | _beginning of time_ | The start of the query interval as a time in milliseconds since the epoch. | +| end | _now_ | The end of the query interval as a time in milliseconds since the epoch. | +| limit | _100_ | The maximum number of records to return. A limit greater than 1,000 is invalid. | +| direction | _backwards_ | The direction of this query. The direction determines the order of the returned result array, but also determines which end of the query interval is the start point for the search. | +| unit | _`minute`_ | One of the values `minute`, `hour`, `day` or `month`, specifying the unit of aggregation in the returned results. | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +In each case a successful result is a [paginated response](#pagination) with an array containing the items that match the query (and it may be empty). + +Stats records contain a hierarchy of elements relating to messages, connections and other resources consumed in an interval. Any single record may contain a subset of the elements, omitting empty sections. + +[See a complete example of a statistics response](/docs/metadata-stats/stats#metrics). + +## Batch + +[Batch mode](/docs/messages/batch#batch-publish) enables you to submit multiple API requests for certain operations in a single API call. The API processes all the requests in parallel. + +### Batch publish + +#### POST main.realtime.ably.net/messages + +Using this endpoint, you can publish messages to channels in parallel, by passing either a single `BatchSpec` object or an array of `BatchSpec` objects in the request body. + +A single `BatchSpec` is an object of the form: + + +```text +{ + channels: , + messages: +} +``` + + +* `` is a single channel name, or an array of up to 100 channel names, expressed as strings. +* `` is a single message, or an array of up to 1000 messages. + +The maximum size of each request body must be less than 2MiB and the total size of all messages in a `messages` array must be less than the [message size limit](/docs/platform/pricing/limits#message) (64kiB by default for paid accounts, 16kiB for free accounts). + +Sample request, containing multiple `BatchSpec` objects in an array: + + +```json +[ + { + channels: ['channel1', 'channel2'], + messages: {data: 'My message'} + }, + { + channels: 'channel3', + messages: [ + {data: 'My message'}, + {name: 'An event', data: 'My event message contents'}, + ] + } +] +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | `application/json`, `application/x-msgpack` or `application/x-www-form-urlencoded` | +| Accept | `application/json` (the default), `application/x-msgpack` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +**Success**: When the request is successful, the operation returns HTTP status `200` and an array of objects with `channel` and `messageId` properties. For example, the following is returned if the sample request above completes successfully: + + +```json +[ + { + "channel": "channel1", + "messageId": "ClDn4dPtUL:0" + }, + { + "channel": "channel2", + "messageId": "3PodoYLYlR:0" + }, + { + "channel": "channel3", + "messageId": "TMefwp6-lP:0" + } +] +``` + + +**Failure**: If the batch publish request itself fails, the response includes an [ErrorInfo](/docs/api/rest-sdk/types#error-info) object. + +**Partial success**: If the batch request itself succeeds, but one or more of the requests within the batch fails, then the response includes a top-level `error` property with a status code of `400` and an error code of `40020`. The `batchResponse` object for the failed request includes the channel name and an [ErrorInfo](/docs/api/rest-sdk/types#error-info) object that describes the error. The successful requests within the batch return a `batchResponse` object for each channel, together with the `messageId` of the published message. + +### Batch presence + +#### GET main.realtime.ably.net/presence + +This endpoint enables you to query the presence states of multiple channels in a single API request. The API retrieves the member presence details of the specified channels in parallel. + +##### Parameters + +| Parameter | Default | Type | Description | +|-----------|---------|------|-------------| +| channels | - | `string` | a list of channel names to retrieve the presence states for. Each name in the list should be separated by commas unless you specify an alternative `separator` | +| separator | _,_ | `string` | optionally, the character to use as a separator for the list of channel names in the `channels` parameter | + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | yes ([basic](#basic-authentication) or [token](#token-authentication)) | + +##### Returns + +**Success**: When successful, the operation returns HTTP status `200` and an array of objects with `channel` and `presence` properties. + + +```json +[ + { + "channel":"channel1", + "presence":[ + { + "id":"JSjj6i27T0:0:0", + "clientId":"bob", + "connectionId":"JSjj6i27T0", + "timestamp":1633985256512, + "action":1 + } + ] + }, + { + "channel":"channel2", + "presence":[ + { + "id":"JSjj6i27T0:1:0", + "clientId":"bob", + "connectionId":"JSjj6i27T0", + "timestamp":1633985256517, + "action":1 + } + ] + }, + { + "channel":"channel3", + "presence":[ + { + "id":"JSjj6i27T0:2:0", + "clientId":"bob", + "connectionId":"JSjj6i27T0", + "timestamp":1633985256517, + "action":1 + } + ] + } +] +``` + + +Each object in the `presence` array of each channel describes the presence state of one of that channel's members: + + +```text +[{ + id: , + clientId: , + connectionId: + timestamp: + action: , + data: +}] +``` + + +**Failure**: If the batch request itself fails the response body contains an [ErrorInfo](/docs/api/rest-sdk/types#error-info) object. + +**Partial success**: If the batch request itself succeeds, but one or more of the requests within the batch fails, then the response for the failed request contains an error object with the error code `40020` and a status code of `400`. Successful requests within the batch include a `presence` array that describes the presence state of each of the channel members. + + +## Utilities + +### Get the service time + +#### GET main.realtime.ably.net/time + +This returns the service time in milliseconds since the epoch. This may be used by clients that do not have local access to a sufficiently accurate time source when generating an Ably [`TokenRequest`](/docs/api/token-request-spec). (Ably [`TokenRequests`](/docs/api/token-request-spec) include a timestamp and have a limited validity period to help defend against replay attacks.) + +The result is a JSON-encoded array of length 1 containing the time result as a number. + + +```bash +curl http://main.realtime.ably.net/time +``` + + +##### Parameters + +None + +##### Options + +| Option | Value | +|--------|-------| +| Content-Type | not applicable | +| Accept | `application/json` by default, or `application/x-msgpack`, `text/html` | +| Auth required | no | + +##### Returns + + +```json +[ {'{{MS_SINCE_EPOCH}}'} ] +``` +