Ably Platform API

The Ably Platform API exposes pub/sub messaging, presence, history, push notifications, and channel/stats endpoints over REST and WebSocket. WebSocket realtime connections use realtime.ably.io. Authentication via Basic auth (key) or token-based.

OpenAPI Specification

ably-platform-api-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: Platform API
  description: The [REST API specification](https://www.ably.io/documentation/rest-api) for Ably.
  version: "1.1.1"
  contact:
    name: "Ably Support"
    url: "https://www.ably.io/contact"
    email: "[email protected]"
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Basic Authentication using an [API key](https://www.ably.io/documentation/core-features/authentication#basic-authentication).
    bearerAuth:
      type: http
      scheme: bearer
      description: Token Authentication using an [Ably Token](https://www.ably.io/documentation/core-features/authentication#basic-authentication), or optionally an [Ably JWT](https://www.ably.io/documentation/core-features/authentication#ably-jwt-process).

  headers:
    # TODO: Issue exists for integrating pagination with OpenAPI, https://github.com/OAI/OpenAPI-Specification/issues/667. If this is ever actioned, we should enable it within our spec.
    Link:
      description: Links to related resources, in the format defined by [RFC 5988](https://tools.ietf.org/html/rfc5988#section-5). This will potentially include a link with relation type `next`, `first`, and `current`, where appropiate.
      schema:
        type: string
        pattern: '(<(.*)?>; rel=\"(first|current|last)?\",)*(<(.*)?>; rel=\"(first|current|last)?\")+'
      required: true

    ServerId:
      description: The ID for the server communicated with.
      schema:
        type: string
      required: true

    ErrorCode:
      description: The error code.
      schema:
        type: integer

    ErrorMessage:
      description: The error message.
      schema:
        type: string

  parameters:
    # Currently each parameter needs to be defined seperately. If https://github.com/OAI/OpenAPI-Specification/issues/445 ever goes through, can amalagmate pagination parameters
    filterStart:
      name: start
      in: query
      schema:
        type: string

    filterLimit:
      name: limit
      in: query
      schema:
        type: integer
        default: '100'

    filterEnd:
      name: end
      in: query
      schema:
        type: string
        default: now

    filterDirection:
      name: direction
      in: query
      schema:
        type: string
        default: backwards
        enum: [forwards, backwards ]

    channelId:
      name: channel_id
      in: path
      schema:
        type: string
      required: true
      description: The [Channel's ID](https://www.ably.io/documentation/rest/channels).

    # TODO: Better document what the name is
    key_name:
      name: keyName
      in: path
      schema:
        type: string
      required: true
      description: The [key name](https://www.ably.io/documentation/rest-api/token-request-spec#api-key-format) comprises of the app ID and key ID of an API key.

    deviceId:
      name: device_id
      in: path
      schema:
        type: string
      required: true
      description: Device's ID.

    versionHeader:
      in: header
      name: X-Ably-Version
      schema:
        type: string
      description: The version of the API you wish to use.

    responseFormat:
      in: query
      name: format
      schema:
        type: string
        enum:
          - json
          - jsonp
          - msgpack
          - html
      description: The response format you would like

  schemas:
    # Message components
    Message:
      type: object
      description: Message object.
      properties:
        name:
          description: The event name, if provided.
          type: string
        data:
          description: The string encoded payload, with the encoding specified below.
          type: string
        id:
          description: A Unique ID that can be specified by the publisher for [idempotent publishing](https://www.ably.io/documentation/rest/messages#idempotent).
          type: string
          readOnly: true
        timestamp:
          description: Timestamp when the message was received by the Ably, as milliseconds since the epoch.
          type: integer
          format: int64
          readOnly: true
        encoding:
          description: This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the data payload.
          type: string
        clientId:
          description: The [client ID](https://www.ably.io/documentation/core-features/authentication#identified-clients) of the publisher of this message.
          type: string
        connectionId:
          description: The connection ID of the publisher of this message.
          type: string
        # TODO: Currently object does not work with application/x-www-form-urlencoded
        extras:
          $ref: '#/components/schemas/Extras'

    Extras:
      type: object
      description: Extras object. Currently only allows for [push](https://www.ably.io/documentation/general/push/publish#channel-broadcast-example) extra.
      properties:
        push:
          $ref: '#/components/schemas/Push'

    Push:
      type: object
      properties:
        data:
          description: Arbitrary [key-value string-to-string payload](https://www.ably.io/documentation/general/push/publish#channel-broadcast-example).
          type: string
        notification:
          $ref: '#/components/schemas/Notification'
        apns:
          description: Extends and overrides generic values when delivering via APNs. [See examples](https://www.ably.io/documentation/general/push/publish#payload-structure)
          type: object
          properties:
            notification:
              $ref: '#/components/schemas/Notification'
        fcm:
          description: Extends and overrides generic values when delivering via GCM/FCM. [See examples](https://www.ably.io/documentation/general/push/publish#payload-structure)
          type: object
          properties:
            notification:
              $ref: '#/components/schemas/Notification'
        web:
          description: Extends and overrides generic values when delivering via web. [See examples](https://www.ably.io/documentation/general/push/publish#payload-structure)
          type: object
          properties:
            notification:
              $ref: '#/components/schemas/Notification'

    Notification:
      type: object
      properties:
        title:
          description: Title to display at the notification.
          type: string
        body:
          description: Text below title on the expanded notification.
          type: string
        icon:
          description: Platform-specific icon for the notification.
          type: string
        sound:
          description: Platform-specific sound for the notification.
          type: string
        collapseKey:
          # Needs more information
          description: Platform-specific, used to group notifications together.
          type: string

    PresenceMessage:
      type: object
      properties:
        id:
          description: Unique ID assigned by Ably to this presence update.
          type: string
          readOnly: true
        action:
          description: The event signified by a PresenceMessage.
          type: string
          enum: [ ABSENT, PRESENT, ENTER, LEAVE, UPDATE ]
          readOnly: true
        data:
          description: The presence update payload, if provided.
          type: string
        clientId:
          description: The client ID of the publisher of this presence update.
          type: string
        connectionId:
          description: The connection ID of the publisher of this presence update.
          type: string
        timestamp:
          description: Timestamp when the presence update was received by Ably, as milliseconds since the epoch.
          type: integer
          format: int64
          readOnly: true
        encoding:
          description: This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the data payload.
          type: string
        extras:
          $ref: '#/components/schemas/Extras'

    TokenRequest:
      type: object
      properties:
        keyName:
          type: string
          description: Name of the key used for the TokenRequest. The keyName comprises of the app ID and key ID on an API Key.
          example: xVLyHw.LMJZxw
        capability:
          type: object
          description: The [capabilities](https://www.ably.io/documentation/core-features/authentication#capabilities-explained) (i.e. a set of channel names/namespaces and, for each, a set of operations) which should be a subset of the set of capabilities associated with the key specified in keyName.
          example: { "channel1": [ "publish", "subscribe" ]}
        clientId:
          type: string
          description: The [client ID](https://www.ably.io/documentation/core-features/authentication#identified-clients) to be assosciated with the token. Can be set to * to allow for any client ID to be used.
        timestamp:
          type: integer
          description: Time of creation of the Ably TokenRequest.
        nonce:
          type: string
          description: An unquoted, un-escaped random string of at least 16 characters. Used to ensure the Ably TokenRequest cannot be reused.
      required:
        - keyName
        - capability
        - timestamp
        - nonce

    SignedTokenRequest:
      allOf:
        - $ref: '#/components/schemas/TokenRequest'
        - type: object
          properties:
            mac:
              type: string
              description: A signature, generated as an HMAC of each of the above components, using the key secret value.
          required:
            - mac

    TokenDetails:
      type: object
      properties:
        token:
          type: string
          description: The Ably Token.
        keyName:
          type: string
          description: Name of the key used to create the token
        issued:
          type: integer
          description: Timestamp of token creation.
        expires:
          type: integer
          description: Timestamp of token expiration.
        capability:
          # TODO: capabilities object representation, does validation as well
          type: string
          description: Regular expression representation of the capabilities of the token.

    ChannelDetails:
      type: object
      properties:
        channelId:
          type: string
          description: The required name of the channel including any qualifier, if any.
        region:
          type: string
          description: In events relating to the activity of a channel in a specific region, this optionally identifies the region.
        isGlobalMaster:
          type: boolean
          description: In events relating to the activity of a channel in a specific region, this optionally identifies whether or not that region is responsible for global coordination of the channel.
        status:
          $ref: '#/components/schemas/ChannelStatus'
      required:
        - channelId

    ChannelStatus:
      type: object
      description: A ChannelStatus instance.
      properties:
        isActive:
          type: boolean
          description: A required boolean value indicating whether the channel that is the subject of the event is active. For events indicating regional activity of a channel this indicates activity in that region, not global activity.
        occupancy:
          $ref: '#/components/schemas/Occupancy'
      required:
        - isActive

    Occupancy:
      type: object
      description: An Occupancy instance indicating the occupancy of a channel. For events indicating regional activity of a channel this indicates activity in that region, not global activity.
      properties:
        publishers:
          type: integer
          description: The number of connections attached to the channel that are authorised to publish.
        subscribers:
          type: integer
          description: The number of connections attached that are authorised to subscribe to messages.
        presenceSubscribers:
          type: integer
          description: The number of connections that are authorised to subscribe to presence messages.
        presenceConnections:
          type: integer
          description: The number of connections that are authorised to enter members into the presence channel.
        presenceMembers:
          type: integer
          description: The number of members currently entered into the presence channel.

    DeviceDetails:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the device generated by the device itself.
        clientId:
          type: string
          description: Optional trusted client identifier for the device.
        formFactor:
          type: string
          description: Form factor of the push device.
          enum: [ phone, tablet, desktop, tv, watch, car, embedded ]
        metadata:
          type: object
          description: Optional metadata object for this device. The metadata for a device may only be set by clients with push-admin privileges and will be used more extensively in the future with smart notifications.
        platform:
          type: string
          description: Platform of the push device.
          enum: [ ios, android, browser ]
        deviceSecret:
          type: string
          description: Secret value for the device.
        push.recipient:
          $ref: '#/components/schemas/Recipient'
        push.state:
          type: string
          description: the current state of the push device.
          enum: [ Active, Failing, Failed ]
          readOnly: true

    Recipient:
      type: object
      description: Push recipient details for a device.
      properties:
        transportType:
          type: string
          description: Defines which push platform is being used.
          enum: [ apns, fcm, gcm, web ]
        deviceToken:
          type: string
          # TODO: Link to above enum for required
          description: when using APNs, specifies the required device token.
        registrationToken:
          type: string
          # TODO: Link to above enum for required
          description: when using GCM or FCM, specifies the required registration token.
          properties:
            auth:
              type: string
              description: An Elliptic curve Diffie-Hellman public key on the P-256 curve. Obtained from a PushDescription using the `getKey` method.
            p256dh:
              type: string
              description: An authentication secret, as described by [Message Encryption for Web Push](https://datatracker.ietf.org/doc/html/draft-ietf-webpush-encryption-08).
        encryptionKey:
          type: object
          # TODO: Link to above enum for required
          description: when using web push, specifies the required encryptionKey.

        clientId:
          type: string
          # TODO: Link to no transportType
          description: Client ID of recipient
          writeOnly: true
        deviceId:
          type: string
          # TODO: Link to no transportType
          description: Client ID of recipient
          writeOnly: true

    Error:
      type: object
      description: Returned error from failed REST.
      properties:
        message:
          type: string
          description: Message explaining the error's cause.
        code:
          type: integer
          description: Error code.
        statusCode:
          type: integer
          description: Status error code.
        href:
          type: string
          description: Link to help with error.
        serverId:
          type: string
          description: Server ID with which error was encountered.

  responses:
    Error:
      description: Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
        application/x-msgpack:
          schema:
            $ref: '#/components/schemas/Error'
        text/html:
          schema:
            $ref: '#/components/schemas/Error'
      headers:
        x-ably-errorcode:
          $ref: '#/components/headers/ErrorCode'
        x-ably-errormessage:
          $ref: '#/components/headers/ErrorMessage'
        x-ably-serverid:
          $ref: '#/components/headers/ServerId'

security:
  - basicAuth: []
  - bearerAuth: []

servers:
- url: https://rest.ably.io

paths:
  /channels/{channel_id}/messages:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: Get message history for a channel
      operationId: getMessagesByChannel
      tags:
        - History
      description: Get message history for a channel
      parameters:
        - $ref: '#/components/parameters/channelId'
        - $ref: '#/components/parameters/filterStart'
        - $ref: '#/components/parameters/filterLimit'
        - $ref: '#/components/parameters/filterEnd'
        - $ref: '#/components/parameters/filterDirection'
      responses:
        '2XX':
          description: OK
          headers:
            link:
              $ref: '#/components/headers/Link'
            x-ably-serverid:
              $ref: '#/components/headers/ServerId'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Message'
            application/x-msgpack:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Message'
            text/html:
              schema:
                type: string
        default:
          description: Error
          headers:
            x-ably-errorcode:
              $ref: '#/components/headers/ErrorCode'
            x-ably-errormessage:
              $ref: '#/components/headers/ErrorMessage'
            x-ably-serverid:
              $ref: '#/components/headers/ServerId'

    post:
      summary: Publish a message to a channel
      operationId: publishMessagesToChannel
      description: Publish a message to the specified channel
      tags:
        - Publishing
      parameters:
        - $ref: '#/components/parameters/channelId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Message'
          application/x-msgpack:
            schema:
              $ref: '#/components/schemas/Message'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Message'
      responses:
        '2XX':
          description: OK
          headers:
            x-ably-serverid:
              $ref: '#/components/headers/ServerId'
          content:
            application/json:
              schema:
                type: object
                properties:
                  channel:
                    type: string
                  messageId:
                    type: string
            application/x-msgpack:
              schema:
                type: object
                properties:
                  channel:
                    type: string
                  messageId:
                    type: string
            text/html:
              schema:
                type: object
                properties:
                  channel:
                    type: string
                  messageId:
                    type: string
        default:
          $ref: '#/components/responses/Error'

  /channels/{channel_id}/presence:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: Get presence of a channel
      operationId: getPresenceOfChannel
      description: Get presence on a channel
      tags:
        - Status
      parameters:
        - $ref: '#/components/parameters/channelId'
        - name: clientId
          in: query
          schema:
            type: string
        - name: connectionId
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
      responses:
        '200':
          description: OK
          headers:
            link:
              $ref: '#/components/headers/Link'
            x-ably-serverid:
              $ref: '#/components/headers/ServerId'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PresenceMessage'
            application/x-msgpack:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PresenceMessage'
            text/html:
              schema:
                type: string
        default:
          $ref: '#/components/responses/Error'

  /channels/{channel_id}/presence/history:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: Get presence history of a channel
      operationId: getPresenceHistoryOfChannel
      description: Get presence on a channel
      tags:
        - History
      parameters:
        - $ref: '#/components/parameters/channelId'
        - $ref: '#/components/parameters/filterStart'
        - $ref: '#/components/parameters/filterLimit'
        - $ref: '#/components/parameters/filterEnd'
        - $ref: '#/components/parameters/filterDirection'
      responses:
        '2XX':
          description: OK
          headers:
            link:
              $ref: '#/components/headers/Link'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PresenceMessage'
            application/x-msgpack:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PresenceMessage'
            text/html:
              schema:
                type: string
        default:
          $ref: '#/components/responses/Error'

  /channels/{channel_id}:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: Get metadata of a channel
      operationId: getMetadataOfChannel
      description: Get metadata of a channel
      tags:
        - Status
      parameters:
        - $ref: '#/components/parameters/channelId'
      responses:
        '200':
          description: OK
          headers:
            x-ably-serverid:
              $ref: '#/components/headers/ServerId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChannelDetails'
        default:
          $ref: '#/components/responses/Error'

  /channels:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: Enumerate all active channels of the application
      operationId: getMetadataOfAllChannels
      description: Enumerate all active channels of the application
      tags:
        - Status
      parameters:
        - in: query
          name: limit
          schema:
            type: integer
            default: 100
        - in: query
          name: prefix
          schema:
            type: string
          description: Optionally limits the query to only those channels whose name starts with the given prefix
        - in: query
          name: by
          schema:
            type: string
            enum: [ value, id ]
          description: optionally specifies whether to return just channel names (by=id) or ChannelDetails (by=value)
      responses:
        '2XX':
          description: OK
          headers:
            link:
              $ref: '#/components/headers/Link'
          content:
            application/json:
              schema:
                oneOf:
                  - type: array
                    items:
                      $ref: '#/components/schemas/ChannelDetails'
                  - type: array
                    items:
                      type: string
            application/x-msgpack:
              schema:
                oneOf:
                  - type: array
                    items:
                      $ref: '#/components/schemas/ChannelDetails'
                  - type: array
                    items:
                      type: string
            text/html:
              schema:
                type: string
        default:
          $ref: '#/components/responses/Error'

  /push/deviceRegistrations:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: List devices registered for receiving push notifications
      operationId: getRegisteredPushDevices
      description: List of device details of devices registed for push notifications.
      tags:
        - Push
      parameters:
        - name: deviceId
          description: Optional filter to restrict to devices associated with that deviceId.
          in: query
          schema:
            type: string
        - name: clientId
          in: query
          description: Optional filter to restrict to devices associated with that clientId.
          schema:
            type: string
        - name: limit
          in: query
          description: The maximum number of records to return.
          schema:
            type: integer
            default: 100
            maximum: 1000
      responses:
        '2XX':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            application/x-msgpack:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            text/html:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
        default:
          $ref: '#/components/responses/Error'

    post:
      summary: Register a device for receiving push notifications
      operationId: registerPushDevice
      description: Register a device’s details, including the information necessary to deliver push notifications to it. Requires "push-admin" capability.
      tags:
        - Push
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
          application/x-msgpack:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
      responses:
        '2XX':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            application/x-msgpack:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            text/html:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
        default:
          $ref: '#/components/responses/Error'

    delete:
      summary: Unregister matching devices for push notifications
      operationId: unregisterAllPushDevices
      description: Unregisters devices. All their subscriptions for receiving push notifications through channels will also be deleted.
      tags:
        - Push
      parameters:
        # TODO: Implement a oneOf filter
        - name: deviceId
          description: Optional filter to restrict to devices associated with that deviceId. Cannot be used with clientId.
          in: query
          schema:
            type: string
        - name: clientId
          in: query
          description: Optional filter to restrict to devices associated with that clientId. Cannot be used with deviceId.
          schema:
            type: string
      responses:
        '2XX':
          description: OK
        default:
          $ref: '#/components/responses/Error'

  /push/deviceRegistrations/{device_id}:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      operationId: getPushDeviceDetails
      summary: Get a device registration
      description: Get the full details of a device.
      tags:
        - Push
      parameters:
        - $ref: '#/components/parameters/deviceId'
      responses:
        '2XX':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            application/x-msgpack:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            text/html:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
        default:
          $ref: '#/components/responses/Error'

    put:
      summary: Update a device registration
      operationId: putPushDeviceDetails
      description: Device registrations can be upserted (the existing registration is replaced entirely) with a PUT operation. Only clientId, metadata and push.recipient are mutable.
      tags:
        - Push
      parameters:
        - $ref: '#/components/parameters/deviceId'
      requestBody:
        content:
          # TODO: Some application of allOf to enforce usage of all details
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
          application/x-msgpack:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
      responses:
        '2XX':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            application/x-msgpack:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            text/html:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
        default:
          $ref: '#/components/responses/Error'

    patch:
      summary: Update a device registration
      operationId: patchPushDeviceDetails
      description: Specific attributes of an existing registration can be updated. Only clientId, metadata and push.recipient are mutable.
      tags:
        - Push
      parameters:
        - $ref: '#/components/parameters/deviceId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
          application/x-msgpack:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DeviceDetails'
      responses:
        '2XX':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            application/x-msgpack:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
            text/html:
              schema:
                $ref: '#/components/schemas/DeviceDetails'
        default:
          $ref: '#/components/responses/Error'

    delete:
      summary: Unregister a single device for push notifications
      operationId: unregisterPushDevice
      description: Unregisters a single device by its device ID. All its subscriptions for receiving push notifications through channels will also be deleted.
      tags:
        - Push
      parameters:
        - $ref: '#/components/parameters/deviceId'
      responses:
        '2XX':
          description: OK
        default:
          $ref: '#/components/responses/Error'

  /push/deviceRegistrations/{device_id}/resetUpdateToken:
    parameters:
      - $ref: '#/components/parameters/versionHeader'
      - $ref: '#/components/parameters/responseFormat'

    get:
      summary: Reset a registered device's update token
      operationId: updatePushDevic

# --- truncated at 32 KB (44 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ably/refs/heads/main/openapi/ably-platform-api-openapi.yml