WebSockets Overview
Real-time event streaming via persistent WebSocket connections
WebSockets Overview
AgentPost provides a WebSocket endpoint for real-time event streaming. While webhooks are ideal for backend event processing, WebSockets enable live UI updates and interactive applications that need instant event delivery without HTTP request overhead.
When to Use WebSockets
| Use Case | Recommended |
|---|---|
| AI agent processing emails | Webhooks |
| Live inbox dashboard | WebSockets |
| Background email pipeline | Webhooks |
| Real-time notification feed | WebSockets |
| Reliable event processing | Webhooks |
| Interactive chat-like UI | WebSockets |
WebSockets complement webhooks -- they are not a replacement. Use webhooks for reliable, server-to-server event processing. Use WebSockets for live, client-facing experiences.
Connection Lifecycle
1. Connect
Establish a WebSocket connection to the AgentPost WebSocket endpoint. Authentication is done via a token query parameter containing your API key:
wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_here2. Subscribe
After connecting, send a subscription message to specify which events you want to receive. You can filter by event type, inbox, or environment:
{
"type": "subscribe",
"event_types": ["message.received", "message.sent"],
"inbox_id": "inb_01JQ8X5K2M3N4P5R6S7T8V9W",
"environment_ids": ["env_01JQ8X5K2M3N4P5R6S7T8V9W"]
}All filter fields are optional. Omit a field to receive all events of that dimension.
3. Receive Events
Events arrive as JSON messages on the WebSocket connection:
{
"type": "event",
"data": {
"id": "evt_01JQ8X5K2M3N4P5R6S7T8V9W",
"type": "message.received",
"timestamp": "2026-03-08T14:30:00.000Z",
"org_id": "org_01JQ8X5K2M3N4P5R6S7T8V9W",
"env_id": "env_01JQ8X5K2M3N4P5R6S7T8V9W",
"data": {
"message_id": "msg_01JQ8X5K2M3N4P5R6S7T8V9W",
"from_address": "customer@acmeco.com",
"subject": "Order inquiry"
}
}
}4. Disconnect
Close the WebSocket connection when you're done. AgentPost cleans up subscriptions and connection tracking automatically.
Authentication
WebSocket connections authenticate using the token query parameter. This is the same API key used for REST API requests:
wss://api.agent-post.dev/ws?token=ap_sk_live_your_key_hereThe query parameter approach is used instead of HTTP headers because the WebSocket API in browsers and most SDK libraries does not support custom headers during the handshake. This is the standard pattern for WebSocket authentication and is the most compatible approach for AI agent SDKs.
The API key must have appropriate scopes for the events you subscribe to. An invalid or expired key results in an immediate connection close with a 401 error frame.
Subscription Filters
You can refine your event stream using filter parameters in the subscribe message:
| Filter | Type | Description |
|---|---|---|
event_types | string[] | Event types to receive (e.g., message.received) |
inbox_id | string | Only events for a specific inbox |
environment_ids | string[] | Only events for specific environments |
Examples
All events across the organization:
{ "type": "subscribe" }Only new messages for a specific inbox:
{
"type": "subscribe",
"event_types": ["message.received"],
"inbox_id": "inb_01JQ8X5K2M3N4P5R6S7T8V9W"
}All message events in the production environment:
{
"type": "subscribe",
"event_types": ["message.received", "message.sent", "message.delivered"],
"environment_ids": ["env_01JQ8X5K2M3N4P5R6S7T8V9W"]
}Heartbeat and Keep-Alive
AgentPost uses the WebSocket protocol's native ping/pong mechanism to detect stale connections:
- The server sends a ping frame every 30 seconds
- The client must respond with a pong frame (most WebSocket libraries handle this automatically)
- If no pong is received within 10 seconds, the connection is closed
Additionally, the server sends an application-level heartbeat message:
{ "type": "ping" }You can respond with:
{ "type": "pong" }This application-level heartbeat serves as a fallback for environments where protocol-level ping/pong is not supported.
Connection Limits
AgentPost enforces a limit of 10 concurrent WebSocket connections per organization. This limit is shared across all API keys and environments within the organization.
If you exceed this limit, the new connection attempt is rejected with a close frame containing the reason "connection limit exceeded."
To manage connections efficiently:
- Share a single connection across your application when possible
- Close connections when they are no longer needed
- Use webhooks for background processing to free WebSocket slots for live UI
Error Handling
WebSocket close frames include standard close codes:
| Code | Meaning | Action |
|---|---|---|
| 1000 | Normal closure | No action needed |
| 1001 | Going away | Server shutting down; reconnect |
| 1008 | Policy violation | Authentication failed; check API key |
| 1011 | Internal error | Server error; reconnect with backoff |
| 4001 | Unauthorized | Invalid or expired API key |
| 4029 | Connection limit | Too many connections; close one first |
Next Steps
- WebSocket Quickstart -- Connect, subscribe, and receive events with code examples
- Webhooks Overview -- Compare with webhook-based event delivery