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
doneNext Steps
- WebSocket Overview -- Connection lifecycle, authentication, and limits
- Webhook Setup -- Set up reliable server-side event handling
- Best Practices -- Handle duplicate events safely