Azure Web PubSub · AsyncAPI Specification

Azure Web PubSub

Version 1.0.0

Azure Web PubSub is a fully managed real-time messaging service from Microsoft Azure that lets clients exchange publish/subscribe messages over WebSockets without operating WebSocket infrastructure. Clients connect to the service over secure WebSocket (`wss://`) and may either use a simple WebSocket frame (text/binary) or upgrade to one of the JSON publish/subscribe subprotocols: - `json.webpubsub.azure.v1` — JSON pub/sub subprotocol that lets a *PubSub WebSocket client* join groups, publish to groups, and route custom events to upstream event handlers directly through the service. - `json.reliable.webpubsub.azure.v1` — Reliable variant of the JSON pub/sub subprotocol that adds `sequenceId` on every server-to-client `message` and requires the client to acknowledge with a `sequenceAck`. Also returns `reconnectionToken` on `connected` so clients can recover sessions across intermittent network failures using the `awps_connection_id` / `awps_reconnection_token` query parameters. The server side of an Azure Web PubSub solution receives client activity as **upstream events** delivered by the service to a configured webhook endpoint using the CloudEvents 1.0 HTTP binding (binary content mode). Event types are namespaced `azure.webpubsub.sys.*` for system events (`connect`, `connected`, `disconnected`) and `azure.webpubsub.user.*` for user events (`message` for simple clients and `` for PubSub subprotocol clients sending `type: event` frames). Web PubSub also advertises an Event Grid integration where events are published with `eventType` values like `Microsoft.SignalRService.ClientConnectionConnected` and `Microsoft.SignalRService.ClientConnectionDisconnected`; the CloudEvents `ce-type` values delivered by the Web PubSub event handler (Webhook upstream) however use the `azure.webpubsub.*` namespace as documented at https://learn.microsoft.com/en-us/azure/azure-web-pubsub/reference-cloud-events and modeled below. This AsyncAPI document models only the documented surface area of the JSON WebSocket subprotocols and the CloudEvents HTTP upstream contract. Fields not documented by Microsoft (for example, undocumented subprotocol message types, undocumented CloudEvents extensions, or REST data-plane operations — which are modeled separately in OpenAPI) are intentionally NOT included.

View Spec View on GitHub MessagingPub-SubReal-TimeServerlessWebSocketsAsyncAPIWebhooksEvents

Channels

/client/hubs/{hub}
publish clientSend
Messages a client sends to the service over the JSON pub/sub subprotocol.
WebSocket channel between a single client and a hub on the Web PubSub service instance. Each connection belongs to exactly one hub. Messages on this channel are JSON frames defined by the `json.webpubsub.azure.v1` or `json.reliable.webpubsub.azure.v1` subprotocol. Simple WebSocket clients (no subprotocol) exchange raw text/binary frames instead and are NOT modeled here — refer to the user event handler contract on the `upstream` server for how their frames surface to the application backend.
/upstream
subscribe upstreamDeliver
Events delivered by Azure Web PubSub to the upstream webhook. `connect` and user events are *blocking* events whose response the service waits for; `connected` and `disconnected` are *unblocking* (asynchronous) notifications.
CloudEvents 1.0 HTTP delivery channel from the Web PubSub service to the customer-configured upstream webhook. The service POSTs one HTTP request per client event, using CloudEvents *binary* content mode (CloudEvents attributes are conveyed in `ce-*` HTTP headers; the event payload is the HTTP body). All requests carry `WebHook-Request-Origin: .webpubsub.azure.com` and a signed `ce-signature` header so the upstream can validate the origin of the request.

Messages

JoinGroup
Join Group request
Client asks the service to add the connection to a group.
LeaveGroup
Leave Group request
Client asks the service to remove the connection from a group.
SendToGroup
Send-To-Group request
Client publishes a message to all connections in a group.
SendEvent
Send custom event request
Client sends a custom user event that the service forwards to the upstream event handler as a CloudEvents request with `ce-type: azure.webpubsub.user.`.
Ping
Ping
Client liveness check.
SequenceAck
Sequence Ack (reliable subprotocol only)
Acknowledgement of a `sequenceId` delivered on an inbound message. Required for the `json.reliable.webpubsub.azure.v1` subprotocol so the service can release in-flight messages.
AckResponse
Ack response
Service response to a client request that carried `ackId`. Clients should inspect `success` before reading `error`.
MessageFromGroup
Group message
Data message delivered to the client because a publisher (REST API, server SDK, or another subprotocol client) sent it to a group the client has joined.
MessageFromServer
Server message
Data message delivered to the client because the server (REST API or server SDK) targeted this connection, the user, or all connections.
SystemConnected
System connected event
Service notifies the client that the WebSocket handshake succeeded. Reliable subprotocol additionally carries `reconnectionToken` for use on session recovery.
SystemDisconnected
System disconnected event
Service notifies the client that the connection was closed by the server or declined by the service.
Pong
Pong
Service response to a `ping` request.
UpstreamSystemConnect
Upstream `connect` (blocking)
Blocking CloudEvents request fired during WebSocket handshake. The upstream may approve the connection (HTTP 200 with optional `userId`/`groups`/`roles`/`subprotocol` body, or HTTP 204) or deny it (4xx). Used to perform authentication, authorization, subprotocol negotiation, and auto-join group assignment.
UpstreamSystemConnected
Upstream `connected` (unblocking)
Asynchronous notification fired after a client has successfully completed the WebSocket handshake. Upstream is expected to return a 2xx; non-2xx responses are logged by the service but do not affect the connection.
UpstreamSystemDisconnected
Upstream `disconnected` (unblocking)
Asynchronous notification fired after a client disconnects, if the `connect` event previously returned a 2xx. The body carries the disconnect `reason`.
UpstreamUserMessage
Upstream `message` for simple WebSocket clients (blocking)
Blocking CloudEvents request fired for every WebSocket frame a *simple* (no subprotocol) client sends. The HTTP body is the raw payload the client sent. The upstream's response body, if any, is sent back to the client as a frame whose type follows the response `Content-Type` (`text/plain` => text frame, `application/octet-stream` => binary frame).
UpstreamUserCustomEvent
Upstream `` for PubSub clients (blocking)
Blocking CloudEvents request fired when a PubSub subprotocol client sends a `type: event` frame. The CloudEvents `ce-type` is `azure.webpubsub.user.` and the body is the `data` field of the original frame (text, JSON, or binary, depending on `dataType`).

Servers

wss
client wss://{instance}.webpubsub.azure.com
Azure Web PubSub client endpoint. Clients open a WebSocket connection to `wss://{instance}.webpubsub.azure.com/client/hubs/{hub}` and optionally specify one of the supported subprotocols via the `Sec-WebSocket-Protocol` header. Authentication is performed with a short-lived JWT access token passed as the `access_token` query parameter (generated by the service's REST data plane or a server SDK).
https
upstream https://{upstreamHost}
Customer-owned HTTP endpoint registered as an event handler on the hub. The Web PubSub service delivers client events to this endpoint using the CloudEvents 1.0 HTTP protocol binding (binary content mode). The endpoint must implement CloudEvents abuse-protection handshake by returning `WebHook-Allowed-Origin` in response to the `WebHook-Request-Origin` validation request.

AsyncAPI Specification

Raw ↑
asyncapi: '2.6.0'
id: 'urn:com:microsoft:azure:webpubsub'
info:
  title: Azure Web PubSub
  version: '1.0.0'
  description: |
    Azure Web PubSub is a fully managed real-time messaging service from
    Microsoft Azure that lets clients exchange publish/subscribe messages
    over WebSockets without operating WebSocket infrastructure. Clients
    connect to the service over secure WebSocket (`wss://`) and may either
    use a simple WebSocket frame (text/binary) or upgrade to one of the
    JSON publish/subscribe subprotocols:

    - `json.webpubsub.azure.v1` — JSON pub/sub subprotocol that lets a
      *PubSub WebSocket client* join groups, publish to groups, and route
      custom events to upstream event handlers directly through the
      service.
    - `json.reliable.webpubsub.azure.v1` — Reliable variant of the JSON
      pub/sub subprotocol that adds `sequenceId` on every server-to-client
      `message` and requires the client to acknowledge with a
      `sequenceAck`. Also returns `reconnectionToken` on `connected` so
      clients can recover sessions across intermittent network failures
      using the `awps_connection_id` / `awps_reconnection_token` query
      parameters.

    The server side of an Azure Web PubSub solution receives client
    activity as **upstream events** delivered by the service to a
    configured webhook endpoint using the CloudEvents 1.0 HTTP binding
    (binary content mode). Event types are namespaced
    `azure.webpubsub.sys.*` for system events (`connect`, `connected`,
    `disconnected`) and `azure.webpubsub.user.*` for user events
    (`message` for simple clients and `<custom_event>` for PubSub
    subprotocol clients sending `type: event` frames). Web PubSub also
    advertises an Event Grid integration where events are published with
    `eventType` values like `Microsoft.SignalRService.ClientConnectionConnected`
    and `Microsoft.SignalRService.ClientConnectionDisconnected`; the
    CloudEvents `ce-type` values delivered by the Web PubSub event handler
    (Webhook upstream) however use the `azure.webpubsub.*` namespace as
    documented at
    https://learn.microsoft.com/en-us/azure/azure-web-pubsub/reference-cloud-events
    and modeled below.

    This AsyncAPI document models only the documented surface area of the
    JSON WebSocket subprotocols and the CloudEvents HTTP upstream
    contract. Fields not documented by Microsoft (for example, undocumented
    subprotocol message types, undocumented CloudEvents extensions, or
    REST data-plane operations — which are modeled separately in OpenAPI)
    are intentionally NOT included.
  contact:
    name: Azure Web PubSub Documentation
    url: https://learn.microsoft.com/en-us/azure/azure-web-pubsub/
  license:
    name: Microsoft Terms of Use
    url: https://www.microsoft.com/en-us/legal/terms-of-use
  externalDocs:
    description: Azure Web PubSub overview
    url: https://learn.microsoft.com/en-us/azure/azure-web-pubsub/
defaultContentType: application/json
servers:
  client:
    url: 'wss://{instance}.webpubsub.azure.com'
    protocol: wss
    description: |
      Azure Web PubSub client endpoint. Clients open a WebSocket
      connection to `wss://{instance}.webpubsub.azure.com/client/hubs/{hub}`
      and optionally specify one of the supported subprotocols via the
      `Sec-WebSocket-Protocol` header. Authentication is performed with a
      short-lived JWT access token passed as the `access_token` query
      parameter (generated by the service's REST data plane or a server
      SDK).
    variables:
      instance:
        default: example
        description: Web PubSub service instance name
    security:
      - clientAccessToken: []
  upstream:
    url: 'https://{upstreamHost}'
    protocol: https
    description: |
      Customer-owned HTTP endpoint registered as an event handler on the
      hub. The Web PubSub service delivers client events to this endpoint
      using the CloudEvents 1.0 HTTP protocol binding (binary content
      mode). The endpoint must implement CloudEvents abuse-protection
      handshake by returning `WebHook-Allowed-Origin` in response to the
      `WebHook-Request-Origin` validation request.
    variables:
      upstreamHost:
        default: contoso.example.com
        description: Customer-controlled upstream webhook host
channels:
  /client/hubs/{hub}:
    description: |
      WebSocket channel between a single client and a hub on the Web
      PubSub service instance. Each connection belongs to exactly one
      hub. Messages on this channel are JSON frames defined by the
      `json.webpubsub.azure.v1` or `json.reliable.webpubsub.azure.v1`
      subprotocol. Simple WebSocket clients (no subprotocol) exchange
      raw text/binary frames instead and are NOT modeled here — refer
      to the user event handler contract on the `upstream` server for
      how their frames surface to the application backend.
    servers:
      - client
    parameters:
      hub:
        description: Hub name. Hubs provide logical isolation within an instance.
        schema:
          type: string
    bindings:
      ws:
        bindingVersion: '0.1.0'
        query:
          type: object
          description: Query string parameters supported on the connect handshake.
          properties:
            access_token:
              type: string
              description: JWT access token authorizing the client connection.
            awps_connection_id:
              type: string
              description: |
                Reliable subprotocol only. Previously-issued connection
                id used to recover a dropped session.
            awps_reconnection_token:
              type: string
              description: |
                Reliable subprotocol only. Token returned on the
                original `connected` system message; required to recover
                a dropped session.
        headers:
          type: object
          properties:
            Sec-WebSocket-Protocol:
              type: string
              enum:
                - json.webpubsub.azure.v1
                - json.reliable.webpubsub.azure.v1
              description: |
                Optional subprotocol negotiation. If omitted the
                connection behaves as a *simple WebSocket client* and
                frames are passed through to the upstream event handler
                as `azure.webpubsub.user.message` events. If present,
                the client may exchange the JSON pub/sub frames defined
                in this document.
    publish:
      operationId: clientSend
      summary: Messages a client sends to the service over the JSON pub/sub subprotocol.
      message:
        oneOf:
          - $ref: '#/components/messages/JoinGroup'
          - $ref: '#/components/messages/LeaveGroup'
          - $ref: '#/components/messages/SendToGroup'
          - $ref: '#/components/messages/SendEvent'
          - $ref: '#/components/messages/Ping'
          - $ref: '#/components/messages/SequenceAck'
    subscribe:
      operationId: clientReceive
      summary: Messages the service sends back to the client.
      message:
        oneOf:
          - $ref: '#/components/messages/AckResponse'
          - $ref: '#/components/messages/MessageFromGroup'
          - $ref: '#/components/messages/MessageFromServer'
          - $ref: '#/components/messages/SystemConnected'
          - $ref: '#/components/messages/SystemDisconnected'
          - $ref: '#/components/messages/Pong'
  /upstream:
    description: |
      CloudEvents 1.0 HTTP delivery channel from the Web PubSub service
      to the customer-configured upstream webhook. The service POSTs
      one HTTP request per client event, using CloudEvents *binary*
      content mode (CloudEvents attributes are conveyed in `ce-*` HTTP
      headers; the event payload is the HTTP body). All requests carry
      `WebHook-Request-Origin: <instance>.webpubsub.azure.com` and a
      signed `ce-signature` header so the upstream can validate the
      origin of the request.
    servers:
      - upstream
    bindings:
      http:
        bindingVersion: '0.3.0'
        type: request
        method: POST
    subscribe:
      operationId: upstreamDeliver
      summary: |
        Events delivered by Azure Web PubSub to the upstream webhook.
        `connect` and user events are *blocking* events whose response
        the service waits for; `connected` and `disconnected` are
        *unblocking* (asynchronous) notifications.
      message:
        oneOf:
          - $ref: '#/components/messages/UpstreamSystemConnect'
          - $ref: '#/components/messages/UpstreamSystemConnected'
          - $ref: '#/components/messages/UpstreamSystemDisconnected'
          - $ref: '#/components/messages/UpstreamUserMessage'
          - $ref: '#/components/messages/UpstreamUserCustomEvent'
components:
  securitySchemes:
    clientAccessToken:
      type: httpApiKey
      in: query
      name: access_token
      description: |
        Short-lived JWT access token passed as the `access_token` query
        parameter on the WebSocket handshake. Tokens are issued by the
        Web PubSub service data-plane REST API
        (`POST /api/hubs/{hub}/:generateToken`) or by a server SDK using
        the service AccessKey.
  messages:
    JoinGroup:
      name: joinGroup
      title: Join Group request
      summary: Client asks the service to add the connection to a group.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/JoinGroupPayload'
    LeaveGroup:
      name: leaveGroup
      title: Leave Group request
      summary: Client asks the service to remove the connection from a group.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/LeaveGroupPayload'
    SendToGroup:
      name: sendToGroup
      title: Send-To-Group request
      summary: Client publishes a message to all connections in a group.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/SendToGroupPayload'
    SendEvent:
      name: event
      title: Send custom event request
      summary: |
        Client sends a custom user event that the service forwards to
        the upstream event handler as a CloudEvents request with
        `ce-type: azure.webpubsub.user.<event_name>`.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/SendEventPayload'
    Ping:
      name: ping
      title: Ping
      summary: Client liveness check.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/PingPayload'
    SequenceAck:
      name: sequenceAck
      title: Sequence Ack (reliable subprotocol only)
      summary: |
        Acknowledgement of a `sequenceId` delivered on an inbound
        message. Required for the `json.reliable.webpubsub.azure.v1`
        subprotocol so the service can release in-flight messages.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/SequenceAckPayload'
    AckResponse:
      name: ack
      title: Ack response
      summary: |
        Service response to a client request that carried `ackId`.
        Clients should inspect `success` before reading `error`.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/AckResponsePayload'
    MessageFromGroup:
      name: messageFromGroup
      title: Group message
      summary: |
        Data message delivered to the client because a publisher (REST
        API, server SDK, or another subprotocol client) sent it to a
        group the client has joined.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/MessageFromGroupPayload'
    MessageFromServer:
      name: messageFromServer
      title: Server message
      summary: |
        Data message delivered to the client because the server (REST
        API or server SDK) targeted this connection, the user, or all
        connections.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/MessageFromServerPayload'
    SystemConnected:
      name: systemConnected
      title: System connected event
      summary: |
        Service notifies the client that the WebSocket handshake
        succeeded. Reliable subprotocol additionally carries
        `reconnectionToken` for use on session recovery.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/SystemConnectedPayload'
    SystemDisconnected:
      name: systemDisconnected
      title: System disconnected event
      summary: |
        Service notifies the client that the connection was closed by
        the server or declined by the service.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/SystemDisconnectedPayload'
    Pong:
      name: pong
      title: Pong
      summary: Service response to a `ping` request.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/PongPayload'
    UpstreamSystemConnect:
      name: upstreamSystemConnect
      title: Upstream `connect` (blocking)
      summary: |
        Blocking CloudEvents request fired during WebSocket handshake.
        The upstream may approve the connection (HTTP 200 with optional
        `userId`/`groups`/`roles`/`subprotocol` body, or HTTP 204) or
        deny it (4xx). Used to perform authentication, authorization,
        subprotocol negotiation, and auto-join group assignment.
      contentType: application/json
      bindings:
        http:
          bindingVersion: '0.3.0'
          headers:
            $ref: '#/components/schemas/CloudEventsConnectHeaders'
      payload:
        $ref: '#/components/schemas/UpstreamConnectPayload'
    UpstreamSystemConnected:
      name: upstreamSystemConnected
      title: Upstream `connected` (unblocking)
      summary: |
        Asynchronous notification fired after a client has successfully
        completed the WebSocket handshake. Upstream is expected to
        return a 2xx; non-2xx responses are logged by the service but
        do not affect the connection.
      contentType: application/json
      bindings:
        http:
          bindingVersion: '0.3.0'
          headers:
            $ref: '#/components/schemas/CloudEventsConnectedHeaders'
      payload:
        $ref: '#/components/schemas/UpstreamEmptyJsonPayload'
    UpstreamSystemDisconnected:
      name: upstreamSystemDisconnected
      title: Upstream `disconnected` (unblocking)
      summary: |
        Asynchronous notification fired after a client disconnects, if
        the `connect` event previously returned a 2xx. The body carries
        the disconnect `reason`.
      contentType: application/json
      bindings:
        http:
          bindingVersion: '0.3.0'
          headers:
            $ref: '#/components/schemas/CloudEventsDisconnectedHeaders'
      payload:
        $ref: '#/components/schemas/UpstreamDisconnectedPayload'
    UpstreamUserMessage:
      name: upstreamUserMessage
      title: Upstream `message` for simple WebSocket clients (blocking)
      summary: |
        Blocking CloudEvents request fired for every WebSocket frame a
        *simple* (no subprotocol) client sends. The HTTP body is the
        raw payload the client sent. The upstream's response body, if
        any, is sent back to the client as a frame whose type follows
        the response `Content-Type` (`text/plain` => text frame,
        `application/octet-stream` => binary frame).
      contentType: application/octet-stream
      bindings:
        http:
          bindingVersion: '0.3.0'
          headers:
            $ref: '#/components/schemas/CloudEventsMessageHeaders'
      payload:
        $ref: '#/components/schemas/UpstreamUserMessagePayload'
    UpstreamUserCustomEvent:
      name: upstreamUserCustomEvent
      title: Upstream `<custom_event>` for PubSub clients (blocking)
      summary: |
        Blocking CloudEvents request fired when a PubSub subprotocol
        client sends a `type: event` frame. The CloudEvents
        `ce-type` is `azure.webpubsub.user.<event_name>` and the body
        is the `data` field of the original frame (text, JSON, or
        binary, depending on `dataType`).
      contentType: application/json
      bindings:
        http:
          bindingVersion: '0.3.0'
          headers:
            $ref: '#/components/schemas/CloudEventsCustomEventHeaders'
      payload:
        $ref: '#/components/schemas/UpstreamUserCustomEventPayload'
  schemas:
    DataType:
      type: string
      enum: [json, text, binary]
      description: |
        Encoding for the `data` field. `json` accepts any JSON value;
        `text` requires a string; `binary` requires a base64-encoded
        string.
    JoinGroupPayload:
      type: object
      required: [type, group]
      properties:
        type:
          type: string
          const: joinGroup
        group:
          type: string
          description: Name of the group to join.
        ackId:
          type: integer
          format: int64
          description: |
            Unique request identifier. If present, the service replies
            with an `ack` message carrying the same `ackId`.
    LeaveGroupPayload:
      type: object
      required: [type, group]
      properties:
        type:
          type: string
          const: leaveGroup
        group:
          type: string
          description: Name of the group to leave.
        ackId:
          type: integer
          format: int64
    SendToGroupPayload:
      type: object
      required: [type, group, data]
      properties:
        type:
          type: string
          const: sendToGroup
        group:
          type: string
          description: Target group name.
        ackId:
          type: integer
          format: int64
        noEcho:
          type: boolean
          default: false
          description: |
            If true, the publishing connection does not receive an echo
            of its own message.
        dataType:
          $ref: '#/components/schemas/DataType'
        data:
          description: |
            Payload to publish. Type depends on `dataType`: any JSON
            value for `json`, string for `text`, base64-encoded string
            for `binary`.
    SendEventPayload:
      type: object
      required: [type, event, data]
      properties:
        type:
          type: string
          const: event
        event:
          type: string
          description: |
            Custom event name. The service forwards this to the
            upstream webhook with `ce-type: azure.webpubsub.user.<event>`
            and `ce-eventName: <event>`.
        ackId:
          type: integer
          format: int64
        dataType:
          $ref: '#/components/schemas/DataType'
        data:
          description: |
            Event payload. Type depends on `dataType`.
    PingPayload:
      type: object
      required: [type]
      properties:
        type:
          type: string
          const: ping
    SequenceAckPayload:
      type: object
      required: [type, sequenceId]
      properties:
        type:
          type: string
          const: sequenceAck
        sequenceId:
          type: integer
          format: int64
          description: |
            Highest `sequenceId` the client has successfully processed
            from the service. Used by the reliable subprotocol so the
            service can release buffered messages.
    AckResponsePayload:
      type: object
      required: [type, ackId, success]
      properties:
        type:
          type: string
          const: ack
        ackId:
          type: integer
          format: int64
        success:
          type: boolean
        error:
          type: object
          description: Present when `success` is false.
          required: [name, message]
          properties:
            name:
              type: string
              enum: [Forbidden, InternalServerError, Duplicate]
            message:
              type: string
    MessageFromGroupPayload:
      type: object
      required: [type, from, group, data]
      properties:
        sequenceId:
          type: integer
          format: int64
          description: |
            Only present on the reliable subprotocol. Client must
            acknowledge using `sequenceAck`.
        type:
          type: string
          const: message
        from:
          type: string
          const: group
        group:
          type: string
        dataType:
          $ref: '#/components/schemas/DataType'
        data:
          description: Message payload (encoding follows `dataType`).
        fromUserId:
          type: string
          description: User id of the publisher, if any.
    MessageFromServerPayload:
      type: object
      required: [type, from, data]
      properties:
        sequenceId:
          type: integer
          format: int64
          description: Only present on the reliable subprotocol.
        type:
          type: string
          const: message
        from:
          type: string
          const: server
        dataType:
          $ref: '#/components/schemas/DataType'
        data:
          description: Message payload (encoding follows `dataType`).
    SystemConnectedPayload:
      type: object
      required: [type, event, connectionId]
      properties:
        type:
          type: string
          const: system
        event:
          type: string
          const: connected
        userId:
          type: string
          description: Authenticated user id of the connection, if any.
        connectionId:
          type: string
          description: Service-assigned unique connection id.
        reconnectionToken:
          type: string
          description: |
            Only present on the reliable subprotocol. Pass back as
            `awps_reconnection_token` (together with `awps_connection_id`)
            on a new connect request to recover this session.
    SystemDisconnectedPayload:
      type: object
      required: [type, event]
      properties:
        type:
          type: string
          const: system
        event:
          type: string
          const: disconnected
        message:
          type: string
          description: Human-readable disconnect reason.
    PongPayload:
      type: object
      required: [type]
      properties:
        type:
          type: string
          const: pong
    CloudEventsCommonHeaders:
      type: object
      description: |
        Common CloudEvents 1.0 binary-mode HTTP headers attached to
        every upstream request from Web PubSub. Additional event-type
        specific headers are documented per message.
      required:
        - ce-specversion
        - ce-type
        - ce-source
        - ce-id
        - ce-time
        - ce-signature
        - ce-connectionId
        - ce-hub
        - ce-eventName
        - WebHook-Request-Origin
      properties:
        WebHook-Request-Origin:
          type: string
          description: '`<instance>.webpubsub.azure.com`'
        ce-specversion:
          type: string
          const: '1.0'
        ce-type:
          type: string
          description: |
            Event type. `azure.webpubsub.sys.<connect|connected|disconnected>`
            for system events; `azure.webpubsub.user.message` for simple
            WebSocket frames; `azure.webpubsub.user.<event_name>` for
            PubSub subprotocol custom events.
        ce-source:
          type: string
          description: '`/hubs/{hub}/client/{connectionId}` (or `/client/{connectionId}` for custom events).'
        ce-id:
          type: string
          description: Unique event id.
        ce-time:
          type: string
          format: date-time
        ce-signature:
          type: string
          description: |
            `sha256={hash-primary},sha256={hash-secondary}` where each
            hash is `Hex(HMAC_SHA256(accessKey, connectionId))`.
            Upstream should validate before processing.
        ce-userId:
          type: string
        ce-connectionId:
          type: string
        ce-hub:
          type: string
        ce-eventName:
          type: string
          description: Event name without the `azure.webpubsub.*` prefix.
        ce-subprotocol:
          type: string
          description: Negotiated subprotocol, if any.
        ce-connectionState:
          type: string
          description: |
            Per-connection state propagated between events. Set by
            upstream on a previous blocking event response and echoed
            back on subsequent events.
    CloudEventsConnectHeaders:
      allOf:
        - $ref: '#/components/schemas/CloudEventsCommonHeaders'
        - type: object
          properties:
            ce-type:
              type: string
              const: azure.webpubsub.sys.connect
            ce-eventName:
              type: string
              const: connect
    CloudEventsConnectedHeaders:
      allOf:
        - $ref: '#/components/schemas/CloudEventsCommonHeaders'
        - type: object
          properties:
            ce-type:
              type: string
              const: azure.webpubsub.sys.connected
            ce-eventName:
              type: string
              const: connected
    CloudEventsDisconnectedHeaders:
      allOf:
        - $ref: '#/components/schemas/CloudEventsCommonHeaders'
        - type: object
          properties:
            ce-type:
              type: string
              const: azure.webpubsub.sys.disconnected
            ce-eventName:
              type: string
              const: disconnected
    CloudEventsMessageHeaders:
      allOf:
        - $ref: '#/components/schemas/CloudEventsCommonHeaders'
        - type: object
          properties:
            ce-type:
              type: string
              const: azure.webpubsub.user.message
            ce-eventName:
              type: string
              const: message
    CloudEventsCustomEventHeaders:
      allOf:
        - $ref: '#/components/schemas/CloudEventsCommonHeaders'
        - type: object
          properties:
            ce-type:
              type: string
              description: '`azure.webpubsub.user.<event_name>`'
              pattern: '^azure\.webpubsub\.user\..+$'
    UpstreamConnectPayload:
      type: object
      description: |
        Body of the `connect` upstream request. Carries the client's
        authentication context (claims), connect-time query string,
        request headers, requested subprotocols, and any client TLS
        certificates presented during the handshake.
      properties:
        claims:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Claims parsed from the client's access token.
        query:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Query string parameters from the connect request.
        headers:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: HTTP request headers from the connect request.
        subprotocols:
          type: array
          items:
            type: string
          description: |
            Subprotocols offered by the client in
            `Sec-WebSocket-Protocol`.
        clientCertificates:
          type: array
          description: Client TLS certificates, if any.
          items:
            type: object
            properties:
              thumbprint:
                type: string
                description: SHA-1 thumbprint of the certificate.
              content:
                type: string
                description: PEM-encoded certificate content.
    UpstreamEmptyJsonPayload:
      type: object
      description: Empty JSON object. The `connected` event carries no body fields.
    UpstreamDisconnectedPayload:
      type: object
      required: [reason]
      properties:
        reason:
          type: string
          description: Reason the client disconnected.
    UpstreamUserMessagePayload:
      description: |
        Raw client frame contents. The HTTP `Content-Type` is
        `text/plain` for text frames and `application/octet-stream` for
        binary frames.
      oneOf:
        - type: string
        - type: string
          format: binary
    UpstreamUserCustomEventPayload:
      description: |
        The `data` value from the original `type: event` frame. The
        HTTP `Content-Type` reflects the original `dataType`:
        `text/plain` for `text`, `application/json` for `json`,
        `application/octet-stream` for `binary`.
      oneOf:
        - type: string
        - type: object
          additionalProperties: true
        - type: array
          items: {}
        - type: number
        - type: boolean
        - type: 'null'
        - type: string
          format: binary