Skip to main content
GET
/
v1
/
sessions
/
{session_id}
/
messages
Get Messages
curl --request GET \
  --url https://api.example.com/v1/sessions/{session_id}/messages \
  --header 'Authorization: <authorization>'
{
  "messages": [
    {
      "id": 17,
      "type": "QUESTION",
      "content": "Do you prefer evening flights?",
      "timestamp": "2025-10-05T18:05:01.555Z",
      "metadata": {"origin": "agent"}
    },
    {
      "id": 18,
      "type": "THOUGHT",
      "content": "Searching airline sites for available flights...",
      "timestamp": "2025-10-05T18:05:02.031Z",
      "metadata": {}
    },
    {
      "id": 19,
      "type": "DONE",
      "content": "Found 3 flights under $450: ...",
      "timestamp": "2025-10-05T18:05:45.123Z",
      "metadata": {"result_count": 3}
    }
  ],
  "status": "finished",
  "has_agent": true
}

Overview

Retrieve messages from the agent, including thoughts, questions, results, and errors. Use the after_id parameter to implement efficient polling.

Request

session_id
string
required
The UUID of the session
Authorization
string
required
Bearer token for authentication
after_id
integer
default:"0"
Return only messages with ID greater than this value. Use for incremental polling.
sanitize
boolean
default:"true"
Filter out system messages, internal prompts, and images. Set to false for debugging.

Response

messages
array
required
Array of message objects
status
string
required
Current execution status: running, waiting_for_input, finished, error
has_agent
boolean
required
Whether the agent is connected and active
{
  "messages": [
    {
      "id": 17,
      "type": "QUESTION",
      "content": "Do you prefer evening flights?",
      "timestamp": "2025-10-05T18:05:01.555Z",
      "metadata": {"origin": "agent"}
    },
    {
      "id": 18,
      "type": "THOUGHT",
      "content": "Searching airline sites for available flights...",
      "timestamp": "2025-10-05T18:05:02.031Z",
      "metadata": {}
    },
    {
      "id": 19,
      "type": "DONE",
      "content": "Found 3 flights under $450: ...",
      "timestamp": "2025-10-05T18:05:45.123Z",
      "metadata": {"result_count": 3}
    }
  ],
  "status": "finished",
  "has_agent": true
}

Example Requests

import { AGIClient } from 'agi';

const client = new AGIClient({ apiKey: 'your_api_key' });

// Get messages (first poll)
const messages = await client.getMessages(sessionId, { after_id: 0 });

// Get messages (incremental - after ID 25)
const newMessages = await client.getMessages(sessionId, { after_id: 25 });

// Poll for messages
let afterId = 0;
while (true) {
  const data = await client.getMessages(sessionId, { after_id: afterId });
  
  for (const msg of data.messages) {
    afterId = Math.max(afterId, msg.id);
    console.log(`[${msg.type}] ${msg.content}`);
    
    if (msg.type === 'QUESTION') {
      // Handle question
    }
  }
  
  if (['finished', 'error'].includes(data.status)) {
    break;
  }
  
  await new Promise(resolve => setTimeout(resolve, 2000));
}

Message Types

THOUGHT

Agent’s reasoning or actions being taken
{
  "type": "THOUGHT",
  "content": "Navigating to Kayak.com to search for flights..."
}

QUESTION

Agent needs user input to continue
{
  "type": "QUESTION",
  "content": "Would you like me to filter for direct flights only?"
}

DONE

Task completion with results
{
  "type": "DONE",
  "content": {
    "summary": "Found 3 flights",
    "flights": [...]
  }
}

ERROR

Error occurred during execution
{
  "type": "ERROR",
  "content": "Unable to access website - connection timeout"
}

LOG

Additional context or debugging info
{
  "type": "LOG",
  "content": "Page loaded successfully: https://kayak.com"
}

Use Cases

Incremental Polling

# Efficient polling - only fetch new messages
after_id = 0
while True:
    data = get_messages(session_id, after_id)

    for msg in data["messages"]:
        after_id = max(after_id, msg["id"])
        process_message(msg)

    if data["status"] == "finished":
        break

Interactive Q&A

def handle_messages(session_id):
    after_id = 0

    while True:
        data = get_messages(session_id, after_id)

        for msg in data["messages"]:
            after_id = max(after_id, msg["id"])

            if msg["type"] == "QUESTION":
                print(f"Agent asks: {msg['content']}")
                answer = input("Your answer: ")
                send_message(session_id, answer)
            elif msg["type"] == "THOUGHT":
                print(f"Agent: {msg['content']}")

        if data["status"] in ["finished", "error"]:
            break

Extract Final Results

# Get all messages after task completes
data = get_messages(session_id, after_id=0, sanitize=True)

# Find the DONE message with results
for msg in data["messages"]:
    if msg["type"] == "DONE":
        results = msg["content"]
        print(f"Results: {results}")

Polling Pattern

# Recommended pattern
after_id = 0

while True:
    # Fetch new messages
    data = get_messages(session_id, after_id)

    # Process each message
    for msg in data["messages"]:
        # Update tracking
        after_id = max(after_id, msg["id"])

        # Handle message
        handle_message(msg)

    # Check completion
    if data["status"] in ["finished", "error"]:
        break

    # Wait before next poll
    time.sleep(2)
For real-time updates without polling, consider using Server-Sent Events instead.

Best Practices

Always track the highest id you’ve seen and use it as after_id in the next poll. This prevents fetching duplicate messages.
Poll interval recommendation: 1-3 seconds. Balance between responsiveness and API load.