Using WebSockets to receive messages - Amazon Chime SDK

Using WebSockets to receive messages

You can use the Amazon Chime JS SDK to receive messages using WebSockets, or you can use the WebSocket client library of your choice.

Follow these topics in the order listed to start using WebSockets:

Defining an IAM policy

To start, define an IAM policy that gives you permission to establish a WebSocket connection. The following example policy gives an AppInstanceUser permission to establish a WebSocket connection.

"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action: [ "chime:Connect" ], "Resource": [ "arn:aws:chime:region:{aws_account_id}:app-instance/{app_instance_id}/user/{app_instance_user_id}" ] }, { "Effect": "Allow", "Action: [ "chime:GetMessagingSessionEndpoint" ], "Resource": [ "*" ] } ] }

Retrieving the endpoint

The following steps explain how to retrieve the endpoint used in a WebSocket connection.

  1. Use the GetMessagingSessionEndpoint API to retrieve the WebSocket endpoint.

  2. Use the URL returned by the GetMessagingSessionEndpoint API to construct a Signature Version 4 Signed WebSocket URL. If you need help doing that, you can follow directions in the Establishing the connection.


    WebSocket URLs have the following form:

Establishing the connection

After you retrieve an endpoint, you use the connect API to establish a WebSocket connection to the Amazon Chime SDK back-end server and receive messages for an AppInstanceUser. You must use AWS Signature Version 4 to sign requests. For more information about signing a request, see Signing AWS Requests with Signature Version 4.


To retrieve the endpoint, you can invoke the GetMessagingSessionEndpoint API. You can use the WebSocket client library of your choice to connect to the endpoint.

Request Syntax

GET /connect ?X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=AKIARALLEXAMPLE%2F20201214%2Fregion%2Fchime%2Faws4_request &X-Amz-Date=20201214T171359Z &X-Amz-Expires=10 &X-Amz-SignedHeaders=host &sessionId={sessionId} &userArn={appInstanceUserArn} &X-Amz-Signature=db75397d79583EXAMPLE

URI Request Parameters

All URI Request Query Parameters must be URL Encoded.


Identifies the version of AWS Signature and the algorithm that you used to calculate the signature. The Amazon Chime SDK supports only AWS Signature Version 4 authentication, so the value of this is AWS4-HMAC-SHA256.


In addition to your access key ID, this parameter also provides the AWS Region and service—the scope—for which the signature is valid. This value must match the scope you use in signature calculations. The general form for this parameter value is:

<yourAccessKeyId>/<date>/<awsRegion>/<awsService >/aws4_request

For example:



The date and time format must follow the ISO 8601 standard, and you must format it as yyyyMMddTHHmmssZ. For example, you must convert 08/01/2020 15:32:41.982-700 to Coordinated Universal Time (UTC) and submit it as 20200801T083241Z.


Lists the headers that you used to calculate the signature. The following headers are required in the signature calculations:

  • The HTTP host header.

  • Any x-amz-* headers that you plan to add to the request.


For added security, sign all the request headers that you plan to include in your request.


Provides the signature to authenticate your request. This signature must match the signature that Amazon Chime SDK calculates. If it doesn't, Amazon Chime SDK denies the request. For example, 733255ef022bec3f2a8701cd61d4b371f3f28c9f19EXAMPLEd48d5193d7.


Optional credential parameter if using credentials sourced from the Security Token Service. For more information about the service, see the


Indicates a unique Id for the WebSocket connection being established.


Indicates the identity of the AppInstanceUser trying to establish a connection. The value should be the ARN of the AppInstanceUser. For example, arn:aws:chime:us%2Deast%2D1:123456789012:app%2Dinstance/694d2099%2Dcb1e%2D463e%2D9d64%2D697ff5b8950e/user/johndoe

Using prefetch to deliver channel details

When you establish a WebSocket connection, you can specify prefetch-on=connect in your query parameters to deliver CHANNEL_DETAILS events. The prefetch feature comes with the connect API, and the feature enables users to see an enriched chat view without extra API calls. Users can:

  • See a preview of the last channel message, plus its timestamp.

  • See the members of a channel.

  • See a channel's unread markers.

After a user connects with the prefetch parameter specified, the user receives the session established event, which indicates the connection has been established. The user then receives up to 50 CHANNEL_DETAILS events. If the user has less than 50 channels, the connect API prefetches all channels via CHANNEL_DETAILS events. If user has more than 50 channels, the API prefetches the top 50 channels that contain unread messages and the latest LastMessageTimestamp values. The CHANNEL_DETAILS events arrive in random order, and you receive events for all 50 channels.

Also, prefetch returns the following for ChannelMessages and ChannelMemberships:

  • ChannelMessages – List of ChannelMessageSummary objects, ordered by CreatedTimestamp in descending order. Only includes the latest 20 messages visible to the user. If there are targeted messages in the channel that are not visible to the current user, then less than 20 messages might be returned. The ChannelMessagesHasMore boolean will be set to true to indicate there are more messages. Soft limit, adjustable at the AWS account level.

  • ChannelMemberships – List of ChannelMembershipSummary objects. Includes a maximum of 30 channel members. Soft limit, adjustable at AWS account level.

This example shows how to use prefetch-on=connect.

GET /connect ?X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=AKIARALLEXAMPLE%2F20201214%2Fregion%2Fchime%2Faws4_request &X-Amz-Date=20201214T171359Z &X-Amz-Expires=10 &X-Amz-SignedHeaders=host &sessionId=sessionId &prefetch-on=connect &userArn=appInstanceUserArn &X-Amz-Signature=db75397d79583EXAMPLE

This example shows the response for one channel. You will receive responses for all 50 channels.

{ "Headers": { "x-amz-chime-event-type": "CHANNEL_DETAILS", "x-amz-chime-message-type": "SYSTEM" }, "Payload": JSON.stringify"({ Channel: ChannelSummary ChannelMessages: List of ChannelMessageSummary ChannelMemberships: List of ChannelMembershipSummary ReadMarkerTimestamp: Timestamp ChannelMessagesHasMore: Boolean }) }

Processing the events

For an AppInstanceUser to receive messages after they establish a connection, you must add them to a channel. To do that, use the CreateChannelMembership API.


An AppInstanceUser always receives messages for all channels that they belong to. Messaging stops when the AppInstance user disconnects.

An AppInstanceAdmin and a ChannelModerator do not receive messages on a channel unless you use the CreateChannelMembership API to explicitly add them.

The following topics explain how to process events.

Understanding message structures

Every WebSocket message that you receive adheres to this format:

{ "Headers": {"key": "value"}, "Payload": "{\"key\": \"value\"}" }

Amazon Chime SDK messaging use the following header keys:

  • x-amz-chime-event-type

  • x-amz-chime-message-type

  • x-amz-chime-event-reason

The next section lists and describes the header's possible values and payloads.


Websocket messages return JSON strings. The structure of the JSON strings depends on the x-amz-event-type headers. The following table lists the possible x-amz-chime-event-type values and payloads:

EventType Payload format


N/A. This message is sent once after the user connects to the WebSocket. It indicates that any message or event on a channel that arrives after the user receives the SESSION_ESTABLISHED message is guaranteed to be delivered to the user as long as the WebSocket stays open.














The ChannelSummary object.


List of ChannelMessageSummary objects, ordered by CreatedTimestamp in descending order. Includes the latest 20 messages, but you can adjust that limit at the AWS account level.


List of ChannelMembershipSummary objects. Returns a maximum of 30 channel members, but you can adjust that limit at the AWS account level.


The time at which the AppInstanceUser last marked the channel as read.











The following table lists the x-amz-chime-message-type message types .

Message type Description


Sent when the websocket receives a STANDARD channel message.


Sent when the WebSocket receives a CONTROL channel message.


All other websocket messages sent by Amazon Chime SDK Messaging.


This is an optional header supported for a specific use case. The header provides information about why a specific event was received.

Event reason Description


DELETE_CHANNEL_MEMBERSHIP events received by elastic channel moderators. Only seen by moderators after membership balancing deletes a sub-channel that they belonged to.

Handling disconnects

Websockets can disconnect due to changes in network connectivity, or when credentials expire. After you open a WebSocket, the Amazon Chime SDK sends regular pings to the messaging client to ensure it is still connected. If the connection closes, the client receives a WebSocket close code. The client can try to reconnect, or not, depending on the close code. The following tables show the close codes that the client can use to reconnect.

For 1000 to 4000 closure codes, reconnect only for the following messages:

Closure codes

Can reconnect




Normal closure



Abnormal closure



Internal server error



Service restart



Try again later



The server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to the 502 HTTP Status Code.

For 4XXX codes, always reconnect except for the following messages:

Closure codes

Can reconnect




Client initiated






Not authorized

When the application uses a close code to reconnect, the application should:

  1. Call the GetMessagingSessionEndpoint API again to obtain a new base URL.

  2. Refresh the IAM credentials if they've expired.

  3. Connect via the WebSocket.

If you use the amazon-chime-sdk-js library, this is handled for you if you implement the needsRefresh() property and the refresh() method. For a working example, see