Endpoint Overview
Every endpoint of the Vike Data API — 68 across 6 namespaces — with the base URL, the one endpoint that is not on it, and the conventions every namespace page assumes.
The Vike Data API is 68 endpoints across 6 namespaces. This page carries the rules that hold
across all of them — where they live, how you authenticate, how they are metered, how they page —
and then hands off. It lists no endpoints itself; each namespace page below does that, with one
### heading per endpoint.
The base URL
https://data.vike.ioThat is what the live OpenAPI document's own servers array declares, and it is the only host that
answers the /v1 namespaces. The same /v1 path under https://vike.io returns 404 —
measured, not inferred.
One endpoint is NOT on the base URL
One of the 68 lives on vike.io and is served by a different application. Following the
base URL cannot reach it:
| Endpoint | Host |
|---|---|
WEBSOCKET /v1/stream | wss://vike.io |
It is the sharpest edge on this reference: it is spelled /v1/stream, which looks like the /v1
base, but data.vike.io's /v1/ prefix is served by an application with no such route. It exists
only on vike.io.
It is not a separate product. It validates the same credential and spends the same hourly counter
as everything under /v1.
Authentication
Every endpoint on this reference is credential-gated. There is no keyless tier and no query-string form — the credential always travels in a header.
curl -H "X-API-Key: $VIKE_API_KEY" \
"https://data.vike.io/v1/onchain/tokens/search?q=USDC&limit=3"Two credential types are accepted, and either alone is enough:
- API key —
X-API-KEY: vk_.... Header names are case-insensitive, soX-API-KeyandX-API-KEYare the same header. - OAuth 2.1 bearer —
Authorization: Bearer vk_oat_....
One implementation validates both credentials on every surface. It tries the bearer first and falls through to the API-key header if the bearer is invalid, so a request may carry either or both. Both reach the same account.
The exception to "credential-gated" is two archive paths served outside the gate —
/archive/manifest.json and /archive/samples/. Those are on Archive.
Key creation, the OAuth discovery document, and the caching window that makes revocation take a few seconds: Authentication.
Metering
One hourly counter per credential, shared by every metered surface. MCP calls and REST calls draw from the same budget — the usage labels separate your analytics, not your allowance. There is one value, and it is stated once, on Rate limits, rather than copied here where it would rot.
Two properties worth carrying before you get there:
- Archive downloads are authenticated and recorded but do not spend the budget (since 2026-09-02). Every other endpoint on this reference costs one unit per HTTP request.
- The counter is per key, not per account. A second API key is a legitimate way to keep a bulk job from starving an interactive client. OAuth works the other way round: every OAuth token you own shares one pooled counter.
Errors
Branch on the status code, not the body. Every /v1 route maps errors the same way, and that
mapping is fixed: caller input the API rejected is a 400, an upstream failure is a 503 —
deliberately never a 200 with an empty body, because a silent empty list is indistinguishable from
"no data".
The full table of status codes, the JSON envelope, and the one surface where an auth failure arrives as HTTP 200: Errors.
422 is a real status the errors page does not list
Parameter bounds are declared on the route itself — a limit ceiling and its siblings — and
nothing intercepts a validation failure, so an out-of-range or malformed parameter gets the
framework's default 422, not the 400 an engine rejection produces. This is also why the
published spec's components.schemas holds HTTPValidationError and ValidationError: a
validation failure is the only response on the whole API whose body the spec actually describes.
Pagination
⚠ There is no single convention. Three different ones are in use, and the difference is not cosmetic — a client written against one will silently truncate against another. Verified endpoint by endpoint:
| Surface | Pagination | Field to pass back |
|---|---|---|
/v1/hyperliquid/* — 18 of its 35 routes | keyset cursor | nextCursor |
/v1/onchain/* | none — limit only, one page | — |
/v1/polymarket/* | /events only, with its own cursor format — see its page | — |
Hyperliquid pages by keyset, not offset, for two reasons: the tables behind it hold billions of
rows, so OFFSET n re-reads and discards every skipped row, and a concurrent insert shifts rows
across page boundaries. The cursor is a base64url-encoded JSON object — opaque; pass it back
verbatim. Do not parse it, and do not construct one.
onchain does not paginate at all. The namespace declares a cursor on no route. Its routes take
a limit with a per-route ceiling and return one page. If you need more than the ceiling, narrow
the window — there is no second page to ask for.
nextCursor is the only cursor spelling on the base URL. Polymarket's /events tape pages too, but with its
own field name and its own cursor format —
its page states the convention. The two are not interchangeable, and a
client that assumes one field name silently stops after the first page against the other.
Two cursor traps
A cursor is bound to the query that produced it. It carries that query's own mode and filters,
and handing one to a different endpoint — or reusing it after changing start/end — is refused
with a 400, not silently honoured. The message says which: nextCursor belongs to a different endpoint, or — when start/end moved — nextCursor belongs to a different query mode, telling
you to restart pagination without a cursor. Change a filter, restart paging.
A non-null cursor does not mean there is more data. The cursor is emitted whenever the page came
back full — exactly limit rows — so a result set that divides evenly by your limit hands you a
final cursor whose next fetch returns nothing. Stop when the cursor is null or the page is
empty — not on the cursor alone.
The namespaces
| Namespace | Endpoints | What it covers |
|---|---|---|
| hyperliquid | 35 | Per-wallet Hyperliquid perp analytics — wallets, builders, cohorts and segments, positions, liquidations, per-coin metrics, HL candles. Half of the whole reference. |
| onchain | 15 | Wallets, tracing, PnL and balances; token search, screening, holders and transfers; labels. Carries the API's only non-GET route. |
| polymarket | 11 | Prediction-market directory, per-outcome probability candles, order books, event tape, settlements, archive discovery, and two trader routes (a wallet's profile, smart-money signals). |
| archive | 3 | The bulk Parquet archive — the manifest, the free daily samples, and the gated store. Two of the three need no credential. |
| schema | 3 | The live OpenAPI document, Swagger UI and ReDoc. All three under /v1; the bare paths 404 by design. |
| stream | 1 | A credential-gated live bar WebSocket. ⚠ Different host (wss://vike.io), and invisible to the spec — OpenAPI has no WebSocket operation to emit. |
Six namespaces, 68 endpoints — the 61 operations of the OpenAPI document plus the
archive's three, the schema's three and the WebSocket. Two of the six are documentation buckets rather than URL prefixes:
there is no /v1/schema/ and no /v1/stream/ under the base URL. Those pages group surfaces that
exist; they do not name a path segment.
hyperliquid 35, onchain 15 and polymarket
11 are the routes each /v1 namespace declares, rendered from the API's
own OpenAPI document at build time; archive 3 is the three archive paths; schema 3 is the
OpenAPI document plus its two rendered views; stream 1 is the WebSocket on vike.io.
What this reference can and cannot do
You cannot generate a client from the published spec
GET https://data.vike.io/v1/openapi.json is real and current, but it will not carry a code
generator, for three reasons that compound:
- It leaves out the archive, the schema views and the WebSocket. It is the framework's own document for the application that
serves the three
/v1namespaces on this reference, and it sees nothing else here — not the WebSocket on the other host, not the file-served archive. - It declares no response schemas. No
/v1route declares a response model, so every 200 in the document is an undeclared{}.components.schemasholds exactly two entries, and both are error types. - It is behind the key gate. The credential check covers the whole
/v1/prefix,/v1/openapi.jsonincluded, so a prospective user cannot read the spec before holding a credential.
The spec describes parameters well and payloads not at all. Where a namespace page states a response field, it was read from a real response; where a page does not state one, we did not have one to show you. That is why these pages print few example bodies.
So this reference is hand-written — one page per namespace, one ### heading per endpoint. Each
heading carries the method and full path, what the endpoint returns and when you would call it, and
its parameters where the route signature determines them. Where a signature does not determine them,
the page says so rather than guessing.
Freshness
How current each Data API answer is: the provisional hourly row, the freshness block, the position-match gate, snapshot age and the archive manifest.
Hyperliquid REST
Every endpoint under /v1/hyperliquid — per-wallet perp history, cohort positioning, builder-code economics, liquidations and candles. The largest namespace, and the one whose vocabulary costs the most to get wrong.