AgentPost
WebSockets

WebSocket Quickstart

Connect to AgentPost's WebSocket endpoint and start receiving real-time events

WebSocket Quickstart

This guide shows you how to connect to AgentPost's WebSocket endpoint, subscribe to events, and handle incoming messages in your application.

Connect and Subscribe

import AgentPost from '@agentpost/sdk';

const client = new AgentPost({ apiKey: 'ap_sk_live_your_key_here' });

// Connect to the WebSocket endpoint
const ws = client.realtime.connect();

ws.on('open', () => {
  console.log('Connected to AgentPost WebSocket');

  // Subscribe to message events for a specific inbox
  ws.subscribe({
    events: ['message.received', 'message.sent'],
    inbox_id: 'inb_01JQ8X5K2M3N4P5R6S7T8V9W',
  });
});

ws.on('event', (event) => {
  switch (event.type) {
    case 'message.received':
      console.log(`New email from ${event.data.from_address}`);
      console.log(`Subject: ${event.data.subject}`);
      break;
    case 'message.sent':
      console.log(`Email sent to ${event.data.to_addresses.join(', ')}`);
      break;
  }
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});

ws.on('close', (code, reason) => {
  console.log(`Disconnected: ${code} ${reason}`);
});
from agentpost import AgentPost

client = AgentPost(api_key="ap_sk_live_your_key_here")

# Connect and stream events
for event in client.realtime.stream(
    events=["message.received", "message.sent"],
    inbox_id="inb_01JQ8X5K2M3N4P5R6S7T8V9W",
):
    if event.type == "message.received":
        print(f"New email from {event.data['from_address']}")
        print(f"Subject: {event.data['subject']}")
    elif event.type == "message.sent":
        print(f"Email sent to {', '.join(event.data['to_addresses'])}")
# Using wscat (install with: npm install -g wscat)
wscat -c "wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_here"

# Once connected, send a subscription message:
> {"type":"subscribe","event_types":["message.received","message.sent"]}

# You'll see events as they arrive:
< {"type":"event","data":{"id":"evt_01JQ8X","type":"message.received","data":{"from_address":"[email protected]","subject":"Help needed"}}}

Raw WebSocket Connection

If you prefer to use the WebSocket API directly without the SDK:

const API_KEY = 'ap_sk_live_your_key_here';
const WS_URL = `wss://api.agent-post.dev/ws?token=${API_KEY}`;

const ws = new WebSocket(WS_URL);

ws.onopen = () => {
  console.log('Connected');

  // Subscribe to events
  ws.send(JSON.stringify({
    type: 'subscribe',
    event_types: ['message.received'],
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);

  if (message.type === 'ping') {
    // Respond to heartbeat
    ws.send(JSON.stringify({ type: 'pong' }));
    return;
  }

  if (message.type === 'event') {
    console.log('Event received:', message.data.type);
    console.log('Payload:', message.data);
  }
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = (event) => {
  console.log(`Disconnected: ${event.code} ${event.reason}`);
  // Implement reconnection logic
};
import websockets
import asyncio
import json

API_KEY = "ap_sk_live_your_key_here"
WS_URL = f"wss://api.agent-post.dev/ws?token={API_KEY}"


async def listen():
    async with websockets.connect(WS_URL) as ws:
        # Subscribe to events
        await ws.send(json.dumps({
            "type": "subscribe",
            "event_types": ["message.received"],
        }))

        async for raw_message in ws:
            message = json.loads(raw_message)

            if message["type"] == "ping":
                await ws.send(json.dumps({"type": "pong"}))
                continue

            if message["type"] == "event":
                event = message["data"]
                print(f"Event: {event['type']}")
                print(f"Data: {event['data']}")


asyncio.run(listen())
# Using websocat (install from https://github.com/vi/websocat)
echo '{"type":"subscribe","event_types":["message.received"]}' | \
  websocat "wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_here"

Filtering by Environment

In multi-environment setups, filter events to a specific environment to avoid mixing production and development data:

// Only receive events from the production environment
ws.subscribe({
  events: ['message.received', 'message.bounced'],
  environmentIds: ['env_01JQ8X_production'],
});

// Or filter by both environment and inbox
ws.subscribe({
  events: ['message.received'],
  inbox_id: 'inb_01JQ8X_support',
  environmentIds: ['env_01JQ8X_production'],
});
# Only receive events from the production environment
for event in client.realtime.stream(
    events=["message.received", "message.bounced"],
    environment_ids=["env_01JQ8X_production"],
):
    print(f"{event.type}: {event.data}")

# Or filter by both environment and inbox
for event in client.realtime.stream(
    events=["message.received"],
    inbox_id="inb_01JQ8X_support",
    environment_ids=["env_01JQ8X_production"],
):
    print(f"{event.type}: {event.data}")
# Subscribe with environment filter using wscat
wscat -c "wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_here"

# Send subscription with environment_ids:
> {"type":"subscribe","event_types":["message.received"],"environment_ids":["env_01JQ8X_production"]}

Handling Reconnection

WebSocket connections can drop due to network issues, server restarts, or idle timeouts. Implement reconnection with exponential backoff:

class ReconnectingWebSocket {
  private ws: WebSocket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 10;
  private baseDelay = 1000; // 1 second

  constructor(
    private url: string,
    private onEvent: (event: any) => void,
  ) {
    this.connect();
  }

  private connect() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      console.log('Connected');
      this.reconnectAttempts = 0;

      this.ws!.send(JSON.stringify({
        type: 'subscribe',
        event_types: ['message.received'],
      }));
    };

    this.ws.onmessage = (event) => {
      const message = JSON.parse(event.data);

      if (message.type === 'ping') {
        this.ws!.send(JSON.stringify({ type: 'pong' }));
        return;
      }

      if (message.type === 'event') {
        this.onEvent(message.data);
      }
    };

    this.ws.onclose = () => {
      this.reconnect();
    };
  }

  private reconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('Max reconnection attempts reached');
      return;
    }

    const delay = this.baseDelay * Math.pow(2, this.reconnectAttempts);
    console.log(`Reconnecting in ${delay}ms...`);

    setTimeout(() => {
      this.reconnectAttempts++;
      this.connect();
    }, delay);
  }

  close() {
    this.maxReconnectAttempts = 0; // Prevent reconnection
    this.ws?.close();
  }
}

// Usage
const rws = new ReconnectingWebSocket(
  `wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_here`,
  (event) => {
    console.log(`New event: ${event.type}`, event.data);
  },
);
import asyncio
import json
import websockets

API_KEY = "ap_sk_live_your_key_here"
WS_URL = f"wss://api.agent-post.dev/ws?token={API_KEY}"
MAX_RECONNECT_ATTEMPTS = 10


async def listen_with_reconnect():
    attempt = 0

    while attempt < MAX_RECONNECT_ATTEMPTS:
        try:
            async with websockets.connect(WS_URL) as ws:
                attempt = 0  # Reset on successful connection
                print("Connected")

                await ws.send(json.dumps({
                    "type": "subscribe",
                    "event_types": ["message.received"],
                }))

                async for raw_message in ws:
                    message = json.loads(raw_message)

                    if message["type"] == "ping":
                        await ws.send(json.dumps({"type": "pong"}))
                        continue

                    if message["type"] == "event":
                        print(f"Event: {message['data']}")

        except (websockets.ConnectionClosed, ConnectionError) as e:
            attempt += 1
            delay = min(2 ** attempt, 60)
            print(f"Disconnected: {e}. Reconnecting in {delay}s...")
            await asyncio.sleep(delay)

    print("Max reconnection attempts reached")


asyncio.run(listen_with_reconnect())
# Simple reconnection loop with wscat
while true; do
  echo "Connecting..."
  wscat -c "wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_here" \
    -x '{"type":"subscribe","event_types":["message.received"]}'

  echo "Disconnected. Reconnecting in 5s..."
  sleep 5
done

Next Steps

On this page