Connection flow
1
Issue a stream token
Call
POST /v1/emails/{projectId}/stream/token with a project-bound API key that has emails:send.2
Connect within 60 seconds
Open
GET /v1/emails/stream?token=... before the token expires.3
Parse SSE messages
Each JSON payload includes
type, emailId, occurredAt, and an event-specific data object.4
Reconnect deliberately
Issue a fresh token when a new connection is required.
Stream events
The current stream can emitsent, delivered, bounced, complained, opened, clicked, and unsubscribed.
Not every accepted message produces every event.
Tracking events require the corresponding tracking behavior and an observed event.
Security boundary
The stream token expires after 60 seconds for connection admission. Treat it as a secret during that window: do not write it to logs, analytics, support tickets, or persistent client storage. Do not expose the project API key in browser JavaScript to create tokens directly. Issue tokens through your authenticated server boundary when a customer-facing client needs a stream.SSE versus webhooks
Use SSE for a live interface that can tolerate reconnecting and fetching current state. Use signed webhooks for server-to-server event processing, attempt history, automatic retry, and replay. For reconciliation, retrieve the current email record by ID instead of assuming a continuously connected stream observed every past event.Webhook delivery
Use durable signed deliveries when downstream processing must survive outages.