list_ai_project_thread_messages

ArtificialIntelligenceApi.list_ai_project_thread_messages(project_id, thread_id, role_id, sortby=None, sortorder=None, limit=None, offset=None, filter_expression=None, projection_expression=None, _request_timeout=None, _request_auth=None, _content_type=None, _headers=None, _host_index=0)

List messages in a project thread

Returns the conversation history of a thread — the user turns, the assistant turns, and the intermediate rows an agent produces such as thoughts, plans and charts. You need at least read-only access to the project. Chart messages carry a presigned URL to the rendered plot in Content instead of the stored file key; that URL expires eight hours after the response is built. Results are paged, oldest first by default. Increase offset by limit while next_available is the string “yes” and stop when it is “no”.

Parameters:
  • project_id (str) – Identifier of the project the thread belongs to. You must have at least read-only access to it. (required)

  • thread_id (str) – Identifier of the thread whose messages you want. (required)

  • role_id (str) – Amorphic role used to authorize this request. (required)

  • sortby (str) – Message field to sort on. Sorting is case-insensitive and treats every value as text, so MessageTime sorts chronologically because timestamps are stored in ISO order.

  • sortorder (str) – Direction to sort in. Defaults to oldest message first.

  • limit (int) – Maximum number of messages to return in one page. Defaults to 5000, which is also the highest value accepted.

  • offset (int) – 1-based index of the first message to return. Defaults to 1.

  • filter_expression (str) – Narrows the list, written as Field:Value pairs separated by commas, for example Type:ai,ContentType:text. Repeating a field widens the match (OR); different fields must all match (AND). Values for Content may use * as a wildcard and ignore case; every other field must match exactly.

  • projection_expression (str) – Comma-separated list of message fields to return, for example MessageTime,Type,Content. Omit it to return every field.

  • _request_timeout (int, tuple(int, int), optional) – timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of (connection, read) timeouts.

  • _request_auth (dict, optional) – set to override the auth_settings for an a single request; this effectively ignores the authentication in the spec for a single request.

  • _content_type (str, Optional) – force content-type for the request.

  • _headers (dict, optional) – set to override the headers for a single request; this effectively ignores the headers in the spec for a single request.

  • _host_index (int, optional) – set to override the host_index for a single request; this effectively ignores the host_index in the spec for a single request.

Return type:

ChatMessagesResponse

Returns:

Returns the result object.

Request and Response Examples

HTTP: GET /ai/projects/{project_id}/threads/{thread_id}/messages

Success (HTTP 200)

The messages on this page, together with `count` (messages in this response), `total_count` (messages matching the request before paging) and `next_available`. Page through by increasing `offset` by `limit` while `next_available` is the string “yes”; stop when it is “no”. `next_available` is a string, not a boolean.

First page of a conversation

{
  "messages": [
    {
      "ChatId": "e2a91c5b-7d64-4f38-91ac-3b5e0d7f2c18",
      "MessageTime": "2026-07-14 09:13:02",
      "Type": "user",
      "ContentType": "text",
      "Content": "Which region missed the Q3 revenue target?",
      "Metadata": {}
    },
    {
      "ChatId": "e2a91c5b-7d64-4f38-91ac-3b5e0d7f2c18",
      "MessageTime": "2026-07-14 09:13:03",
      "Type": "ai",
      "ContentType": "text",
      "Content": "EMEA came in 6.2% under target; APAC and AMER both cleared theirs.",
      "ModelId": "anthropic.claude-sonnet-4-6",
      "Metadata": {
        "InputTokens": 812,
        "OutputTokens": 143
      }
    }
  ],
  "count": 2,
  "total_count": 2,
  "next_available": "no"
}

Thread with no messages yet

{
  "messages": [],
  "count": 0,
  "total_count": 0,
  "next_available": "no"
}

Errors

Documented error codes: IPV-1002, AUTH-1012, AUTH-1001, IPV-1050, IPV-1004, GE-1008.

HTTP 400

The request was invalid or you do not have permission. The body is {“Message”: “<CODE> - <text>”}. Common cases include an unknown project or thread (IPV-1002), no access to the project (AUTH-1012), a missing role_id header (AUTH-1001), a `limit` above 5000 (IPV-1050), or a malformed `filterExpression` (IPV-1004). Permission failures return 400, not 403.

Thread does not exist

{
  "Message": "IPV-1002 - Invalid ChatId - e2a91c5b-7d64-4f38-91ac-3b5e0d7f2c18, resource not found."
}

Limit above the maximum

{
  "Message": "IPV-1050 - Out of range for items per page, Limit is 5000"
}

HTTP 500

An unexpected server error. The body is {“Message”: “GE-1008 - Could not complete the request. Please try again.”}. A `sortby` naming a field that some messages do not carry also surfaces here.

Request could not be completed

{
  "Message": "GE-1008 - Could not complete the request. Please try again."
}