Chat and conversation management for an Amazon Q Business application using APIs - Amazon Q Business

Chat and conversation management for an Amazon Q Business application using APIs

Chatting in an Amazon Q Business web experience preview and a deployed Amazon Q Business web experience uses the following API operations.

Important

Amazon Q Business Chat and ChatSync APIs are intended to be activated by end user interactions, not programmatic access. To protect availability, requests exceeding normal user patterns may be throttled. If throttling occurs, first wait and retry later as it is often temporary. However, if throttling persists—or if you believe the throttling is in error—contact AWS Support for troubleshooting assistance.

API action API description Relevant User Guide topic
Chat Starts or continues a streaming Amazon Q Business conversation
ChatSync Starts or continues a non-streaming Amazon Q Business conversation
DeleteConversation Deletes an Amazon Q Business web experience conversation Conversation management
ListConversations Lists conversations in an Amazon Q Business web experience Conversation management
ListMessages Lists messages in an Amazon Q Business web experience Using Amazon Q Business web experiences

This section outlines how to use Amazon Q Business APIs to make authenticated API calls, and how to configure a streaming chat conversation.

Setting up a streaming Amazon Q Business chat using APIs

Amazon Q Business provides a streaming Chat API that you can use to deliver chat responses to your end users as a continuing series of partial results. When you use the streaming API, chat responses are transmitted using sequential data packets.

You can configure streaming for your Amazon Q Business application environment in two ways: using WebSockets directly, or using an AWS SDK. The information in this section can be used to for both methods.

If you use WebSockets to configure streaming, a secure WebSockets connection is created to a supported Amazon Q Business endpoint over port 8443. An example endpoint may look like this: wss://qbusiness.us-west-2.api.aws:8443/chat.

To ensure that your application environment can successfully establish a WebSockets connection, you must ensure that port 8443 is enabled and not blocked by network rules you have configured at the router, VPN, VPC, or firewall level.

Important

We strongly recommend using SDKs to configure streaming instead of using WebSockets directly. SDKs are the simplest and most reliable method for chat streams. To start streaming using an AWS SDK, see Chat in the Amazon Q Business API Reference.

Setting up a WebSocket stream

The key components for a WebSocket protocol for streaming requests with Amazon Q Business are:

  • The upgrade request. This contains the query parameters for your request, and a signature that Amazon Q Business uses as a seed signature.

  • One or more messages in event stream encoding that contain metadata and chat bytes.

The following section outlines the steps to set up your WebSocket stream.

  1. Attach the following policy to the IAM role that makes the request. See Adding IAM policies for more information.

    { "Version": "2012-10-17", "Statement": [ { "Sid": "my-qbusiness-websocket-policy", "Effect": "Allow", "Action": "qbusiness:Chat", "Resource": "*" } ] }
  2. To start the session, create a presigned URL in the following format. Line breaks have been added for readability.

    GET wss://qbusiness.us-west-2.api.aws:8443/chat? &X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=access-key%2FYYYYMMDD%2Fus-west-2%2Fqbusiness%2Faws4_request &X-Amz-Date=YYYYMMDDTHHMMSSZ &X-Amz-Expires=300 &X-Amz-Security-Token=security-token &X-Amz-Signature=string &X-Amz-SignedHeaders=host &chat-input={"applicationId":"application_id","userId":"test_user@amazon.com","userGroups":null,"clientToken":str(uuid.uuid4())}
    Note

    The maximum value for X-Amz-Expires is 300 seconds (5 minutes).

    Additional operations and parameters are listed in the API Reference; parameters common to all AWS API operations are listed in the Common Parameters section.

    To construct the URL for your request and create the Signature Version 4 signature, refer to the following steps. Examples are in pseudocode.

    1. Create a canonical request. A canonical request is a string that includes information from your request in a standardized format. This ensures that when AWS receives the request, it can calculate the same signature you created for your URL. For more information, see Create a Canonical Request for Signature Version 4.

      # HTTP verb method = "GET" # Service name service = "qbusiness" # Region region = "us-west-2" # Amazon Q Business streaming endpoint endpoint = "wss://qbusiness.us-west-2.amazonaws.com:8443" # Host host = "qbusiness.us-west-2.amazonaws.com:8443" # Date and time of request amz-date = YYYYMMDDTHHMMSSZ # Date without time for credential scope datestamp = YYYYMMDD
    2. Create a canonical URI, which is the part of the URI between the domain and the query string.

      canonical_uri = "/chat"
    3. Create the canonical headers and signed headers. Note the trailing \n in the canonical headers.

      • Append the lowercase header name followed by a colon ( : ).

      • Append a comma-separated list of values for that header. Do not sort values in headers that have multiple values.

      • Append a new line (\n).

      canonical_headers = "host:" + host + "\n" signed_headers = "host"
    4. Match the algorithm to the hashing algorithm. Use SHA-256.

      algorithm = "AWS4-HMAC-SHA256"
    5. Create the credential scope, which scopes the derived key to the date, AWS Region, and service. For example, 20240415/us-west-2/qbusiness/aws4_request.

      credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
    6. Create the canonical query string. Query string values must be URI-encoded and sorted by name.

      • Sort the parameter names by character code point in ascending order. Parameters with duplicate names should be sorted by value. For example, a parameter name that begins with the uppercase letter F precedes a parameter name that begins with the lowercase letter b.

      • Do not URI-encode any of the unreserved characters that RFC 3986 defines: A-Z, a-z, 0-9, hyphen ( - ), underscore ( _ ), period ( . ), and tilde ( ~ ).

      • Percent-encode all other characters with %XY, where X and Y are hexadecimal characters (0-9 and uppercase A-F). For example, the space character must be encoded as %20 (don't include '+', as some encoding schemes do); extended UTF-8 characters must be in the form %XY%ZA%BC.

      • Double-encode any equals ( = ) characters in parameter values.

      canonical_querystring = "X-Amz-Algorithm=" + algorithm canonical_querystring += "&X-Amz-Credential="+ access key + "%2F" + credential_scope canonical_querystring += "&X-Amz-Date=" + amz_date canonical_querystring += "&X-Amz-Expires=300" canonical_querystring += "&X-Amz-Security-Token=" + URI-Encode(token, 'UTF-8', safe='') canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers chat_input_string = { "applicationId": "application_id", "userId": "testuser@amazon.com", "userGroups": None, "clientToken": str(uuid.uuid4()), "conversationId": None, "parentMessageId": None } canonical_querystring += "&" + "chat-input" + "=" + URI-Encode(json.dumps(chat_input_string), 'UTF-8')
    7. Create a hash of the payload. For a GET request, the payload is an empty string.

      payload_hash = HashSHA256(("").Encode("utf-8")).Digest()
    8. Combine the following elements to create the canonical request.

      canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash string_to_sign = algorithm + '\n' + amz_date + '\n' + new_credential_scope + '\n' + hashed_canonical_request
  3. Create the string to sign, which contains meta information about your request. You use the string to sign in the next step when you calculate the request signature. For more information, see Create a String to Sign for Signature Version 4.

    hashed_canonical_request = HashSHA256(canonical_request.Encode("utf-8")).HexDigest() new_credential_scope = datestamp + '/' + region + '/qbusiness/aws4_request' string_to_sign=algorithm + "\n" + amz_date + "\n" + new_credential_scope + "\n" + HashSHA256(canonical_request.Encode("utf-8")).HexDigest()
  4. Calculate the signature. To do this, derive a signing key from your AWS secret access key. For a greater degree of protection, the derived key is specific to the date, service, and AWS Region. Use this derived key to sign the request. For more information, see Calculate the Signature for AWS Signature Version 4.

    Make sure you implement the GetSignatureKey function to derive your signing key. If you have not yet derived a signing key, refer to Examples of how to derive a signing key for Signature Version 4.

    #Create the signing key signing_key = GetSignatureKey(secret_key, datestamp, region, service) # Sign the string_to_sign using the signing key signature = HMAC.new(signing_key, (string_to_sign).Encode("utf-8"), Sha256()).HexDigest

    The function HMAC(key, data) represents an HMAC-SHA256 function that returns results in binary format.

  5. Add signing information to the request and create the request URL.

    After you calculate the signature, add it to the query string. For more information, see Add the Signature to the Request.

    First, add the authentication information to the query string.

    canonical_querystring += "&X-Amz-Signature=" + signature

    Second, create the URL for the request.

    request_url = endpoint + canonical_uri + "?" + canonical_querystring

    Use the request URL with your WebSocket library to make the request to Amazon Q Business.

  6. The request to Amazon Q Business must include the following headers. Typically these headers are managed by your WebSocket client library.

    Host: qbusiness.us-west-2.amazonaws.com:8443 Connection: Upgrade Upgrade: websocket Origin: URI-of-WebSocket-client Sec-WebSocket-Version: 13 Sec-WebSocket-Key: randomly-generated-string <calculated at runtime>
  7. When Amazon Q Business receives your WebSocket request, it responds with a WebSocket upgrade response. Typically your WebSocket library manages this response and sets up a socket for communications with Amazon Q Business.

    The following is the response from Amazon Q Business. Line breaks have been added for readability.

    HTTP/1.1 101 WebSocket Protocol Handshake Connection: upgrade Upgrade: websocket websocket-origin: wss://qbusiness.us-west-2.amazonaws.com:8443 websocket-location: qbusiness.us-west-2.amazonaws.com:8443/chat? &X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=access-key%2FYYYYMMDD%2Fus-west-2%2Fqbusiness%2Faws4_request &X-Amz-Date=YYYYMMDDTHHMMSSZ &X-Amz-Expires=300 &X-Amz-Security-Token=security_token &X-Amz-SignedHeaders=host &chat-input=%7B%22applicationId%22%3A%20%22aa419bef-ac4e-4c57-9224-f603e185ac09%22%2C%20%22userId%22%3A%20%testuser%40amazon.com%22%2C%20%22userGroups%22%3A%20null%2C%20%22clientToken%22%3A%20%2283eb07d9-193c-420c-97c6-f2f343d13591%22%2C%20%22conversationId%22%3A%20null%2C%20%22parentMessageId%22%3A%20null%7D &X-Amz-Signature=Signature Version 4 signature x-amzn-RequestId: RequestId sec-websocket-accept: hash-of-the-Sec-WebSocket-Key-header
  8. Make your WebSocket streaming request.

    After the WebSocket connection is established, the client can start sending a sequence of chat frames, each encoded using event stream encoding.

    Each data frame contains three headers combined with a chunk of raw text bytes; the following table describes these headers.

    Header name byte length Header name (string) Header value type Value string byte length Value string (UTF-8)
    13 :content-type 7 24 application/json
    11 :event-type 7 10 textEvent
    13 :message-type 7 5 event
  9. To end the data stream, send an end of input event in an event stream encoded message.

    Header name byte length Header name (string) Header value type Value string byte length Value string (UTF-8)
    13 :content-type 7 16 application/json
    11 :event-type 7 15 endOfInputEvent
    13 :message-type 7 5 event

    When you decode the binary response, you end up with a JSON structure containing the chat output.

Handling WebSocket streaming errors

If an exception occurs while processing your request, Amazon Q Business responds with a terminal WebSocket frame containing an event stream encoded response. This response contains the headers described in the following table; the body of the response contains a descriptive error message.

Header name byte length Header name (string) Header value type Value string byte length Value string (UTF-8)
13 :content-type 7 16 application/json
15 :exception-type 7 varies varies, see below
13 :message-type 7 9 exception

The exception-type header contains one of the following values:

  • BadRequestException: There was a client error when the stream was created, or an error occurred while streaming data. Make sure that your client is ready to accept data and try your request again.

  • InternalFailureException: Amazon Q Business had a problem during the handshake with the client. Try your request again.

Amazon Q Business can also return any of the common service errors. For a list, see Common Errors.

Event stream encoding

Amazon Q Business uses a format called event stream encoding for streaming chat.

Event stream encoding provides bidirectional communication between a client and a server. Chats sent to the Amazon Q Business service are encoded in this format. The response from Amazon Q Business also uses this encoding.

Each message consists of two sections: the prelude and the data. The prelude consists of:

  1. The total byte length of the message

  2. The combined byte length of all headers

The data section consists of:

  1. Headers

  2. Payload

Each section ends with a 4-byte big-endian integer cyclic redundancy check (CRC) checksum. The message CRC checksum is for both the prelude section and the data section. Amazon Q Business uses CRC32 (often referred to as GZIP CRC32) to calculate both CRCs. For more information about CRC32, see GZIP file format specification version 4.3.

Total message overhead, including the prelude and both checksums, is 16 bytes.

The following diagram shows the components that make up a message and a header. There are multiple headers per message.

A schematic of the components of a message and a header for a streaming transcription.

Each message contains the following components:

  • Prelude: Consists of two, 4-byte fields, for a fixed total of 8 bytes.

    • First 4 bytes: The big-endian integer byte-length of the entire message, inclusive of this 4-byte length field.

    • Second 4 bytes: The big-endian integer byte-length of the 'headers' portion of the message, excluding the 'headers' length field itself.

  • Prelude CRC: The 4-byte CRC checksum for the prelude portion of the message, excluding the CRC itself. The prelude has a separate CRC from the message CRC. That ensures that Amazon Q Business can detect corrupted byte-length information immediately without causing errors, such as buffer overruns.

  • Headers: Metadata annotating the message; for example, message type and content type. Messages have multiple headers, which are key:value pairs, where the key is a UTF-8 string. Headers can appear in any order in the 'headers' portion of the message, and each header can appear only once.

  • Payload: The streaming chat content to be transcribed.

  • Message CRC: The 4-byte CRC checksum from the start of the message to the start of the checksum. That is, everything in the message except the CRC itself.

The header frame is the authorization frame for the streaming chat. Amazon Q Business uses the authorization header's value as the seed for generating a chain of authorization headers for the data frames in the request.

Each header contains the following components; there are multiple headers per frame.

  • Header name byte-length: The byte-length of the header name.

  • Header name: The name of the header that indicates the header type. For valid values, see the following frame descriptions.

  • Header value type: A number indicating the header value. The following list shows the possible values for the header and what they indicate.

    • 0 – TRUE

    • 1 – FALSE

    • 2 – BYTE

    • 3 – SHORT

    • 4 – INTEGER

    • 5 – LONG

    • 6 – BYTE ARRAY

    • 7 – STRING

    • 8 – TIMESTAMP

    • 9 – UUID

  • Value string byte length: The byte length of the header value string.

  • Header value: The value of the header string. Valid values for this field depend on the type of header.

Data frames

Each streaming request contains one or more data frames. There are two steps to creating a data frame:

  1. Combine raw ChatInput data with metadata to create the payload of your request.

  2. Combine the payload with a signature to form the event message that is sent to Amazon Q Business.