Event Streaming (SSE)
Subscribe to real-time Sui events via Server-Sent Events. Events are pushed to your client as they are indexed — no polling required.
Use GET /v1/events for batch queries, historical lookups, and pagination. Use GET /v1/events/stream for live dashboards, real-time alerts, and continuous processing where low latency matters.
Endpoint
GET http://127.0.0.1:3001/v1/events/stream?package=<PACKAGE_ID>Query Parameters
| Parameter | Required | Description |
|---|---|---|
| package | Yes | Sui package ID or MVR name |
| event_type | No | Filter by event type |
| sender | No | Filter by sender address |
| token | No | Short-lived JWT for browser auth (see Token Exchange below) |
Authentication
Two authentication methods are supported. Use whichever fits your environment.
API Key (server-side)
Pass your API key in the x-api-key header. Works with curl, SDKs, and any HTTP client that supports custom headers.
curl -H "x-api-key: YOUR_API_KEY" \
"http://127.0.0.1:3001/v1/events/stream?package=0xYOUR_PACKAGE_ID"Stream Token (browser)
The browser EventSource API cannot set custom headers. Exchange your dashboard session for a short-lived token and pass it as a query parameter.
Token Exchange
Authenticated dashboard users can request a 60-second stream token.
// 1. Get a stream token (requires the admin session cookie)
const res = await fetch('/api/stream/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ package: '0xYOUR_PACKAGE_ID' }) // optional scope
});
const { token } = await res.json();
// 2. Connect to the SSE stream
const source = new EventSource(
`http://127.0.0.1:3001/v1/events/stream?package=0xYOUR_PACKAGE_ID&token=${token}`
);
source.addEventListener('sui.event', (e) => {
const event = JSON.parse(e.data);
console.log('New event:', event);
});Tokens expire after 60 seconds. Reconnection after expiry requires a fresh token exchange.
Event Types
The SSE stream sends typed events. Listen for specific event names using addEventListener.
| Event | Description |
|---|---|
| sui.event | A new indexed Sui event. The data field contains the full event JSON. |
| timeout | Connection closed after reaching the maximum duration (30 minutes). Reconnect to resume. |
| limit | Connection closed after delivering the maximum number of events (10,000). Reconnect to resume. |
| error | A server-side error occurred. The data field contains { error: { code, message } }. |
Reconnection
The stream includes a retry: field that tells the client the recommended reconnection interval. Each event carries an id: field. On reconnection, the browser automatically sends Last-Event-ID so the server resumes from where you left off — no duplicate events.
# Manual reconnection with curl:
curl -H "x-api-key: YOUR_API_KEY" \
-H "Last-Event-ID: <cursor from last received event>" \
"http://127.0.0.1:3001/v1/events/stream?package=0xYOUR_PACKAGE_ID"Limits
| Limit | Default |
|---|---|
| Max connection duration | 30 minutes |
| Max events per connection | 10,000 |
| Concurrent connections per API key | 5 |
| Heartbeat interval | 15 seconds |
| Stream token TTL | 60 seconds |
Node.js Example
import { EventSource } from 'eventsource'; // npm install eventsource
// EventSourceInit only exposes withCredentials and a custom fetch.
// Pass a fetch wrapper to inject the x-api-key header on every request,
// including reconnects.
const es = new EventSource(
'http://127.0.0.1:3001/v1/events/stream?package=0xYOUR_PACKAGE_ID',
{
fetch: (input, init) =>
fetch(input, {
...init,
headers: { ...init.headers, 'x-api-key': 'YOUR_API_KEY' }
})
}
);
es.addEventListener('sui.event', (e) => {
const event = JSON.parse(e.data);
console.log(`[${event.checkpoint}] ${event.eventType}`, event.data);
});
es.addEventListener('error', (e) => {
console.error('SSE error:', e.data);
});
// Graceful shutdown
process.on('SIGINT', () => es.close());- • Start with the Quickstart if you haven't registered a package yet
- • Set up Webhooks for push-based delivery to your own endpoints