curl -N -sS \
-H "Authorization: Bearer $OXINSIDER_API_KEY" \
'https://api.0xinsider.com/api/v1/stream'"id: 142\ndata: {\"seq\":142,\"published_at\":\"2026-06-04T12:00:00Z\",\"type\":\"WhaleTradesInserted\",\"count\":3}\n\n"Stream
Stream live feed events over Server-Sent Events, with an id on every frame so a reconnect replays what you missed.
curl -N -sS \
-H "Authorization: Bearer $OXINSIDER_API_KEY" \
'https://api.0xinsider.com/api/v1/stream'"id: 142\ndata: {\"seq\":142,\"published_at\":\"2026-06-04T12:00:00Z\",\"type\":\"WhaleTradesInserted\",\"count\":3}\n\n"whale_trades_inserted events instead, use Event replay.
Parameters
Filters are set when you connect and cannot be changed on an open connection. They apply to replayed frames and live frames alike, and a frame has to pass every filter you set.| Parameter | Description |
|---|---|
event | A comma-separated list of frame types, such as WhaleTradesInserted,wallet_grade_changed. A frame passes only when its type is in your list. An unknown name answers 400 and names the value. suspicious_trade_flagged and insider_radar_flag_raised both select the flagged-trade frames; the frame itself still carries type: insider_radar_flag_raised. |
condition_id | One market, as the raw Polymarket condition_id or its mkt_ id. A frame passes only when it carries a matching condition_id, so frames that carry none are dropped while this is set. |
min_grade | A wallet grade from S (best) to F. See Grades. Grade-change and LargeTradeInsertedV2 frames can pass. A large trade uses the trader grade captured when its event is published. Frames with no grade are dropped. |
wallet | A Polymarket wallet address. Only matching LargeTradeInsertedV2 frames pass. |
min_size | A positive dollar amount. Only LargeTradeInsertedV2 frames at least this large pass. |
Last-Event-ID | A request header holding the seq of the last frame you processed. The server replays everything after it, then goes live. |
last_event_id, seq | Query-string stand-ins for Last-Event-ID, for a client that cannot set the header. A value that is not a number attaches you live with no replay. |
Frames
| Frame | What it is |
|---|---|
A data: frame | One JSON feed envelope, carrying seq, published_at, type, and the fields for that event type. |
The SSE id: | The frame’s sequence number, shared across the whole cluster. It is the same number as seq in the JSON, and it stays valid across replicas and process restarts. |
LargeTradeInsertedV2 | One trade, with a durable trade.event_id separate from the SSE sequence. The legacy count frame remains available. |
event: resync | A marker saying the server could not cover your resume point, or that its sequence numbering restarted. Refetch current state, keep the connection open, and store the marker’s id. |
event: error | The last frame before the server closes the connection. See “When the stream ends on its own” below. |
: keep-alive | A comment line every 5 seconds on an idle connection, so nothing in between closes it. |
resync marker carries completeness.status: truncated when your resume point was older than the retained window, lagged when the stream fell behind, and reset when the server’s sequence numbering restarted while your connection was open. Frames are never skipped without one.
After a reset marker, the frames that follow carry lower id values than the frames before it. The marker’s id is one below the first of the new numbering, so storing it as your cursor resumes with nothing missed; from_sequence is the last id you were sent and to_sequence is the first of the new numbering.
How to reconnect without missing a frame
- Open the stream with
curl -Nor a browserEventSource. Sending no resume cursor attaches you to live frames, with no replay and no error. - Store each frame’s
idafter you have processed it. - On reconnect, send
Last-Event-ID: <that id>. A browserEventSourcedoes this for you. - Read the replayed frames in ascending
id, then the live frames. There is no gap inseqbetween the two. - On
event: resync, refetch current state, keep the connection open, and store the marker’sidas your cursor.
When the stream ends on its own
The key is checked when you connect, and again every 30 seconds while the connection is open. If the key is revoked, expired, or rotated, or the account that owns it is deleted, locked, or no longer subscribed, the stream ends within 40 seconds with one final frame and the connection closes:event: error
id: 9120
data: {"type":"error","error":{"code":"invalid_api_key","message":"The API key this stream was opened with is no longer valid (revoked, expired or rotated). The stream is closed; a reconnect with it is refused with 401 invalid_api_key.","doc_url":"https://docs.0xinsider.com/api-reference/introduction#authentication"},"retry":false}
error is the same object a reconnect is answered with in its response body, so one handler covers both cases. retry: false means a reconnect with the same credential is refused with that code: invalid_api_key (401), subscription_required (402), forbidden (403, a deleted account), account_locked (423), or insufficient_scope (403). Don’t reconnect: fix the credential or the account first.
There is one retryable case. If the credential store has not confirmed the key for 90 seconds, the frame carries database_unavailable and retry: true. Reconnect after error.retry_at with Last-Event-ID set to that frame’s id, and the replay covers what you missed.
A browser EventSource also fires its own error event when the connection fails, with no data, so check event.data before you parse it. @0xinsider/sdk gives you the frame from streamFeed() as an envelope with type error, and streamFeedResilient() stops on the reconnect’s 4xx.
Example
curl -N -H "Authorization: Bearer $OXINSIDER_API_KEY" \
-H "Last-Event-ID: $LAST_SEQ" \
"https://api.0xinsider.com/api/v1/stream?event=WhaleTradesInserted"
What it does not return
- An open stream past the cap of 5 connections per key, or past the cluster-wide ceiling. Over either, you get
429withRetry-After, so close the connections you are not reading. - An open stream while the admission or replay service is down. You get
503withRetry-After: reconnect after the wait. - Another account’s targeted events. Alert and following frames reach only the key that owns them.
- Frames older than the retained window. You get one
resyncmarker instead. - Recomputed Polymarket data. Each frame is the envelope 0xinsider broadcasts internally, forwarded as it is.
- Anything at all on an idle connection, apart from the keep-alive comment every 5 seconds.
- Frames after the key or the account stops authorizing the stream. You get one
event: errorframe, and then the connection closes.
Authorizations
Legacy default or named integration API key, or OAuth 2.1 access token, in the Authorization header as Bearer oxi_sk_live_... or Bearer oxi_at_.... Default keys retain full access; integration keys are limited to their approved read, webhooks, export and usage scopes and expire within 90 days. All credentials share the owner's account limits. Data calls require an active Pro subscription and return live data. A 401 carries WWW-Authenticate: Bearer resource_metadata="https://api.0xinsider.com/.well-known/oauth-protected-resource" (RFC 6750 section 3, RFC 9728).
Headers
Opt into strict query-name validation. The default is compatible: unknown names are ignored and reported in X-Query-Ignored. With strict, an unknown name returns 400 bad_request with error.reason unknown_query_parameter before the handler runs, including when its percent escape is incomplete.
strict Cluster-shared sequence id of the last frame the client successfully processed. The stream replays the strictly-newer retained window before resuming live, even when reconnect routing changes replicas. A future or expired id emits resync. Browser EventSource clients send this automatically on reconnect. Omit to attach live from now.
Query Parameters
Query-string fallback for the Last-Event-ID resume cursor when the client cannot set the request header. Numeric cluster-shared sequence id; non-numeric or absent attaches live with no replay. A future or expired id emits resync.
Alias for last_event_id. Numeric cluster-shared sequence id to resume after; non-numeric or absent attaches live with no replay. A future or expired id emits resync.
Optional per-connection subscribe-time filter. Comma-separated list of frame wire types (the SSE 'type' discriminator, e.g. WhaleTradesInserted,wallet_grade_changed); a frame passes only when its type is in the set. An unknown token returns HTTP 400 naming the offending value. An empty/all-whitespace value is treated as absent (no constraint). Applied to BOTH the replay window and live frames, and always AFTER the per-subscriber privacy gate, so it can never widen visibility beyond what the key may already see. Combines with condition_id and min_grade as a logical AND; an absent param adds no constraint.
Optional per-connection subscribe-time filter. Raw provider condition_id or mkt_-prefixed market id (normalized the same way the other v1 market endpoints normalize). A frame passes only when it carries a matching condition_id field; frames that carry no condition_id (e.g. whale-pulse events) are EXCLUDED while this is set. An empty value after normalization returns HTTP 400. Combines with event and min_grade as a logical AND; an absent param adds no constraint.
Optional per-connection subscribe-time filter. A frame passes only when it carries a grade field whose grade is better-or-equal to this minimum (S is best). Frames without a grade (every frame except wallet_grade_changed and LargeTradeInsertedV2) are excluded. An invalid grade returns HTTP 400. Combines with the other filters as a logical AND.
S, A, B, C, D, F Filter LargeTradeInsertedV2 frames to this Polymarket wallet. Other event types have no wallet and are excluded when set. Applied to live and retained Redis frames after privacy checks.
^0x[a-fA-F0-9]{40}$Filter LargeTradeInsertedV2 frames to trades at or above this USD notional. Positive decimal with at most six places; other event types are excluded when set.
^[0-9]+(\.[0-9]{1,6})?$Response
Open Server-Sent Events stream. The body is an unbounded text/event-stream of frames; each data frame is a JSON feed envelope (with cluster-shared seq, published_at, type, and event-specific fields) and carries an SSE id equal to seq. resync marker frames use event: resync for expired, future, lagged, sequence-reset, or otherwise uncovered cursors. A terminal event: error frame (id: , data: { type: 'error', error: { code, message, ... }, retry: }) ends the stream when the key or account it was opened with no longer authorizes it, or when the credential store has not confirmed it within 90 seconds; the connection closes after it.
Newline-delimited SSE frames: 'id: \ndata: \n\n' for events, 'event: resync\nid: \ndata: \n\n' for resync markers, 'event: error\nid: \ndata: \n\n' as the one terminal frame when the credential stops authorizing the stream, and ': keep-alive' comment lines while idle.
Was this page helpful?