Skip to main content

Overview

The Create Sessions API supports webhook notifications to receive real-time updates about session lifecycle events and task execution status. When you provide a webhook_url during session creation, the system will automatically send HTTP POST requests to your endpoint when specific events occur.

Configuration

Request Parameter

When creating a session via POST /v1/sessions, you can optionally include a webhook_url parameter:
{
  "agent_name": "agi-0",
  "webhook_url": "https://your-server.com/webhooks/sessions"
}

Validation

  • The webhook URL must be a valid HTTP or HTTPS URL
  • Maximum length: 2,000 characters
  • Must start with http:// or https://

How It Works

1. Session Creation

When you create a session with a webhook_url:
  1. The webhook URL is stored with the session record
  2. A session.created webhook is immediately triggered (non-blocking)
  3. The session creation API returns immediately without waiting for webhook delivery

2. Background Monitoring

After a message is sent to the agent (via POST /v1/sessions/{session_id}/message), the system starts a background task that monitors the agent’s event stream. This monitoring:
  • Runs independently of any active SSE connections
  • Automatically triggers webhooks for terminal events
  • Stops monitoring after receiving a terminal event (done, question, or error)

3. Webhook Delivery

Webhooks are delivered asynchronously using a fire-and-forget pattern:
  • Non-blocking: Webhook failures never block session operations
  • Automatic retries: Failed webhooks are retried up to 3 times with exponential backoff
  • Timeout: Each webhook attempt has a 10-second timeout
  • Total retry window: Maximum 30 seconds for all retry attempts

Webhook Events

Session Lifecycle Events

session.created

Triggered immediately after a session is successfully created. Payload:
{
  "event": "session.created",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "ready",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  }
}

session.status_changed

Triggered when a session’s status changes (e.g., paused, resumed, cancelled). Payload:
{
  "event": "session.status_changed",
  "timestamp": "2024-01-15T10:35:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "paused",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  },
  "old_status": "running",
  "new_status": "paused"
}

session.deleted

Triggered when a session is deleted. Payload:
{
  "event": "session.deleted",
  "timestamp": "2024-01-15T11:00:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "ready",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  }
}

Task Execution Events

task.started

Triggered when a task starts (after sending a message to the agent). Payload:
{
  "event": "task.started",
  "timestamp": "2024-01-15T10:32:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "running",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  },
  "message": "Navigate to example.com and click the login button"
}

task.completed

Triggered when a task completes successfully. Payload:
{
  "event": "task.completed",
  "timestamp": "2024-01-15T10:40:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "ready",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  },
  "result": {
    "status": "success",
    "message": "Task completed successfully"
  }
}

task.question

Triggered when the agent needs user input to proceed. Payload:
{
  "event": "task.question",
  "timestamp": "2024-01-15T10:35:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "ready",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  },
  "question": "Which email address should I use for login?",
  "context": {}
}

task.error

Triggered when a task encounters an error. Payload:
{
  "event": "task.error",
  "timestamp": "2024-01-15T10:38:00.000Z",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "ready",
    "agent_name": "agi-0",
    "created_at": "2024-01-15T10:30:00.000Z",
    "vnc_url": "http://vnc-instance:5900"
  },
  "error": "Failed to locate element: button.login",
  "details": {}
}

Webhook Request Format

All webhook requests are sent as HTTP POST requests with the following characteristics:

Headers

Content-Type: application/json
X-Event-Type: {event_type}
User-Agent: AgencyAPI-Webhooks/1.0

Body

The request body is a JSON object containing:
  • event: The event type (e.g., “session.created”, “task.completed”)
  • timestamp: ISO 8601 timestamp in UTC
  • session: Session metadata object
  • Additional event-specific data fields

Implementation Details

Retry Logic

The webhook client implements automatic retry with exponential backoff:
  • Initial attempt: Immediate
  • Retry attempts: Up to 2 additional attempts
  • Backoff strategy: Exponential (doubles wait time between retries)
  • Maximum retry window: 30 seconds total
  • Retry triggers: Network timeouts, HTTP errors, connection failures

Error Handling

  • Webhook failures are logged but never raise exceptions
  • Session operations continue normally even if webhooks fail
  • Failed webhooks are logged with error details for debugging
  • After all retries are exhausted, the failure is logged and the system moves on

Background Processing

  • Webhooks are triggered using asyncio.create_task() for non-blocking execution
  • The trigger_webhook_background() method returns immediately
  • Webhook delivery happens asynchronously without blocking the API response

Best Practices

Webhook Endpoint Implementation

Your webhook endpoint should:
  1. Respond quickly: Return a 200 status code within 5 seconds
  2. Be idempotent: Handle duplicate webhook deliveries gracefully
  3. Validate requests: Verify the request format and required fields
  4. Log events: Store webhook events for debugging and auditing
  5. Handle failures: Implement proper error handling and logging

Example Webhook Handler

from fastapi import FastAPI, Request, HTTPException
import httpx

app = FastAPI()

@app.post("/webhooks/sessions")
async def handle_session_webhook(request: Request):
    try:
        payload = await request.json()
        event_type = payload.get("event")
        session_id = payload.get("session", {}).get("id")
        
        # Process the webhook event
        if event_type == "session.created":
            # Handle session creation
            pass
        elif event_type == "task.completed":
            # Handle task completion
            pass
        # ... handle other event types
        
        # Return 200 to acknowledge receipt
        return {"status": "received"}
    except Exception as e:
        # Log error but return 200 to prevent retries
        # (or return 500 if you want retries)
        return {"status": "error", "message": str(e)}

Security Considerations

  • HTTPS: Always use HTTPS endpoints for webhook URLs
  • Authentication: Consider implementing webhook signature verification
  • Rate limiting: Be prepared to handle multiple webhooks in quick succession
  • Validation: Validate webhook payloads before processing

Monitoring

The system logs webhook delivery attempts with the following log events:
  • webhook_delivered: Successful webhook delivery
  • webhook_retry: Retry attempt (with attempt number and wait time)
  • webhook_failed_permanently: All retries exhausted
  • webhook_notification_error: Unexpected error during webhook processing
You can monitor these logs to track webhook delivery status and troubleshoot issues.

Example Usage

Creating a Session with Webhooks

import { AGIClient } from 'agi';

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

const session = await client.createSession('agi-0', {
  webhook_url: 'https://your-server.com/webhooks/sessions'
});

console.log(`Session created: ${session.session_id}`);

Handling Webhook Events

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/webhooks/sessions', methods=['POST'])
def handle_webhook():
    payload = request.json
    event_type = payload.get('event')
    session_id = payload.get('session', {}).get('id')
    
    if event_type == 'session.created':
        print(f"Session {session_id} created")
    elif event_type == 'task.completed':
        print(f"Task completed for session {session_id}")
        # Process results, update database, etc.
    elif event_type == 'task.question':
        question = payload.get('question')
        print(f"Agent asking: {question}")
        # Notify user, queue for response, etc.
    elif event_type == 'task.error':
        error = payload.get('error')
        print(f"Task error: {error}")
        # Log error, notify admins, etc.
    
    return jsonify({'status': 'received'}), 200