The Sessions API provides a comprehensive set of endpoints for managing stateful conversations with ElizaOS agents. This reference covers all available endpoints, request/response schemas, and error handling.

Base URL

http://localhost:3000/api/messaging/sessions

Authentication

Currently, the Sessions API does not require authentication. In production environments, you should implement appropriate authentication mechanisms.

Endpoints

Create Session

Creates a new conversation session with an agent.

POST /api/messaging/sessions

Create a new session with configurable timeout policies
Request Body:
interface CreateSessionRequest {
  agentId: string;           // UUID of the agent
  userId: string;            // UUID of the user
  metadata?: {               // Optional session metadata
    [key: string]: any;
  };
  timeoutConfig?: {          // Optional timeout configuration
    timeoutMinutes?: number;           // 5-1440 minutes
    autoRenew?: boolean;               // Default: true
    maxDurationMinutes?: number;       // Maximum session duration
    warningThresholdMinutes?: number;  // When to warn about expiration
  };
}
Response (201 Created):
interface CreateSessionResponse {
  sessionId: string;
  agentId: string;
  userId: string;
  createdAt: Date;
  metadata: object;
  expiresAt: Date;
  timeoutConfig: SessionTimeoutConfig;
}
Example:
curl -X POST http://localhost:3000/api/messaging/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "123e4567-e89b-12d3-a456-426614174000",
    "userId": "987f6543-e21b-12d3-a456-426614174000",
    "timeoutConfig": {
      "timeoutMinutes": 30,
      "autoRenew": true
    }
  }'

Get Session Information

Retrieves detailed information about a session including its current status.

GET /api/messaging/sessions/{sessionId}

Get session details and current status
Response (200 OK):
interface SessionInfoResponse {
  sessionId: string;
  agentId: string;
  userId: string;
  createdAt: Date;
  lastActivity: Date;
  metadata: object;
  expiresAt: Date;
  timeoutConfig: SessionTimeoutConfig;
  renewalCount: number;
  timeRemaining: number;     // Milliseconds until expiration
  isNearExpiration: boolean;  // True if within warning threshold
}
Errors:
  • 404 Not Found - Session does not exist
  • 410 Gone - Session has expired

Send Message

Sends a message within a session. Automatically renews the session if auto-renewal is enabled.

POST /api/messaging/sessions/{sessionId}/messages

Send a message in the conversation
Request Body:
interface SendMessageRequest {
  content: string;           // Message content (max 4000 chars)
  metadata?: {              // Optional message metadata
    [key: string]: any;
  };
  attachments?: any[];      // Optional attachments
}
Response (201 Created):
interface MessageResponse {
  id: string;
  content: string;
  authorId: string;
  createdAt: Date;
  metadata: object;
  sessionStatus?: {         // Session renewal information
    expiresAt: Date;
    renewalCount: number;
    wasRenewed: boolean;
    isNearExpiration: boolean;
  };
}
Errors:
  • 400 Bad Request - Invalid content or metadata
  • 404 Not Found - Session not found
  • 410 Gone - Session expired

Get Messages

Retrieves messages from a session with pagination support.

GET /api/messaging/sessions/{sessionId}/messages

Retrieve conversation history
Query Parameters:
interface GetMessagesQuery {
  limit?: string;    // Number of messages (1-100, default: 50)
  before?: string;   // Timestamp for pagination (older messages)
  after?: string;    // Timestamp for pagination (newer messages)
}
Response (200 OK):
interface GetMessagesResponse {
  messages: SimplifiedMessage[];
  hasMore: boolean;
  cursors?: {
    before?: number;  // Use for getting older messages
    after?: number;   // Use for getting newer messages
  };
}

interface SimplifiedMessage {
  id: string;
  content: string;
  authorId: string;
  isAgent: boolean;
  createdAt: Date;
  metadata: {
    thought?: string;     // Agent's internal reasoning
    actions?: string[];   // Actions taken by agent
    [key: string]: any;
  };
}

Renew Session

Manually renews a session to extend its expiration time.

POST /api/messaging/sessions/{sessionId}/renew

Manually extend session lifetime
Response (200 OK):
interface SessionInfoResponse {
  sessionId: string;
  agentId: string;
  userId: string;
  createdAt: Date;
  lastActivity: Date;
  expiresAt: Date;
  timeoutConfig: SessionTimeoutConfig;
  renewalCount: number;
  timeRemaining: number;
  isNearExpiration: boolean;
}
Errors:
  • 404 Not Found - Session not found
  • 410 Gone - Session expired
  • 422 Unprocessable Entity - Cannot renew (max duration reached)

Update Timeout Configuration

Updates the timeout configuration for an active session.

PATCH /api/messaging/sessions/{sessionId}/timeout

Modify session timeout settings
Request Body:
interface SessionTimeoutConfig {
  timeoutMinutes?: number;           // 5-1440 minutes
  autoRenew?: boolean;
  maxDurationMinutes?: number;
  warningThresholdMinutes?: number;
}
Response (200 OK): Returns updated SessionInfoResponse Errors:
  • 400 Bad Request - Invalid timeout configuration
  • 404 Not Found - Session not found
  • 410 Gone - Session expired

Send Heartbeat

Keeps a session alive and optionally renews it if auto-renewal is enabled.

POST /api/messaging/sessions/{sessionId}/heartbeat

Keep session alive with periodic heartbeat
Response (200 OK): Returns SessionInfoResponse with updated expiration information. Errors:
  • 404 Not Found - Session not found
  • 410 Gone - Session expired

Delete Session

Explicitly ends and removes a session.

DELETE /api/messaging/sessions/{sessionId}

End and delete a session
Response (200 OK):
{
  success: true,
  message: "Session {sessionId} deleted successfully"
}
Errors:
  • 404 Not Found - Session not found

List Sessions (Admin)

Lists all active sessions in the system. This is an administrative endpoint.

GET /api/messaging/sessions

List all active sessions
Response (200 OK):
interface ListSessionsResponse {
  sessions: SessionInfoResponse[];
  total: number;
  stats: {
    totalSessions: number;
    activeSessions: number;
    expiredSessions: number;
  };
}

Health Check

Checks the health status of the Sessions API service.

GET /api/messaging/sessions/health

Check service health
Response (200 OK):
interface HealthCheckResponse {
  status: 'healthy' | 'degraded' | 'unhealthy';
  activeSessions: number;
  timestamp: string;
  expiringSoon?: number;      // Sessions near expiration
  invalidSessions?: number;    // Corrupted sessions detected
  uptime?: number;            // Service uptime in seconds
}

Error Responses

All error responses follow a consistent format:
interface ErrorResponse {
  error: string;              // Error message
  details?: {                // Additional context
    [key: string]: any;
  };
}

Common Error Codes

Status CodeError TypeDescription
400Bad RequestInvalid input parameters or request body
404Not FoundSession or resource not found
410GoneSession has expired
422Unprocessable EntityOperation cannot be completed (e.g., max duration reached)
500Internal Server ErrorUnexpected server error

Error Classes

The API uses specific error classes for different scenarios:
  • SessionNotFoundError - Session does not exist
  • SessionExpiredError - Session has exceeded its timeout
  • SessionCreationError - Failed to create session
  • AgentNotFoundError - Specified agent not found
  • InvalidUuidError - Invalid UUID format
  • MissingFieldsError - Required fields missing
  • InvalidContentError - Message content validation failed
  • InvalidMetadataError - Metadata exceeds size limit
  • InvalidPaginationError - Invalid pagination parameters
  • InvalidTimeoutConfigError - Invalid timeout configuration
  • SessionRenewalError - Cannot renew session
  • MessageSendError - Failed to send message

Rate Limiting

Currently, the Sessions API does not implement rate limiting. In production, you should implement appropriate rate limiting based on your requirements.

WebSocket Events

When using WebSocket connections alongside the Sessions API, the following events are available:
// Join a session for real-time updates
socket.emit('join', { roomId: sessionId });

// Listen for new messages
socket.on('messageBroadcast', (message) => {
  // Handle new message
});

// Session expiration warning
socket.on('sessionExpirationWarning', (data) => {
  // data.sessionId, data.minutesRemaining
});

// Session expired
socket.on('sessionExpired', (data) => {
  // data.sessionId, data.expiredAt
});

// Session renewed
socket.on('sessionRenewed', (data) => {
  // data.sessionId, data.expiresAt, data.renewalCount
});

Environment Variables

Configure the Sessions API behavior using these environment variables:
VariableDefaultDescription
SESSION_DEFAULT_TIMEOUT_MINUTES30Default session timeout
SESSION_MIN_TIMEOUT_MINUTES5Minimum allowed timeout
SESSION_MAX_TIMEOUT_MINUTES1440Maximum allowed timeout (24 hours)
SESSION_MAX_DURATION_MINUTES720Maximum total session duration (12 hours)
SESSION_WARNING_THRESHOLD_MINUTES5When to trigger expiration warning
SESSION_CLEANUP_INTERVAL_MINUTES5How often to clean expired sessions
CLEAR_SESSIONS_ON_SHUTDOWNfalseClear all sessions on server shutdown

SDK Examples

JavaScript/TypeScript Client

class SessionsAPIClient {
  constructor(private baseUrl: string = 'http://localhost:3000') {}
  
  async createSession(agentId: string, userId: string, config?: SessionTimeoutConfig) {
    const response = await fetch(`${this.baseUrl}/api/messaging/sessions`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ agentId, userId, timeoutConfig: config })
    });
    
    if (!response.ok) throw new Error(`Failed to create session: ${response.status}`);
    return response.json();
  }
  
  async sendMessage(sessionId: string, content: string, metadata?: object) {
    const response = await fetch(
      `${this.baseUrl}/api/messaging/sessions/${sessionId}/messages`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content, metadata })
      }
    );
    
    if (!response.ok) throw new Error(`Failed to send message: ${response.status}`);
    return response.json();
  }
  
  async getMessages(sessionId: string, limit = 50, before?: number) {
    const params = new URLSearchParams({ limit: limit.toString() });
    if (before) params.append('before', before.toString());
    
    const response = await fetch(
      `${this.baseUrl}/api/messaging/sessions/${sessionId}/messages?${params}`
    );
    
    if (!response.ok) throw new Error(`Failed to get messages: ${response.status}`);
    return response.json();
  }
  
  async renewSession(sessionId: string) {
    const response = await fetch(
      `${this.baseUrl}/api/messaging/sessions/${sessionId}/renew`,
      { method: 'POST' }
    );
    
    if (!response.ok) throw new Error(`Failed to renew session: ${response.status}`);
    return response.json();
  }
  
  async sendHeartbeat(sessionId: string) {
    const response = await fetch(
      `${this.baseUrl}/api/messaging/sessions/${sessionId}/heartbeat`,
      { method: 'POST' }
    );
    
    if (!response.ok) throw new Error(`Heartbeat failed: ${response.status}`);
    return response.json();
  }
}

Python Client

import requests
from typing import Optional, Dict, Any

class SessionsAPIClient:
    def __init__(self, base_url: str = "http://localhost:3000"):
        self.base_url = base_url
        self.session = requests.Session()
    
    def create_session(
        self, 
        agent_id: str, 
        user_id: str,
        timeout_config: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Create a new session with an agent."""
        payload = {
            "agentId": agent_id,
            "userId": user_id
        }
        
        if timeout_config:
            payload["timeoutConfig"] = timeout_config
        
        response = self.session.post(
            f"{self.base_url}/api/messaging/sessions",
            json=payload
        )
        response.raise_for_status()
        return response.json()
    
    def send_message(
        self,
        session_id: str,
        content: str,
        metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Send a message in a session."""
        payload = {"content": content}
        
        if metadata:
            payload["metadata"] = metadata
        
        response = self.session.post(
            f"{self.base_url}/api/messaging/sessions/{session_id}/messages",
            json=payload
        )
        response.raise_for_status()
        return response.json()
    
    def get_messages(
        self,
        session_id: str,
        limit: int = 50,
        before: Optional[int] = None,
        after: Optional[int] = None
    ) -> Dict[str, Any]:
        """Retrieve messages from a session."""
        params = {"limit": str(limit)}
        
        if before:
            params["before"] = str(before)
        if after:
            params["after"] = str(after)
        
        response = self.session.get(
            f"{self.base_url}/api/messaging/sessions/{session_id}/messages",
            params=params
        )
        response.raise_for_status()
        return response.json()
    
    def renew_session(self, session_id: str) -> Dict[str, Any]:
        """Manually renew a session."""
        response = self.session.post(
            f"{self.base_url}/api/messaging/sessions/{session_id}/renew"
        )
        response.raise_for_status()
        return response.json()
    
    def send_heartbeat(self, session_id: str) -> Dict[str, Any]:
        """Send a heartbeat to keep session alive."""
        response = self.session.post(
            f"{self.base_url}/api/messaging/sessions/{session_id}/heartbeat"
        )
        response.raise_for_status()
        return response.json()

Next Steps