Stream · AsyncAPI Specification

Stream Chat Realtime WebSocket API

Version 1.0.0

AsyncAPI 2.6 description of Stream (GetStream.io) Chat's **real-time WebSocket** surface. Unlike the request/response server-side REST API (`https://chat.stream-io-api.com`, modeled in `openapi/getstream-openapi.yml`), Stream's client SDKs establish a persistent, bidirectional **WebSocket** connection to receive real-time chat events. Per Stream's official docs (getstream.io/chat/docs), every client-side chat integration opens a WebSocket connection via `client.connectUser()`; the connection is how devices receive real-time events. Stream limits the number of open connections per user to 50 in production and 3 in development. ## How the connection is opened A client connects by opening a WebSocket to `wss://chat.stream-io-api.com/connect` with the connection payload and credentials passed as query parameters: - `json` - a URL-encoded JSON object containing `user_details` (at minimum the `id`) and `user_token`. - `api_key` - the application API key. - `authorization` - the user's JWT. - `stream-auth-type` - the literal string `jwt`. On a successful handshake the server immediately emits a `health.check` event carrying a `connection_id`; this same event is re-sent periodically as a heartbeat to keep the socket alive. Thereafter the server pushes chat events (message.new, typing.start, reaction.new, notification.*, user.presence.changed, and others) for the channels the user is watching. The client sends `health.check` events back as keep-alives. Event names and fields are taken from Stream's documented event object (getstream.io/chat/docs/node/event_object).

View Spec View on GitHub ChatMessagingActivity FeedsVideoAudioModerationWebSocketReal TimeAsyncAPIWebhooksEvents

Channels

/connect
publish sendKeepAlive
Send keep-alive events to Stream.
The single multiplexed WebSocket channel. After the handshake, the server pushes all real-time events for the connected user across every channel they watch, and the client publishes keep-alive `health.check` events.

Messages

HealthCheck
Health check / connection heartbeat
Connection keep-alive; the first one carries the connection_id.
MessageNew
New message
A new message was sent to a channel the user watches.
MessageUpdated
Message updated
MessageDeleted
Message deleted
MessageRead
Channel marked read
A user marked a channel read; unread counts changed.
ReactionNew
New reaction
TypingStart
Typing started
TypingStop
Typing stopped
UserPresenceChanged
User presence changed
A watched user's online/offline presence changed.
UserWatchingStart
User started watching a channel
NotificationMessageNew
Notification - new message
A new message arrived in a channel the user is a member of but is not currently watching.
NotificationAddedToChannel
Notification - added to a channel

Servers

wss
production chat.stream-io-api.com
Stream Chat real-time WebSocket edge. The client opens `wss://chat.stream-io-api.com/connect?json={payload}&api_key={key}&authorization={jwt}&stream-auth-type=jwt`.

AsyncAPI Specification

Raw ↑
asyncapi: '2.6.0'
id: 'urn:io:getstream:chat:websocket'
info:
  title: Stream Chat Realtime WebSocket API
  version: '1.0.0'
  description: |
    AsyncAPI 2.6 description of Stream (GetStream.io) Chat's **real-time
    WebSocket** surface. Unlike the request/response server-side REST API
    (`https://chat.stream-io-api.com`, modeled in
    `openapi/getstream-openapi.yml`), Stream's client SDKs establish a
    persistent, bidirectional **WebSocket** connection to receive real-time chat
    events.

    Per Stream's official docs (getstream.io/chat/docs), every client-side chat
    integration opens a WebSocket connection via `client.connectUser()`; the
    connection is how devices receive real-time events. Stream limits the number
    of open connections per user to 50 in production and 3 in development.

    ## How the connection is opened
    A client connects by opening a WebSocket to `wss://chat.stream-io-api.com/connect`
    with the connection payload and credentials passed as query parameters:

    - `json` - a URL-encoded JSON object containing `user_details` (at minimum
      the `id`) and `user_token`.
    - `api_key` - the application API key.
    - `authorization` - the user's JWT.
    - `stream-auth-type` - the literal string `jwt`.

    On a successful handshake the server immediately emits a `health.check` event
    carrying a `connection_id`; this same event is re-sent periodically as a
    heartbeat to keep the socket alive. Thereafter the server pushes chat events
    (message.new, typing.start, reaction.new, notification.*, user.presence.changed,
    and others) for the channels the user is watching. The client sends `health.check`
    events back as keep-alives.

    Event names and fields are taken from Stream's documented event object
    (getstream.io/chat/docs/node/event_object).
  contact:
    name: API Evangelist
    email: kin@apievangelist.com
    url: https://apievangelist.com
  license:
    name: API documentation - Stream Terms
    url: https://getstream.io/legal/terms/
  x-transport-notes:
    transport: WebSocket
    protocol: wss
    endpoint: 'wss://chat.stream-io-api.com/connect'
    direction: bidirectional
    openedBy: 'client.connectUser() in the Stream Chat SDKs'
    heartbeat: 'health.check events, sent both by server and client'
    connectionLimit: '50 concurrent connections per user in production, 3 in development'
    source: https://getstream.io/chat/docs/node/event_object/
defaultContentType: application/json
servers:
  production:
    url: chat.stream-io-api.com
    protocol: wss
    description: |
      Stream Chat real-time WebSocket edge. The client opens
      `wss://chat.stream-io-api.com/connect?json={payload}&api_key={key}&authorization={jwt}&stream-auth-type=jwt`.
    security:
      - jwtUser: []
channels:
  /connect:
    description: |
      The single multiplexed WebSocket channel. After the handshake, the server
      pushes all real-time events for the connected user across every channel
      they watch, and the client publishes keep-alive `health.check` events.
    bindings:
      ws:
        bindingVersion: '0.1.0'
        query:
          type: object
          properties:
            json:
              type: string
              description: URL-encoded JSON with user_details and user_token.
            api_key:
              type: string
              description: Application API key.
            authorization:
              type: string
              description: The user JWT.
            stream-auth-type:
              type: string
              enum:
                - jwt
    subscribe:
      operationId: receiveEvents
      summary: Receive real-time chat events pushed by Stream.
      description: |
        Events the server pushes to the connected client over the WebSocket.
        Each event is a JSON object with at least a `type` field; many also carry
        `cid`, `user`, `message`, `reaction`, `channel`, `watcher_count`, and
        `total_unread_count`.
      message:
        oneOf:
          - $ref: '#/components/messages/HealthCheck'
          - $ref: '#/components/messages/MessageNew'
          - $ref: '#/components/messages/MessageUpdated'
          - $ref: '#/components/messages/MessageDeleted'
          - $ref: '#/components/messages/MessageRead'
          - $ref: '#/components/messages/ReactionNew'
          - $ref: '#/components/messages/TypingStart'
          - $ref: '#/components/messages/TypingStop'
          - $ref: '#/components/messages/UserPresenceChanged'
          - $ref: '#/components/messages/UserWatchingStart'
          - $ref: '#/components/messages/NotificationMessageNew'
          - $ref: '#/components/messages/NotificationAddedToChannel'
    publish:
      operationId: sendKeepAlive
      summary: Send keep-alive events to Stream.
      description: |
        The client periodically publishes a `health.check` event to keep the
        WebSocket connection alive.
      message:
        $ref: '#/components/messages/HealthCheck'
components:
  securitySchemes:
    jwtUser:
      type: httpApiKey
      in: query
      name: authorization
      description: |
        The user JWT passed as the `authorization` query parameter, alongside
        `stream-auth-type=jwt` and the application `api_key`.
  messages:
    HealthCheck:
      name: health.check
      title: Health check / connection heartbeat
      summary: Connection keep-alive; the first one carries the connection_id.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/HealthCheckEvent'
      examples:
        - name: firstHealthCheck
          summary: First event after handshake, carrying connection_id
          payload:
            type: health.check
            connection_id: 8a3b2c1d-1234-5678-9abc-def012345678
            created_at: '2026-07-03T12:00:00Z'
            me:
              id: john
              role: user
              online: true
    MessageNew:
      name: message.new
      title: New message
      summary: A new message was sent to a channel the user watches.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
      examples:
        - name: messageNew
          payload:
            type: message.new
            cid: messaging:general
            channel_id: general
            channel_type: messaging
            user:
              id: john
            message:
              id: 8f2a1b3c
              text: Hello everyone
              type: regular
            watcher_count: 5
            created_at: '2026-07-03T12:00:01Z'
    MessageUpdated:
      name: message.updated
      title: Message updated
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    MessageDeleted:
      name: message.deleted
      title: Message deleted
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    MessageRead:
      name: message.read
      title: Channel marked read
      summary: A user marked a channel read; unread counts changed.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    ReactionNew:
      name: reaction.new
      title: New reaction
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
      examples:
        - name: reactionNew
          payload:
            type: reaction.new
            cid: messaging:general
            user:
              id: jane
            message:
              id: 8f2a1b3c
            reaction:
              type: like
              score: 1
            created_at: '2026-07-03T12:00:02Z'
    TypingStart:
      name: typing.start
      title: Typing started
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    TypingStop:
      name: typing.stop
      title: Typing stopped
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    UserPresenceChanged:
      name: user.presence.changed
      title: User presence changed
      summary: A watched user's online/offline presence changed.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    UserWatchingStart:
      name: user.watching.start
      title: User started watching a channel
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    NotificationMessageNew:
      name: notification.message_new
      title: Notification - new message
      summary: >-
        A new message arrived in a channel the user is a member of but is not
        currently watching.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
    NotificationAddedToChannel:
      name: notification.added_to_channel
      title: Notification - added to a channel
      contentType: application/json
      payload:
        $ref: '#/components/schemas/Event'
  schemas:
    HealthCheckEvent:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - health.check
        connection_id:
          type: string
          description: The id assigned to this WebSocket connection. Present on the first event.
        created_at:
          type: string
          format: date-time
        me:
          $ref: '#/components/schemas/OwnUser'
    Event:
      type: object
      description: |
        The generic Stream Chat event envelope. `type` is always present; the
        other fields appear depending on the event type, per
        getstream.io/chat/docs/node/event_object.
      required:
        - type
      properties:
        type:
          type: string
          description: The event type, e.g. message.new, typing.start, reaction.new.
        cid:
          type: string
          description: The channel id in "{type}:{id}" form.
        channel_id:
          type: string
        channel_type:
          type: string
        message:
          $ref: '#/components/schemas/Message'
        reaction:
          $ref: '#/components/schemas/Reaction'
        user:
          $ref: '#/components/schemas/User'
        member:
          type: object
        channel:
          type: object
        watcher_count:
          type: integer
        total_unread_count:
          type: integer
        unread_channels:
          type: integer
        created_at:
          type: string
          format: date-time
    Message:
      type: object
      properties:
        id:
          type: string
        text:
          type: string
        type:
          type: string
        user:
          $ref: '#/components/schemas/User'
        parent_id:
          type: string
        created_at:
          type: string
          format: date-time
    Reaction:
      type: object
      properties:
        type:
          type: string
        score:
          type: integer
        user_id:
          type: string
        message_id:
          type: string
    User:
      type: object
      properties:
        id:
          type: string
        role:
          type: string
        online:
          type: boolean
        name:
          type: string
        image:
          type: string
        last_active:
          type: string
          format: date-time
    OwnUser:
      allOf:
        - $ref: '#/components/schemas/User'
        - type: object
          properties:
            total_unread_count:
              type: integer
            unread_channels:
              type: integer
            devices:
              type: array
              items:
                type: object