Skip to main content

Overview

AgenticPal uses a two-step streaming pattern to provide real-time agent responses via Server-Sent Events (SSE):
  1. POST /chat/message - Store the user’s message and receive a thread ID
  2. GET /chat/stream - Open SSE connection to stream the agent’s response
This approach keeps sensitive message data server-side and only passes the thread ID via URL.

Step 1: POST /chat/message

Store the user’s message server-side and receive a thread ID for streaming.

Authentication

Requires a valid session cookie (session_id) obtained through the OAuth flow.

Request Body

user_message
string
required
The user’s message or query to the agent.
  • Minimum length: 1 character
  • Maximum length: 10,000 characters
Examples:
  • "What meetings do I have tomorrow?"
  • "Send an email to John about the project update"
thread_id
string
Optional thread ID for conversation continuity. If not provided, a new thread is created.

Request Example

{
  "user_message": "What meetings do I have tomorrow?",
  "thread_id": "thread_abc123"
}

Response

thread_id
string
required
Thread ID to use when opening the SSE stream in Step 2
status
string
required
Message status - always "queued" indicating the message is ready for processing

Response Example

{
  "thread_id": "thread_abc123",
  "status": "queued"
}

Status Codes

CodeDescription
200Message stored successfully
401Not authenticated - missing or invalid session cookie
429Rate limit exceeded
500Server error

cURL Example

curl -X POST "https://api.example.com/chat/message" \
  -H "Content-Type: application/json" \
  -H "Cookie: session_id=your_session_id" \
  -d '{
    "user_message": "What meetings do I have tomorrow?"
  }'

Step 2: GET /chat/stream

Open an SSE connection to stream the agent’s response in real-time.

Authentication

Requires a valid session cookie (session_id) obtained through the OAuth flow.

Query Parameters

thread_id
string
required
The thread ID returned from POST /chat/message

Response Format

Returns a text/event-stream (Server-Sent Events) with the following event types:

Event Types

node_start
event
Emitted when the agent starts processing a graph node.Data:
  • node (string): Name of the node that started
node_end
event
Emitted when the agent completes processing a graph node.Data:
  • node (string): Name of the node that ended
token
event
Emitted for each token generated by the language model during response generation.Data:
  • token (string): The token/text chunk
complete
event
Emitted when the agent completes processing successfully.Data:
  • thread_id (string): Thread ID
  • response (string): Complete final response
  • results (object): Execution results from tools
confirmation_required
event
Emitted when the agent needs user confirmation before executing actions.Data:
  • thread_id (string): Thread ID
  • message (string): Confirmation message
  • pending_actions (array): Actions waiting for confirmation
error
event
Emitted when an error occurs during agent processing.Data:
  • error (string): Error type code
  • message (string): Error message

SSE Stream Example

event: node_start
data: {"event_type":"node_start","data":{"node":"agent"},"timestamp":"2026-03-08T10:30:00.000000"}

event: token
data: {"event_type":"token","data":{"token":"You"},"timestamp":"2026-03-08T10:30:00.100000"}

event: token
data: {"event_type":"token","data":{"token":" have"},"timestamp":"2026-03-08T10:30:00.150000"}

event: token
data: {"event_type":"token","data":{"token":" 2"},"timestamp":"2026-03-08T10:30:00.200000"}

event: token
data: {"event_type":"token","data":{"token":" meetings"},"timestamp":"2026-03-08T10:30:00.250000"}

event: node_end
data: {"event_type":"node_end","data":{"node":"agent"},"timestamp":"2026-03-08T10:30:01.000000"}

event: complete
data: {"event_type":"complete","data":{"thread_id":"thread_abc123","response":"You have 2 meetings tomorrow: Team standup at 9 AM and Budget review at 2 PM.","results":{"action_1":{"tool":"google_calendar_search","success":true}}},"timestamp":"2026-03-08T10:30:01.100000"}

Confirmation Required Example

event: confirmation_required
data: {"event_type":"confirmation_required","data":{"thread_id":"thread_xyz789","message":"Should I create a meeting titled 'Project Review' on March 10th at 3 PM?","pending_actions":[{"tool":"create_calendar_event","params":{"title":"Project Review","start":"2026-03-10T15:00:00"}}]},"timestamp":"2026-03-08T10:30:02.000000"}
When receiving this event, use the confirm or cancel endpoints.

Status Codes

CodeDescription
200SSE stream established successfully
400No pending message found - must call POST /chat/message first
401Not authenticated - missing or invalid session cookie
429Rate limit exceeded
500Server error

Error Response

{
  "error": "no_pending_message",
  "message": "No pending message found for this thread. Send a message via POST /chat/message first."
}

Rate Limiting

Default rate limit: 60 requests per minute per session.

cURL Example

curl -X GET "https://api.example.com/chat/stream?thread_id=thread_abc123" \
  -H "Cookie: session_id=your_session_id" \
  -N

JavaScript Example

// Step 1: Send message
const messageResponse = await fetch('https://api.example.com/chat/message', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    user_message: 'What meetings do I have tomorrow?'
  })
});

const { thread_id } = await messageResponse.json();

// Step 2: Open SSE stream
const eventSource = new EventSource(
  `https://api.example.com/chat/stream?thread_id=${thread_id}`,
  { withCredentials: true }
);

// Handle token events
eventSource.addEventListener('token', (event) => {
  const data = JSON.parse(event.data);
  console.log('Token:', data.data.token);
});

// Handle completion
eventSource.addEventListener('complete', (event) => {
  const data = JSON.parse(event.data);
  console.log('Final response:', data.data.response);
  eventSource.close();
});

// Handle errors
eventSource.addEventListener('error', (event) => {
  const data = JSON.parse(event.data);
  console.error('Error:', data.data.message);
  eventSource.close();
});

Build docs developers (and LLMs) love