Search and streams
Search everything vike knows by name, symbol or address, and the tools that help an agent use the event streams - the channel and filter registry, a filter check, the stored events and your own connections.
5 tools that span the products: search, the vike.io search box as a tool, and four
for the event streams at wss://stream.vike.io/v1/stream/<path>. An agent cannot
hold a WebSocket open; these let it describe one, check a subscription before a program sends it, read what a channel
carried, and see your own connections.
search
1 credit. Find tokens, Hyperliquid markets, traders, vaults and builders, labelled wallets and entities on four
chains, Polymarket wallets and markets by one query: the same search as the box on vike.io and as
GET /v1/search.
| Parameter | Type | Default | Notes |
|---|---|---|---|
q | string | required | What to look for, 1 to 256 characters: a name, symbol, label, address, ENS name or polymarket.com link. |
limit | integer | 5 | Rows per section, 1 to 20 (default 5). |
Returns {tokens, hl_markets, wallets, traders, vaults, builders, polymarket, markets, did_you_mean}, each a list of
at most limit rows. q may be free text, a 0x address (also inside a pasted URL), an ENS name (searched as the
address it points to) or a polymarket.com link (its market). A type word such as cex, bridge or hacker lists that
type's biggest entities; an entity row has wallet_count and url, the vike.io page listing its wallets, and an
address only when the entity is one wallet (a group of wallets has no single address). Several Polymarket markets
of one event come back as one row, {event_slug, title, markets_n}. did_you_mean holds coins one typo away when no
token matched, and closed Polymarket markets appear only when nothing else did. Unlike the website, the tool does not
find a Polymarket trader by X handle and returns no handle: Polymarket's terms keep them off the API. A section whose
read fails is an empty list rather than an error, so an empty section is not proof of no match. url fields are
vike.io paths.
What is the address of Wintermute, and is it on Hyperliquid too?
Find the Polymarket market about the next Fed rate decision.
stream_info
Free — 0 credits. How to use the streams, read off the stream server's own registry: every path and its
channels; for each channel its filter keys, each a list (with its maximum length), one value, a number (min_usd and
the other min_ keys) or a boolean (contract: true or false, never the string "true"), with the allowed
values or the server's own message for a bad one, and its defaults (hl.fills gets min_usd: 1000 unless one is
given); the REST catch-up route of each path; the limits (one connection per API key and three per account on each
path, the newest winning with close 4410; 100 subscriptions per connection; a ping every 15 seconds); the close
codes; the 3-day cursor retention; how to authenticate (the X-API-KEY header, or Authorization: Bearer; ?token=
only for a browser, which cannot set WebSocket headers, as a key in a URL can end up in logs); and the subscribe
message's shape. It takes no parameters.
Which stream channels can I filter by wallet, and what values does
pnl_cohorttake?
stream_check_filter
Free — 0 credits. Validate a subscribe message, or a channel and filter, with the same validator the stream
server runs, without connecting.
| Parameter | Type | Default | Notes |
|---|---|---|---|
message | object | — | A whole subscribe message, e.g. {"action": "subscribe", "id": "w1", "channel": "hl.fills", "filter": {"coin": ["BTC"]}}. Or give channel and filter instead. |
channel | string | — | A stream channel, e.g. hl.fills, hl.liquidations, chain.transfers, pm.trades; stream_info lists them all. Used when message is not given. |
filter | object | — | The filter object, e.g. {"wallet": ["0x..."], "min_usd": 50000}. Used when message is not given. |
path | enum | — | The endpoint the connection would use. Default: the channel's own path. One of hl, hl-cohorts, onchain, polymarket. |
Returns {valid: true, url, subscribe}, where subscribe.filter is exactly what the server will apply (values
normalised, lists sorted, defaults added), or {valid: false, code, message} with the server's own error:
bad_subscription naming the key, or unknown_channel listing the channels of the path. path checks the channel
against the endpoint the connection would use: a channel of another path is unknown_channel there.
Is this subscription valid: hl.fills, coin BTC and ETH, min_usd 250000?
stream_events
1 credit. The stored events of one channel after a cursor, oldest first, with the stream's own filters: what a socket missed, or a look at a channel without one.
| Parameter | Type | Default | Notes |
|---|---|---|---|
channel | string | required | A stream channel, e.g. hl.fills, hl.liquidations, chain.transfers, pm.trades; stream_info lists them all. Required. |
cursor | string | — | next_cursor of the previous page or the cursor of a stream frame. Omit (and omit since_ms) for the oldest retained event. |
since_ms | integer | — | Epoch MILLISECONDS: start after this arrival time instead of a cursor. Not together with cursor. |
filter | object | — | The channel's filter keys as on a subscribe, e.g. {"coin": ["BTC"], "min_usd": 100000}. An unknown or channel-foreign key is refused. |
limit | integer | 200 | Events per page, 1 to 1000 (default 200). |
Returns {events: [{cursor, event}], next_cursor, has_more}; event is what the WebSocket frame carried. An idle
window of the channel (channels run on demand) is an item {cursor, gap} in its place. Pass next_cursor back as
cursor; at the end of the data a page returns the channel head, so an empty page on a quiet channel returns the same
cursor. Events are kept 3 days: an older cursor is refused, and the message names one to resume from. since_ms starts
after an arrival time instead of a cursor. Delivery is at least once, so drop a repeat by event.event_id.
hl.fills without min_usd is min_usd: 1000, as on the socket; 0 is every fill. Every channel stream_info lists
is accepted, including one the stream does not run yet (a subscribe there answers unknown_channel): its pages are
empty, like a quiet channel's.
Show the Hyperliquid liquidations over $1M in the last hour.
stream_connections
Free — 0 credits. Your own recent stream connections, newest first: every API key and OAuth app of your account, and nobody else's.
| Parameter | Type | Default | Notes |
|---|---|---|---|
hours | integer | 168 | How far back to look, 1 to 720 hours (default 168, a week). A connection opened before it is not listed. |
limit | integer | 50 | Connections to return, newest first, 1 to 1000 (default 50). |
Returns {connections, open, total, window_hours, truncated, source}; a connection carries path, url, api_key_id (or
oauth_client_id), connected_at, state (open or closed), its subscribe count and, once closed, closed_at,
duration_s, its channels, close_code and events_sent. It is reconstructed from the connect, subscribe and close
records the stream writes, not read from the stream's live state, and it may lag a few seconds: open means no close
has been recorded yet (a server crash records none), and an open connection's channels are named only when it closes.
truncated is true when only the newest records of the window could be read, so its oldest connections are missing.
Use it to see why a socket was closed: two programs on one key close each other with 4410
(One connection per key). To move a stream elsewhere, connect the
new client with the same key: the newest connection replaces the older one.
Why does my stream connection keep closing with 4410?