> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plaisolutions.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Threads

> API endpoints for managing conversation threads and messages between users and agents

## List All Threads

<api-endpoint method="GET" path="/threads" />

List all conversation threads across your project with advanced filtering and pagination options.

### Query Parameters

<ParamField query="skip" type="integer" optional>
  Number of threads to skip for pagination (default: 0)
</ParamField>

<ParamField query="take" type="integer" optional>
  Number of threads to return (default: 50, max: 100)
</ParamField>

<ParamField query="order" type="string" optional>
  Sort order for results (default: "desc")

  * `asc` - Ascending order (oldest first)
  * `desc` - Descending order (newest first)
</ParamField>

<ParamField query="userId" type="string" optional>
  Filter threads by user ID
</ParamField>

<ParamField query="externalRef" type="string" optional>
  Filter threads by external reference identifier
</ParamField>

<ParamField query="agentId" type="string" optional>
  Filter threads by agent ID
</ParamField>

<ParamField query="date_from" type="string" optional>
  Start date filter (ISO 8601 format, e.g., "2024-01-01")
</ParamField>

<ParamField query="date_to" type="string" optional>
  End date filter (ISO 8601 format, e.g., "2024-01-31")
</ParamField>

### Response

<ResponseField name="count" type="integer">
  Total number of threads matching the criteria
</ResponseField>

<ResponseField name="has_more" type="boolean">
  Whether more results are available
</ResponseField>

<ResponseField name="next" type="string">
  Cursor for the next page of results
</ResponseField>

<ResponseField name="previous" type="string">
  Cursor for the previous page of results
</ResponseField>

<ResponseField name="data" type="array">
  Array of thread objects with messages

  <Expandable title="Thread with Messages Object">
    <ResponseField name="id" type="string">
      Thread unique identifier
    </ResponseField>

    <ResponseField name="agent_id" type="string">
      ID of the agent handling this thread
    </ResponseField>

    <ResponseField name="user_id" type="string">
      ID of the user participating in this thread
    </ResponseField>

    <ResponseField name="external_ref" type="string">
      External reference identifier for integration purposes
    </ResponseField>

    <ResponseField name="title" type="string">
      Thread title (auto-generated or custom)
    </ResponseField>

    <ResponseField name="created_at" type="string">
      When the thread was created (ISO 8601 format)
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      When the thread was last updated (ISO 8601 format)
    </ResponseField>

    <ResponseField name="messages" type="array">
      Array of messages in this thread

      <Expandable title="Message Object">
        <ResponseField name="id" type="string">
          Message unique identifier
        </ResponseField>

        <ResponseField name="thread_id" type="string">
          ID of the thread this message belongs to
        </ResponseField>

        <ResponseField name="role" type="string">
          Message sender role (user, assistant, system, tool)
        </ResponseField>

        <ResponseField name="content" type="string">
          Message content/text
        </ResponseField>

        <ResponseField name="message_type" type="string">
          Type of message (text, image, pdf)
        </ResponseField>

        <ResponseField name="tool_call_id" type="string">
          ID of tool call if message is a tool response
        </ResponseField>

        <ResponseField name="tool_calls" type="array">
          Array of tool calls made in this message
        </ResponseField>

        <ResponseField name="tool_result" type="object">
          Result data from tool execution
        </ResponseField>

        <ResponseField name="title" type="string">
          Message title or summary
        </ResponseField>

        <ResponseField name="created_at" type="string">
          When the message was created (ISO 8601 format)
        </ResponseField>

        <ResponseField name="updated_at" type="string">
          When the message was last updated (ISO 8601 format)
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request GET 'https://api.plaisolutions.com/threads?take=20&agentId=agent_123&date_from=2024-01-01' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.plaisolutions.com/threads?take=20&agentId=agent_123&date_from=2024-01-01', {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  const threads = await response.json();
  console.log(threads);
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.plaisolutions.com/threads"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  params = {
      "take": 20,
      "agentId": "agent_123",
      "date_from": "2024-01-01"
  }

  response = requests.get(url, headers=headers, params=params)
  threads = response.json()
  print(threads)
  ```
</CodeGroup>

***

## Create Thread for Agent

<api-endpoint method="POST" path="/agents/{agent_id}/threads" />

Create a new conversation thread for a specific agent.

### Path Parameters

<ParamField path="agent_id" type="string" required>
  The unique identifier of the agent
</ParamField>

### Request Body

<ParamField body="external_ref" type="string" optional>
  External reference identifier for integration tracking
</ParamField>

### Response

Returns the created thread object.

<ResponseField name="id" type="string">
  Thread unique identifier
</ResponseField>

<ResponseField name="agent_id" type="string">
  ID of the agent handling this thread
</ResponseField>

<ResponseField name="user_id" type="string">
  ID of the user who created this thread
</ResponseField>

<ResponseField name="external_ref" type="string">
  External reference identifier
</ResponseField>

<ResponseField name="title" type="string">
  Thread title
</ResponseField>

<ResponseField name="created_at" type="string">
  When the thread was created (ISO 8601 format)
</ResponseField>

<ResponseField name="updated_at" type="string">
  When the thread was last updated (ISO 8601 format)
</ResponseField>

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request POST 'https://api.plaisolutions.com/agents/agent_123/threads' \
  --header 'Authorization: Bearer YOUR_TOKEN' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "external_ref": "support_ticket_456"
  }'
  ```

  ```javascript JavaScript theme={null}
  const agentId = 'agent_123';
  const response = await fetch(`https://api.plaisolutions.com/agents/${agentId}/threads`, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      external_ref: "support_ticket_456"
    })
  });

  const thread = await response.json();
  console.log(thread);
  ```

  ```python Python theme={null}
  import requests

  agent_id = "agent_123"
  url = f"https://api.plaisolutions.com/agents/{agent_id}/threads"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  data = {
      "external_ref": "support_ticket_456"
  }

  response = requests.post(url, headers=headers, json=data)
  thread = response.json()
  print(thread)
  ```
</CodeGroup>

***

## List Agent Threads

<api-endpoint method="GET" path="/agents/{agent_id}/threads" />

List all conversation threads for a specific agent.

### Path Parameters

<ParamField path="agent_id" type="string" required>
  The unique identifier of the agent
</ParamField>

### Query Parameters

<ParamField query="skip" type="integer" optional>
  Number of threads to skip (default: 0)
</ParamField>

<ParamField query="take" type="integer" optional>
  Number of threads to return (default: 50)
</ParamField>

<ParamField query="order" type="string" optional>
  Sort order for results (default: "desc")
</ParamField>

### Response

<ResponseField name="count" type="integer">
  Total number of threads for this agent
</ResponseField>

<ResponseField name="has_more" type="boolean">
  Whether more results are available
</ResponseField>

<ResponseField name="next" type="string">
  Cursor for the next page
</ResponseField>

<ResponseField name="previous" type="string">
  Cursor for the previous page
</ResponseField>

<ResponseField name="data" type="array">
  Array of thread objects (without messages)
</ResponseField>

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request GET 'https://api.plaisolutions.com/agents/agent_123/threads?take=25' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const agentId = 'agent_123';
  const response = await fetch(`https://api.plaisolutions.com/agents/${agentId}/threads?take=25`, {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  const threads = await response.json();
  console.log(threads);
  ```

  ```python Python theme={null}
  import requests

  agent_id = "agent_123"
  url = f"https://api.plaisolutions.com/agents/{agent_id}/threads"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  params = {"take": 25}

  response = requests.get(url, headers=headers, params=params)
  threads = response.json()
  print(threads)
  ```
</CodeGroup>

***

## Get Thread with Messages

<api-endpoint method="GET" path="/agents/{agent_id}/threads/{thread_id}" />

Get detailed information about a specific thread including all messages.

### Path Parameters

<ParamField path="agent_id" type="string" required>
  The unique identifier of the agent
</ParamField>

<ParamField path="thread_id" type="string" required>
  The unique identifier of the thread
</ParamField>

### Response

Returns the complete thread object with all messages and conversation history.

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request GET 'https://api.plaisolutions.com/agents/agent_123/threads/thread_456' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const agentId = 'agent_123';
  const threadId = 'thread_456';
  const response = await fetch(`https://api.plaisolutions.com/agents/${agentId}/threads/${threadId}`, {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  const thread = await response.json();
  console.log(thread);
  ```

  ```python Python theme={null}
  import requests

  agent_id = "agent_123"
  thread_id = "thread_456"
  url = f"https://api.plaisolutions.com/agents/{agent_id}/threads/{thread_id}"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }

  response = requests.get(url, headers=headers)
  thread = response.json()
  print(thread)
  ```
</CodeGroup>

***

## Chat Session Threads

### Create Thread from Chat Session

<api-endpoint method="POST" path="/chat_sessions/{chat_session_id}/threads" />

Create a new thread within a chat session context.

### Path Parameters

<ParamField path="chat_session_id" type="string" required>
  The unique identifier of the chat session
</ParamField>

### Response

Returns the created thread object within the chat session context.

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request POST 'https://api.plaisolutions.com/chat_sessions/session_123/threads' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const chatSessionId = 'session_123';
  const response = await fetch(`https://api.plaisolutions.com/chat_sessions/${chatSessionId}/threads`, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  const thread = await response.json();
  console.log(thread);
  ```

  ```python Python theme={null}
  import requests

  chat_session_id = "session_123"
  url = f"https://api.plaisolutions.com/chat_sessions/{chat_session_id}/threads"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }

  response = requests.post(url, headers=headers)
  thread = response.json()
  print(thread)
  ```
</CodeGroup>

### List Chat Session Threads

<api-endpoint method="GET" path="/chat_sessions/{chat_session_id}/threads" />

List all threads within a specific chat session.

### Path Parameters

<ParamField path="chat_session_id" type="string" required>
  The unique identifier of the chat session
</ParamField>

### Response

Returns an array of thread objects associated with the chat session.

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request GET 'https://api.plaisolutions.com/chat_sessions/session_123/threads' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const chatSessionId = 'session_123';
  const response = await fetch(`https://api.plaisolutions.com/chat_sessions/${chatSessionId}/threads`, {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  const threads = await response.json();
  console.log(threads);
  ```

  ```python Python theme={null}
  import requests

  chat_session_id = "session_123"
  url = f"https://api.plaisolutions.com/chat_sessions/{chat_session_id}/threads"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }

  response = requests.get(url, headers=headers)
  threads = response.json()
  print(threads)
  ```
</CodeGroup>

### Get Thread from Chat Session

<api-endpoint method="GET" path="/chat_sessions/{chat_session_id}/threads/{thread_id}" />

Get a specific thread within a chat session context.

### Path Parameters

<ParamField path="chat_session_id" type="string" required>
  The unique identifier of the chat session
</ParamField>

<ParamField path="thread_id" type="string" required>
  The unique identifier of the thread
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request GET 'https://api.plaisolutions.com/chat_sessions/session_123/threads/thread_456' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const chatSessionId = 'session_123';
  const threadId = 'thread_456';
  const response = await fetch(`https://api.plaisolutions.com/chat_sessions/${chatSessionId}/threads/${threadId}`, {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  const thread = await response.json();
  console.log(thread);
  ```

  ```python Python theme={null}
  import requests

  chat_session_id = "session_123"
  thread_id = "thread_456"
  url = f"https://api.plaisolutions.com/chat_sessions/{chat_session_id}/threads/{thread_id}"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }

  response = requests.get(url, headers=headers)
  thread = response.json()
  print(thread)
  ```
</CodeGroup>

### Delete Thread from Chat Session

<api-endpoint method="DELETE" path="/chat_sessions/{chat_session_id}/threads/{thread_id}" />

Delete a specific thread from a chat session.

### Path Parameters

<ParamField path="chat_session_id" type="string" required>
  The unique identifier of the chat session
</ParamField>

<ParamField path="thread_id" type="string" required>
  The unique identifier of the thread to delete
</ParamField>

### Response

Returns a confirmation of thread deletion.

<Warning>
  Deleting a thread will permanently remove all messages and conversation history. This action cannot be undone.
</Warning>

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request DELETE 'https://api.plaisolutions.com/chat_sessions/session_123/threads/thread_456' \
  --header 'Authorization: Bearer YOUR_TOKEN'
  ```

  ```javascript JavaScript theme={null}
  const chatSessionId = 'session_123';
  const threadId = 'thread_456';
  const response = await fetch(`https://api.plaisolutions.com/chat_sessions/${chatSessionId}/threads/${threadId}`, {
    method: 'DELETE',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  console.log('Thread deleted:', response.ok);
  ```

  ```python Python theme={null}
  import requests

  chat_session_id = "session_123"
  thread_id = "thread_456"
  url = f"https://api.plaisolutions.com/chat_sessions/{chat_session_id}/threads/{thread_id}"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }

  response = requests.delete(url, headers=headers)
  print(f"Thread deleted: {response.ok}")
  ```
</CodeGroup>

### Invoke Thread from Chat Session

<api-endpoint method="POST" path="/chat_sessions/{chat_session_id}/threads/{thread_id}/invoke" />

Send a message to an agent through a chat session thread.

### Path Parameters

<ParamField path="chat_session_id" type="string" required>
  The unique identifier of the chat session
</ParamField>

<ParamField path="thread_id" type="string" required>
  The unique identifier of the thread
</ParamField>

### Request Body

<ParamField body="prompt" type="string" required>
  The message/prompt to send to the agent
</ParamField>

<ParamField body="enabled_tools" type="array" optional>
  Array of tool IDs to enable for this specific interaction
</ParamField>

### Response

Returns the agent's response and any tool results.

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request POST 'https://api.plaisolutions.com/chat_sessions/session_123/threads/thread_456/invoke' \
  --header 'Authorization: Bearer YOUR_TOKEN' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "prompt": "Hello, can you help me with product recommendations?",
    "enabled_tools": ["web_search", "product_database"]
  }'
  ```

  ```javascript JavaScript theme={null}
  const chatSessionId = 'session_123';
  const threadId = 'thread_456';
  const response = await fetch(`https://api.plaisolutions.com/chat_sessions/${chatSessionId}/threads/${threadId}/invoke`, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      prompt: "Hello, can you help me with product recommendations?",
      enabled_tools: ["web_search", "product_database"]
    })
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python Python theme={null}
  import requests

  chat_session_id = "session_123"
  thread_id = "thread_456"
  url = f"https://api.plaisolutions.com/chat_sessions/{chat_session_id}/threads/{thread_id}/invoke"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  data = {
      "prompt": "Hello, can you help me with product recommendations?",
      "enabled_tools": ["web_search", "product_database"]
  }

  response = requests.post(url, headers=headers, json=data)
  result = response.json()
  print(result)
  ```
</CodeGroup>

***

## Thread Management Best Practices

<Steps>
  <Step title="Thread Organization">
    Use meaningful external references to track threads across your application
  </Step>

  <Step title="Message History">
    Regularly retrieve thread messages to maintain conversation context
  </Step>

  <Step title="Session Management">
    Utilize chat sessions for temporary or anonymous user interactions
  </Step>

  <Step title="Cleanup Strategy">
    Implement thread lifecycle management to remove old or inactive conversations
  </Step>

  <Step title="Performance">
    Use pagination when listing threads to avoid performance issues
  </Step>
</Steps>

### Thread Lifecycle

<CardGroup cols={2}>
  <Card title="Creation" icon="plus">
    Threads are created automatically when users start conversations or manually via API
  </Card>

  <Card title="Active State" icon="message-circle">
    Threads remain active while users exchange messages with agents
  </Card>

  <Card title="Persistence" icon="database">
    All messages and context are preserved throughout the thread lifetime
  </Card>

  <Card title="Cleanup" icon="trash">
    Implement cleanup policies based on age, activity, or business requirements
  </Card>
</CardGroup>

### External Reference Patterns

<Tip>
  **Common External Reference Patterns:**

  * Support tickets: `ticket_12345`
  * User sessions: `session_user_67890`
  * Order inquiries: `order_98765`
  * Product questions: `product_sku_abc123`
  * Channel integration: `slack_channel_general`
</Tip>

### Message Types and Structure

<AccordionGroup>
  <Accordion title="Text Messages">
    Standard text-based conversations between users and agents

    ```json theme={null}
    {
      "role": "user",
      "message_type": "text",
      "content": "Hello, I need help with my order"
    }
    ```
  </Accordion>

  <Accordion title="Tool Messages">
    Messages containing tool calls and results

    ```json theme={null}
    {
      "role": "assistant", 
      "message_type": "text",
      "content": "I'll help you check your order status",
      "tool_calls": [
        {
          "function": "check_order_status",
          "arguments": {"order_id": "12345"}
        }
      ]
    }
    ```
  </Accordion>

  <Accordion title="Media Messages">
    Messages containing images, documents, or other media

    ```json theme={null}
    {
      "role": "user",
      "message_type": "image", 
      "content": null,
      "title": "Product photo for identification"
    }
    ```
  </Accordion>
</AccordionGroup>

### Filtering and Search

<Note>
  **Advanced Filtering Options:**

  * Filter by date range to find recent conversations
  * Filter by agent to analyze specific agent performance
  * Filter by external reference for integration lookup
  * Filter by user for customer support scenarios
  * Combine filters for precise thread discovery
</Note>

### Security Considerations

<Warning>
  **Thread Security:**

  * Threads inherit permissions from their associated agents and projects
  * External references should not contain sensitive information
  * Implement proper access controls for chat session management
  * Consider message retention policies for compliance
  * Monitor thread access patterns for security anomalies
</Warning>

### Integration Patterns

Use threads effectively in different integration scenarios:

```javascript theme={null}
// Customer Support Integration
async function createSupportThread(ticketId, agentId) {
  const thread = await fetch(`/agents/${agentId}/threads`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer YOUR_TOKEN' },
    body: JSON.stringify({
      external_ref: `support_${ticketId}`
    })
  });
  return await thread.json();
}

// Chat Widget Integration  
async function getOrCreateChatThread(sessionId, agentId) {
  // Try to find existing thread
  const threads = await fetch(`/agents/${agentId}/threads?externalRef=chat_${sessionId}`);
  const threadList = await threads.json();
  
  if (threadList.data.length > 0) {
    return threadList.data[0];
  }
  
  // Create new thread if none exists
  return createSupportThread(`chat_${sessionId}`, agentId);
}
```

### Performance Optimization

<Tip>
  **Optimize Thread Performance:**

  * Use appropriate pagination limits (20-50 threads per request)
  * Filter by date range to reduce result sets
  * Cache frequently accessed threads
  * Use external references for quick thread lookup
  * Implement thread archiving for old conversations
</Tip>
