Matrix · AsyncAPI Specification

Matrix Client-Server Sync API

Version v3

AsyncAPI description of the Matrix Client-Server sync mechanism. Matrix delivers real-time events to clients through the `/_matrix/client/v3/sync` endpoint, which is a long-lived HTTPS GET request (HTTP long-polling). Clients open a request with a `since` continuation token and a server-side `timeout`; the homeserver holds the connection open until new events are available or the timeout elapses, then returns a JSON document describing incremental state and timeline changes. The `next_batch` value returned in each response is used as the `since` value on the next request to continue the stream. The official Matrix specification (v1.11) does NOT define a WebSocket or Server-Sent Events (SSE) transport for sync. The spec states: "The mandatory baseline for client-server communication in Matrix is exchanging JSON objects over HTTP APIs. More efficient transports may be specified in future as optional extensions." This AsyncAPI document therefore models only the documented HTTPS long-poll transport. Implementation-specific extensions such as MSC3575 Sliding Sync remain HTTP-based and are not modeled here. Event types covered by `/sync` include room timeline events (m.room.message, m.room.encrypted, m.room.member, m.room.redaction, m.reaction, m.room.name, m.room.topic, m.room.avatar), ephemeral events (m.typing, m.receipt), presence events (m.presence), to-device events, account data, and device-list / one-time-key updates relevant to end-to-end encryption.

View Spec View on GitHub MessagingDecentralizedFederatedOpen StandardReal-Time CommunicationVoIPAsyncAPIWebhooksEvents

Channels

/v3/sync
subscribe sync
Receive incremental sync updates over HTTPS long-poll
Long-polling sync channel. A client opens an authenticated HTTPS GET request to `/_matrix/client/v3/sync` with a `since` token and an optional `timeout` (milliseconds). The homeserver holds the connection open until at least one event is available for the client or until the timeout is reached, then responds with a JSON SyncResponse. The `next_batch` value is supplied as `since` on the subsequent request to resume the stream. Transport is explicitly HTTPS long-polling; the Matrix specification does not currently define a WebSocket or SSE alternative.

Messages

SyncResponse
Matrix /sync response
Incremental snapshot of new events and state for the calling user.

Servers

https
homeserver {homeserver}/_matrix/client
Matrix homeserver Client-Server API root. The sync endpoint is served over HTTPS using long-polling; the homeserver holds the request open until new events are available or the timeout elapses.

AsyncAPI Specification

matrix-sync-asyncapi.yml Raw ↑
asyncapi: 2.6.0
info:
  title: Matrix Client-Server Sync API
  version: v3
  description: >-
    AsyncAPI description of the Matrix Client-Server sync mechanism.

    Matrix delivers real-time events to clients through the `/_matrix/client/v3/sync`
    endpoint, which is a long-lived HTTPS GET request (HTTP long-polling). Clients
    open a request with a `since` continuation token and a server-side `timeout`;
    the homeserver holds the connection open until new events are available or the
    timeout elapses, then returns a JSON document describing incremental state and
    timeline changes. The `next_batch` value returned in each response is used as
    the `since` value on the next request to continue the stream.

    The official Matrix specification (v1.11) does NOT define a WebSocket or
    Server-Sent Events (SSE) transport for sync. The spec states: "The mandatory
    baseline for client-server communication in Matrix is exchanging JSON objects
    over HTTP APIs. More efficient transports may be specified in future as
    optional extensions." This AsyncAPI document therefore models only the
    documented HTTPS long-poll transport. Implementation-specific extensions such
    as MSC3575 Sliding Sync remain HTTP-based and are not modeled here.

    Event types covered by `/sync` include room timeline events (m.room.message,
    m.room.encrypted, m.room.member, m.room.redaction, m.reaction, m.room.name,
    m.room.topic, m.room.avatar), ephemeral events (m.typing, m.receipt),
    presence events (m.presence), to-device events, account data, and
    device-list / one-time-key updates relevant to end-to-end encryption.
  contact:
    name: Matrix.org Foundation
    url: https://matrix.org
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  externalDocs:
    description: Matrix Client-Server API specification
    url: https://spec.matrix.org/latest/client-server-api/#syncing
defaultContentType: application/json
servers:
  homeserver:
    url: '{homeserver}/_matrix/client'
    protocol: https
    description: >-
      Matrix homeserver Client-Server API root. The sync endpoint is served
      over HTTPS using long-polling; the homeserver holds the request open
      until new events are available or the timeout elapses.
    variables:
      homeserver:
        description: Fully qualified hostname of the Matrix homeserver.
        default: matrix.org
    security:
      - bearerAuth: []
      - accessTokenQuery: []
channels:
  /v3/sync:
    description: >-
      Long-polling sync channel. A client opens an authenticated HTTPS GET
      request to `/_matrix/client/v3/sync` with a `since` token and an
      optional `timeout` (milliseconds). The homeserver holds the connection
      open until at least one event is available for the client or until the
      timeout is reached, then responds with a JSON SyncResponse. The
      `next_batch` value is supplied as `since` on the subsequent request to
      resume the stream. Transport is explicitly HTTPS long-polling; the
      Matrix specification does not currently define a WebSocket or SSE
      alternative.
    bindings:
      http:
        type: request
        method: GET
        bindingVersion: 0.3.0
    parameters:
      timeout:
        description: >-
          Maximum time in milliseconds for the server to wait for events
          before responding. Default 0 (return immediately). Long-polling
          clients typically use 30000 ms.
        schema:
          type: integer
          format: int64
          minimum: 0
          default: 0
      since:
        description: >-
          Pagination token from a previous sync's `next_batch`. Omit on the
          initial sync to receive a snapshot.
        schema:
          type: string
      filter:
        description: >-
          Filter ID returned by `POST /v3/user/{userId}/filter`, or an inline
          JSON-encoded Filter object that limits which events the server
          returns.
        schema:
          type: string
      full_state:
        description: >-
          If true, all state events known to the server are returned even if
          `since` is non-empty. Default false.
        schema:
          type: boolean
          default: false
      set_presence:
        description: >-
          Presence state to set for the calling user for the duration of the
          request. One of `offline`, `online`, or `unavailable`. Default
          `online`.
        schema:
          type: string
          enum:
            - offline
            - online
            - unavailable
          default: online
      use_state_after:
        description: >-
          If true, the server returns room state at the END of the timeline
          (as `state_after`) rather than at the start (as `state`). Default
          false. Added in a recent client-server spec version.
        schema:
          type: boolean
          default: false
    subscribe:
      operationId: sync
      summary: Receive incremental sync updates over HTTPS long-poll
      description: >-
        Receives a SyncResponse describing all new events and state changes
        for the calling user since the supplied `since` token. The response
        is delivered as the body of the long-polled HTTPS GET request.
      bindings:
        http:
          bindingVersion: 0.3.0
      message:
        $ref: '#/components/messages/SyncResponse'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: opaque
      description: >-
        Homeserver-issued access token supplied as `Authorization: Bearer
        <access_token>`.
    accessTokenQuery:
      type: httpApiKey
      in: query
      name: access_token
      description: >-
        Legacy authentication mode that passes the access token as the
        `access_token` query parameter. Bearer header is preferred.
  messages:
    SyncResponse:
      name: SyncResponse
      title: Matrix /sync response
      summary: Incremental snapshot of new events and state for the calling user.
      contentType: application/json
      payload:
        $ref: '#/components/schemas/SyncResponse'
  schemas:
    SyncResponse:
      type: object
      required:
        - next_batch
      properties:
        next_batch:
          type: string
          description: Token to supply as `since` on the next sync request.
        rooms:
          $ref: '#/components/schemas/Rooms'
        presence:
          $ref: '#/components/schemas/PresenceUpdates'
        account_data:
          $ref: '#/components/schemas/AccountData'
        to_device:
          $ref: '#/components/schemas/ToDevice'
        device_lists:
          $ref: '#/components/schemas/DeviceLists'
        device_one_time_keys_count:
          type: object
          additionalProperties:
            type: integer
          description: >-
            Per-algorithm count of one-time keys the server currently holds
            for this device, used by E2EE clients to top up keys.
        device_unused_fallback_key_types:
          type: array
          items:
            type: string
          description: List of unused fallback key algorithms held by the server.
    Rooms:
      type: object
      properties:
        join:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/JoinedRoom'
          description: Rooms the user has joined, keyed by room ID.
        invite:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/InvitedRoom'
          description: Rooms the user has been invited to.
        knock:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/KnockedRoom'
          description: Rooms the user has knocked on.
        leave:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/LeftRoom'
          description: Rooms the user has left or been banned from.
    JoinedRoom:
      type: object
      properties:
        summary:
          $ref: '#/components/schemas/RoomSummary'
        state:
          $ref: '#/components/schemas/StateEvents'
        state_after:
          $ref: '#/components/schemas/StateEvents'
        timeline:
          $ref: '#/components/schemas/Timeline'
        ephemeral:
          $ref: '#/components/schemas/Ephemeral'
        account_data:
          $ref: '#/components/schemas/AccountData'
        unread_notifications:
          $ref: '#/components/schemas/UnreadNotificationCounts'
        unread_thread_notifications:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/UnreadNotificationCounts'
    InvitedRoom:
      type: object
      properties:
        invite_state:
          type: object
          properties:
            events:
              type: array
              items:
                $ref: '#/components/schemas/StrippedStateEvent'
    KnockedRoom:
      type: object
      properties:
        knock_state:
          type: object
          properties:
            events:
              type: array
              items:
                $ref: '#/components/schemas/StrippedStateEvent'
    LeftRoom:
      type: object
      properties:
        state:
          $ref: '#/components/schemas/StateEvents'
        state_after:
          $ref: '#/components/schemas/StateEvents'
        timeline:
          $ref: '#/components/schemas/Timeline'
        account_data:
          $ref: '#/components/schemas/AccountData'
    RoomSummary:
      type: object
      properties:
        m.heroes:
          type: array
          items:
            type: string
          description: Member user IDs used to summarize the room.
        m.joined_member_count:
          type: integer
        m.invited_member_count:
          type: integer
    StateEvents:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/ClientEvent'
    Timeline:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/ClientEvent'
        limited:
          type: boolean
          description: True if the server omitted events because the timeline was truncated.
        prev_batch:
          type: string
          description: Token for fetching earlier messages with `/messages`.
    Ephemeral:
      type: object
      description: >-
        Ephemeral events not stored in the room history. Includes typing and
        receipt events.
      properties:
        events:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/TypingEvent'
              - $ref: '#/components/schemas/ReceiptEvent'
    AccountData:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/AccountDataEvent'
    PresenceUpdates:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/PresenceEvent'
    ToDevice:
      type: object
      description: >-
        Direct device-to-device messages, primarily used by end-to-end
        encryption for key exchange (e.g. m.room_key, m.room_key_request,
        m.key.verification.*).
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/ToDeviceEvent'
    DeviceLists:
      type: object
      description: >-
        Lists of users whose device lists have changed since the last sync,
        used by E2EE clients to refetch device keys.
      properties:
        changed:
          type: array
          items:
            type: string
        left:
          type: array
          items:
            type: string
    UnreadNotificationCounts:
      type: object
      properties:
        highlight_count:
          type: integer
        notification_count:
          type: integer
    ClientEvent:
      type: object
      description: >-
        Generic Matrix client event envelope. The `type` field selects the
        concrete event schema; see specific event subtypes below.
      required:
        - type
        - event_id
        - sender
        - origin_server_ts
      properties:
        type:
          type: string
          description: >-
            Event type, e.g. `m.room.message`, `m.room.member`,
            `m.room.encrypted`, `m.room.redaction`, `m.reaction`,
            `m.room.name`, `m.room.topic`, `m.room.avatar`,
            `m.room.create`, `m.room.join_rules`, `m.room.power_levels`,
            `m.room.canonical_alias`, `m.room.history_visibility`,
            `m.room.guest_access`, `m.room.encryption`, `m.space.child`,
            `m.space.parent`.
        event_id:
          type: string
        sender:
          type: string
        origin_server_ts:
          type: integer
          format: int64
        room_id:
          type: string
        state_key:
          type: string
        content:
          type: object
        unsigned:
          type: object
          properties:
            age:
              type: integer
            redacted_because:
              type: object
            transaction_id:
              type: string
            prev_content:
              type: object
            replaces_state:
              type: string
      oneOf:
        - $ref: '#/components/schemas/RoomMessageEvent'
        - $ref: '#/components/schemas/RoomEncryptedEvent'
        - $ref: '#/components/schemas/RoomMemberEvent'
        - $ref: '#/components/schemas/RoomRedactionEvent'
        - $ref: '#/components/schemas/ReactionEvent'
        - $ref: '#/components/schemas/RoomNameEvent'
        - $ref: '#/components/schemas/RoomTopicEvent'
        - $ref: '#/components/schemas/RoomAvatarEvent'
    StrippedStateEvent:
      type: object
      description: Stripped state event used in invite_state and knock_state.
      required:
        - type
        - state_key
        - sender
        - content
      properties:
        type:
          type: string
        state_key:
          type: string
        sender:
          type: string
        content:
          type: object
    RoomMessageEvent:
      type: object
      description: m.room.message - a message posted in a room.
      properties:
        type:
          const: m.room.message
        content:
          type: object
          properties:
            msgtype:
              type: string
              description: >-
                One of m.text, m.emote, m.notice, m.image, m.file, m.audio,
                m.video, m.location.
            body:
              type: string
            format:
              type: string
            formatted_body:
              type: string
            url:
              type: string
            info:
              type: object
            'm.relates_to':
              type: object
    RoomEncryptedEvent:
      type: object
      description: m.room.encrypted - an end-to-end encrypted event payload.
      properties:
        type:
          const: m.room.encrypted
        content:
          type: object
          properties:
            algorithm:
              type: string
              description: e.g. m.megolm.v1.aes-sha2 or m.olm.v1.curve25519-aes-sha2.
            ciphertext:
              oneOf:
                - type: string
                - type: object
            sender_key:
              type: string
            device_id:
              type: string
            session_id:
              type: string
    RoomMemberEvent:
      type: object
      description: m.room.member - a membership change in a room.
      properties:
        type:
          const: m.room.member
        state_key:
          type: string
          description: The user ID whose membership is described.
        content:
          type: object
          properties:
            membership:
              type: string
              enum:
                - invite
                - join
                - knock
                - leave
                - ban
            displayname:
              type: string
            avatar_url:
              type: string
            reason:
              type: string
            is_direct:
              type: boolean
            third_party_invite:
              type: object
            join_authorised_via_users_server:
              type: string
    RoomRedactionEvent:
      type: object
      description: m.room.redaction - redacts another event.
      properties:
        type:
          const: m.room.redaction
        redacts:
          type: string
        content:
          type: object
          properties:
            reason:
              type: string
            redacts:
              type: string
    ReactionEvent:
      type: object
      description: >-
        m.reaction - an annotation/reaction event using an m.annotation
        relation to a target event.
      properties:
        type:
          const: m.reaction
        content:
          type: object
          properties:
            'm.relates_to':
              type: object
              properties:
                rel_type:
                  const: m.annotation
                event_id:
                  type: string
                key:
                  type: string
    RoomNameEvent:
      type: object
      description: m.room.name - updates the room's display name.
      properties:
        type:
          const: m.room.name
        content:
          type: object
          properties:
            name:
              type: string
    RoomTopicEvent:
      type: object
      description: m.room.topic - updates the room's topic.
      properties:
        type:
          const: m.room.topic
        content:
          type: object
          properties:
            topic:
              type: string
    RoomAvatarEvent:
      type: object
      description: m.room.avatar - updates the room's avatar.
      properties:
        type:
          const: m.room.avatar
        content:
          type: object
          properties:
            url:
              type: string
            info:
              type: object
    TypingEvent:
      type: object
      description: m.typing - ephemeral list of users currently typing in a room.
      properties:
        type:
          const: m.typing
        content:
          type: object
          properties:
            user_ids:
              type: array
              items:
                type: string
    ReceiptEvent:
      type: object
      description: >-
        m.receipt - read/private read/threaded read receipts for events in a
        room.
      properties:
        type:
          const: m.receipt
        content:
          type: object
          additionalProperties:
            type: object
            description: >-
              Keyed by event ID. Each value contains a map of receipt types
              (e.g. m.read, m.read.private, m.fully_read) to user receipt
              data.
    PresenceEvent:
      type: object
      description: m.presence - a presence update for a user.
      properties:
        type:
          const: m.presence
        sender:
          type: string
        content:
          type: object
          properties:
            presence:
              type: string
              enum:
                - online
                - offline
                - unavailable
            last_active_ago:
              type: integer
            status_msg:
              type: string
            currently_active:
              type: boolean
            displayname:
              type: string
            avatar_url:
              type: string
    AccountDataEvent:
      type: object
      description: >-
        Global or per-room account_data events. Types include
        m.fully_read, m.direct, m.push_rules, m.ignored_user_list,
        m.identity_server, m.tag, and m.secret_storage.*.
      properties:
        type:
          type: string
        content:
          type: object
    ToDeviceEvent:
      type: object
      description: >-
        Direct device-to-device event delivered via the to_device section of
        /sync. Common types: m.room_key, m.forwarded_room_key,
        m.room_key_request, m.key.verification.request,
        m.key.verification.start, m.key.verification.accept,
        m.key.verification.key, m.key.verification.mac,
        m.key.verification.done, m.key.verification.cancel,
        m.secret.request, m.secret.send, m.dummy.
      properties:
        type:
          type: string
        sender:
          type: string
        content:
          type: object