I tried retrieving Amazon Connect Customer AI agent self-service conversations using the ListMessages API
This page has been translated by machine translation. View original
Introduction
When using Amazon Connect Customer AI agents to handle self-service inquiries, you may want to review the conversation content between customers and AI agents after a call ends.
For example, use cases include the following:
- Reviewing the AI agent's responses
- Integrating inquiry content and response results with external systems
- Analyzing the AI agent's response accuracy
Information about Amazon Connect Customer AI agents can be viewed from the ListMessages API, ListSpans API, CloudWatch Logs, Automated Interaction Log, Contact Lens, and others depending on the use case.
This time, we will use the ListMessages API, which can retrieve conversation messages within an AI agent session.
We executed the DescribeContact API from AWS CloudShell using a Contact ID as the starting point, extracted the Assistant ID and Session ID from the retrieved Session ARN, and retrieved the conversation using the ListMessages API.
Conclusion First
The flow for retrieving conversations with an AI agent from a Contact ID is as follows:
Contact ID
↓
DescribeContact
↓
Contact.WisdomInfo.SessionArn
↓
Extract Assistant ID and Session ID
↓
ListMessages
↓
Retrieve messages between customer and AI agent
Extract the Assistant ID and Session ID from Contact.WisdomInfo.SessionArn included in the DescribeContact response, and specify them in aws qconnect list-messages.
In this verification, the following commands were executed from AWS CloudShell.
export AWS_REGION="ap-northeast-1"
export INSTANCE_ID="<connect-instance-id>"
export CONTACT_ID="<contact-id>"
SESSION_ARN=$(aws connect describe-contact \
--instance-id "$INSTANCE_ID" \
--contact-id "$CONTACT_ID" \
--region "$AWS_REGION" \
--query 'Contact.WisdomInfo.SessionArn' \
--output text)
if [ -z "$SESSION_ARN" ] ||
[ "$SESSION_ARN" = "None" ] ||
[ "$SESSION_ARN" = "null" ]; then
echo "ERROR: Failed to retrieve the AI agent Session ARN." >&2
exit 1
fi
ASSISTANT_ID=$(echo "$SESSION_ARN" | awk -F/ '{print $(NF-1)}')
SESSION_ID=$(echo "$SESSION_ARN" | awk -F/ '{print $NF}')
echo "CONTACT_ID=$CONTACT_ID"
echo "ASSISTANT_ID=$ASSISTANT_ID"
echo "SESSION_ID=$SESSION_ID"
aws qconnect list-messages \
--assistant-id "$ASSISTANT_ID" \
--session-id "$SESSION_ID" \
--filter TEXT_ONLY \
--region "$AWS_REGION" \
--output json |
jq -r '
.messages
| sort_by(.timestamp)
| .[]
| select(.value.text.value? != null)
| "\(.participant): \(.value.text.value | gsub("\\s+"; " "))"
'
In this verification, we executed this command after the call ended and were able to confirm messages between the customer and AI agent in the format of CUSTOMER and BOT.
Conclusion First
The ListMessages API does not allow you to specify a Contact ID directly. To execute it, you need the AI agent's Assistant ID and Session ID.
Therefore, first execute the DescribeContact API by specifying the Contact ID and retrieve Contact.WisdomInfo.SessionArn from the response. Since the Session ARN contains the Assistant ID and Session ID at the end, extract each of them and specify them in the ListMessages API.
In this verification, we retrieved the conversation from AWS CloudShell using the following steps:
- Execute the
DescribeContactAPI specifying the Contact ID - Retrieve
Contact.WisdomInfo.SessionArn - Extract the Assistant ID and Session ID from the Session ARN
- Execute the
ListMessagesAPI specifying the extracted IDs - Format the retrieved messages chronologically using
jq
The following are the commands executed this time.
export AWS_REGION="ap-northeast-1"
export INSTANCE_ID="<connect-instance-id>"
export CONTACT_ID="<contact-id>"
SESSION_ARN=$(aws connect describe-contact \
--instance-id "$INSTANCE_ID" \
--contact-id "$CONTACT_ID" \
--region "$AWS_REGION" \
--query 'Contact.WisdomInfo.SessionArn' \
--output text)
if [ -z "$SESSION_ARN" ] ||
[ "$SESSION_ARN" = "None" ] ||
[ "$SESSION_ARN" = "null" ]; then
echo "ERROR: Failed to retrieve the AI agent Session ARN." >&2
exit 1
fi
ASSISTANT_ID=$(echo "$SESSION_ARN" | awk -F/ '{print $(NF-1)}')
SESSION_ID=$(echo "$SESSION_ARN" | awk -F/ '{print $NF}')
echo "CONTACT_ID=$CONTACT_ID"
echo "ASSISTANT_ID=$ASSISTANT_ID"
echo "SESSION_ID=$SESSION_ID"
aws qconnect list-messages \
--assistant-id "$ASSISTANT_ID" \
--session-id "$SESSION_ID" \
--filter TEXT_ONLY \
--region "$AWS_REGION" \
--output json |
jq -r '
.messages
| sort_by(.timestamp)
| .[]
| select(.value.text.value? != null)
| "\(.participant): \(.value.text.value | gsub("\\s+"; " "))"
'
When we executed this command after the call ended, customer utterances were retrieved as CUSTOMER and AI agent responses were retrieved as BOT.
Prerequisites
This was verified in the following environment:
- Region:
ap-northeast-1 - Amazon Connect Customer instance: already created
- Self-service AI agent: already created
- Voice flow using AI agent: already created
- Execution environment: AWS CloudShell
Resource IDs, message IDs, account IDs, and phone numbers in the article have been changed to example values.
Also, the AWS CloudShell environment used has both the aws command and jq command available. How to verify without using jq is explained in the latter half.
Flow for Retrieving Conversations from a Contact ID
To execute the ListMessages API, an Assistant ID and Session ID are required.
This time, we executed the DescribeContact API by specifying a Contact ID and retrieved these IDs from Contact.WisdomInfo.SessionArn in the response.
The DescribeContact API is an API that retrieves information about a specified contact. The response includes WisdomInfo as information related to the AI agent, and the Session ARN is stored within it.
{
"Contact": {
"WisdomInfo": {
"SessionArn": "arn:aws:wisdom:ap-northeast-1:111111111111:session/aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee/ffffffff-1111-4222-8333-444444444444"
}
}
}
In this verification, the Session ARN had the following format:
arn:aws:wisdom:<region>:<account-id>:session/<assistant-id>/<session-id>
For this reason, we split the ARN by / and extract the Assistant ID and Session ID from the end.
arn:aws:wisdom:<region>:<account-id>:session/<assistant-id>/<session-id>
↑ ↑
Assistant ID Session ID
Details of the DescribeContact API are described in the following documentation.
Details of WisdomInfo are described in the following documentation.
Extracting IDs from the Session ARN
Use the following commands to extract the Assistant ID and Session ID from the end of the Session ARN.
ASSISTANT_ID=$(echo "$SESSION_ARN" | awk -F/ '{print $(NF-1)}')
SESSION_ID=$(echo "$SESSION_ARN" | awk -F/ '{print $NF}')
awk -F/ treats / as a delimiter, and NF is used to get the number of elements.
$(NF-1): The second-to-last element$NF: The last element
In the Session ARN format confirmed this time, the second-to-last element corresponds to the Assistant ID, and the last element corresponds to the Session ID.
When the Session ARN Cannot Be Retrieved
Since SessionArn is not a required field of WisdomInfo, it may not be retrievable depending on the target Contact.
Therefore, the actual processing checks whether the Session ARN is empty.
if [ -z "$SESSION_ARN" ] ||
[ "$SESSION_ARN" = "None" ] ||
[ "$SESSION_ARN" = "null" ]; then
echo "ERROR: Failed to retrieve the AI agent Session ARN." >&2
exit 1
fi
In this verification, we targeted voice contacts that used an AI agent, so the Session ARN was retrievable.
Executing the ListMessages API from AWS CloudShell
Once the Assistant ID and Session ID are retrieved, execute aws qconnect list-messages.
The AWS CLI command name is qconnect, but the target is the Amazon Connect Customer AI agent session.
aws qconnect list-messages \
--assistant-id "$ASSISTANT_ID" \
--session-id "$SESSION_ID" \
--filter TEXT_ONLY \
--region "$AWS_REGION" \
--output json
ListMessages retrieves messages within a session by specifying an Assistant ID and Session ID. In the AWS CLI reference, list-messages is listed as a pagination-supported API.
The following options are used in this command:
| Option | Description |
|---|---|
--assistant-id |
The AI agent's Assistant ID |
--session-id |
The Session ID from which to retrieve messages |
--filter TEXT_ONLY |
A filter to target text messages |
--region |
The region in which to execute the API |
--output json |
Outputs the response in JSON format |
Execution Results
In this environment, the Contact ID, Assistant ID, and Session ID were displayed as follows.
IDs in the article have been changed to example values.
CONTACT_ID=11111111-2222-4333-8444-555555555555
ASSISTANT_ID=aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee
SESSION_ID=ffffffff-1111-4222-8333-444444444444
Next, the conversation between the customer and AI agent was displayed.
CUSTOMER: I'd like to check my delivery date and time
BOT: Certainly. I will check your delivery date and time. Could you please provide the last 4 digits of your order number and the phone number you registered at the time of your order?
CUSTOMER: The last 4 digits are 1742 and my phone number is 090xxxxxxxx
BOT: Thank you. I will check that for you.
BOT: Your scheduled delivery date is September 8th, and the delivery time slot is between 4:00 PM and 6:00 PM.
CUSTOMER: I'd like to change just the delivery time slot to 2:00 PM
BOT: Certainly. You'd like to change the delivery time slot to 2:00 PM. Let me check that for you. I will verify whether the 2:00 PM to 4:00 PM time slot on September 8th is available.
BOT: I apologize. The 2:00 PM to 4:00 PM time slot is fully booked. For September 8th, the 12:00 PM to 2:00 PM or the 6:00 PM to 8:00 PM time slots are available. How would you like to proceed?
CUSTOMER: Then please go with 6:00 PM to 8:00 PM
BOT: Certainly. Let me confirm the change details. Current scheduled delivery: September 8th, 4:00 PM to 6:00 PM. After change: September 8th, 6:00 PM to 8:00 PM. Does this look correct?
CUSTOMER: Yes
BOT: Thank you. I will change the delivery date and time.
BOT: The delivery date and time change has been completed. Your delivery will be on September 8th between 6:00 PM and 8:00 PM. The change details have been sent to you via SMS.
CUSTOMER: Yes, thank you very much
BOT: Thank you for using our service. If you have any questions, please feel free to contact us at any time.
In this verification, the following information was retrieved:
- Customer utterances
- AI agent responses
CUSTOMERandBOTindicating the speaker- Chronological order of messages
Although timestamps are omitted in the display, messages are viewed chronologically using sort_by(.timestamp).
Also, we executed the command after the call ended and were able to retrieve up to the final AI agent response.
Checking JSON Without Using jq
If you want to check the ListMessages response as-is without formatting the conversation, you do not need to use jq.
After retrieving the Assistant ID and Session ID, execute the following command:
aws qconnect list-messages \
--assistant-id "$ASSISTANT_ID" \
--session-id "$SESSION_ID" \
--filter TEXT_ONLY \
--region "$AWS_REGION" \
--output json
An example output is as follows.
Message IDs and timestamps have been changed for the article.
{
"messages": [
{
"value": {
"text": {
"value": "\nThank you for using our service. If you have any questions, please feel free to contact us at any time.\n"
}
},
"messageId": "aaaaaaaa-1111-4222-8333-bbbbbbbbbbbb",
"participant": "BOT",
"timestamp": "2026-08-05T23:56:38.745000+00:00"
},
{
"value": {
"text": {
"value": "Yes, thank you very much"
}
},
"messageId": "cccccccc-1111-4222-8333-dddddddddddd",
"participant": "CUSTOMER",
"timestamp": "2026-08-05T23:56:37.161000+00:00"
},
{
"value": {
"text": {
"value": "\nThe delivery date and time change has been completed. Your delivery will be on September 8th between 6:00 PM and 8:00 PM. The change details have been sent to you via SMS.\n"
}
},
"messageId": "eeeeeeee-1111-4222-8333-ffffffffffff",
"participant": "BOT",
"timestamp": "2026-08-05T23:56:22.978000+00:00"
}
]
}
In this format, the following information can be confirmed:
messageIdparticipanttimestampvalue.text.value
Line Breaks in Message Body
Looking at the BOT message body, \n is included at the beginning and end of the string.
"value": "\nThe delivery date and time change has been completed.\n"
Because these line break characters are included, when displaying the JSON as-is, BOT: and the message body may appear on separate lines.
If you want to display the conversation body in a readable format, extract the body using jq as shown earlier and replace line breaks and consecutive whitespace with single spaces.
ListMessages Is Not a Transcript of the Entire Call
What is retrieved by ListMessages is the messages within the AI agent session.
Therefore, it is not an API that retrieves a transcript of the entire voice contact including sections where the AI agent is not involved.
You need to select the feature to use depending on the information you want to retrieve.
| Information to Retrieve | Example Verification Method |
|---|---|
| Messages between customer and AI agent | ListMessages |
| AI agent processing and tool execution | ListSpans |
| Detailed event logs of AI agent | CloudWatch Logs |
| View self-service history in admin console | Automated Interaction Log |
| Transcript of voice contact | Contact Lens |
As in this case, when retrieving messages exchanged between a customer and AI agent within an AI agent session via API, ListMessages is appropriate.
On the other hand, when internal AI agent processing, tool execution, or a transcript of the entire voice contact is needed, use a combination of other features.
Things to Verify When Retrieving
Verify the Presence of the Session ARN
Executing ListMessages requires an Assistant ID and Session ID.
This time we retrieved them from Contact.WisdomInfo.SessionArn in DescribeContact, but you need to account for Contacts where SessionArn does not exist.
When implementing, please add error handling for when the Session ARN cannot be retrieved, or processing to treat such contacts as out of scope.
Consider the Timing of Message Retrieval
In this verification, we executed the command after the call ended and were able to retrieve up to the final AI agent response.
However, when automating the retrieval process in production, you need to verify with the flows and environment you use whether all messages can always be retrieved immediately after the inquiry ends.
In preparation for retrieval failures, it would also be worth considering retries after a certain period of time and managing already-retrieved Contact IDs.
Consider Pagination
list-messages is a pagination-supported command.
Since the AWS CLI performs automatic pagination by default, the commands shown in this article will retrieve all messages even when they span multiple pages.
On the other hand, if --no-paginate is specified, only the first page will be retrieved. Also, if the number of items is limited with --max-items, use the returned token in --starting-token as needed to resume retrieval.
When implementing custom retrieval processing using the API or SDK, use the nextToken included in the response to retrieve the next page.
Summary
By retrieving the Session ARN from the Contact ID and specifying the extracted Assistant ID and Session ID in the ListMessages API, we were able to retrieve the conversation between the customer and AI agent.
The target of ListMessages is messages within the AI agent session. When a transcript of the entire call or processing traces are needed, use Contact Lens, ListSpans, CloudWatch Logs, and other features.
