Skip to main content
Aura pushes live events over Server-Sent Events on a single endpoint. One connection, many topics, plain HTTP. SSE rather than WebSocket is a deliberate choice: it runs over ordinary HTTP, it reconnects automatically in every browser, and it has replay built into the protocol through Last-Event-ID. You do not need a client library, and curl works as a debugging tool.
If you are polling REST endpoints in a loop, switch to this. Polling burns your rate-limit budget to re-fetch data that mostly did not change, and it is slower at noticing the changes that matter.

Connect

topics is a comma-separated list and is the only required parameter.

Topics

Public, no session needed

Requires a session

These only work for the wallet you authenticated as. Requesting another wallet’s topics returns 403. Authenticate with a bearer token the same way as any other request:
The browser EventSource API cannot send an Authorization header. In a browser, rely on the session cookie, which is sent automatically. In Node or a bot, use fetch with a streaming response and parse the frames yourself.

Topic limits

Covering more than that means opening more connections. The limit exists because each topic is a live subscription on the server, not a filter applied to a firehose.

Event format

Every data frame arrives as event type aura with a JSON body:
Treat unknown entity values and unknown payload fields as forward compatibility rather than errors. New entities and fields get added without a version bump, and a client that throws on anything unrecognized will break on a routine release.

Heartbeats

Every 15 seconds the server sends an SSE comment:
Comments are ignored by EventSource automatically. If you are parsing frames yourself, skip lines starting with :. Their purpose is to keep proxies from timing out an idle connection, and they double as a liveness signal: no heartbeat for over 30 seconds means the connection is dead even if the socket looks open.

Reconnecting without gaps

This is the part worth getting right. Every event carries an id, and passing the last one you processed replays what you missed.
You can also pass it as ?lastEventId=84213 if setting headers is awkward. Browsers handle this natively. EventSource remembers the last id it saw and sends it on reconnect with no code from you, which is a large part of why SSE is worth the tradeoff here.

When replay is not possible

Replay works within a retention window. If you were disconnected longer than that, you get a reset frame instead of a gap:
Handle it by refetching current state from REST and resuming the stream from live:
Silently ignoring aura-reset means running on stale state indefinitely. It is the one frame you must handle, because it is the server telling you it can no longer guarantee you have seen everything.
1

Snapshot first, then stream

Fetch the order book from REST, then open the stream. Buffer events that arrive during the snapshot and apply them afterwards, discarding any whose id predates the snapshot.
2

Track the last id you applied

Persist it. On reconnect, send it as Last-Event-ID.
3

Handle aura-reset by resnapshotting

Go back to step one for that topic. Do not try to reason about what you missed.
4

Watch the heartbeat

If more than 30 seconds pass with no frame of any kind, tear down and reconnect rather than trusting the socket.

Errors

A mid-stream failure arrives as an aura-error frame and the connection closes:
Reconnect without a cursor and resnapshot.

Connection limits

Stream connections are limited to 600 per minute per IP, which is sized for reconnect storms rather than steady state. A normal client holds one connection open indefinitely and never approaches it.

Next

Integrator guide

Streaming versus polling, elevated rate limits, and bot patterns.

Place your first order

Get an order on-chain, then watch it fill on the stream.
Last modified on July 29, 2026