vike
API Endpoints

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.io

That 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:

EndpointHost
WEBSOCKET /v1/streamwss://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
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, so X-API-Key and X-API-KEY are 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:

SurfacePaginationField to pass back
/v1/hyperliquid/* — 18 of its 35 routeskeyset cursornextCursor
/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

NamespaceEndpointsWhat it covers
hyperliquid35Per-wallet Hyperliquid perp analytics — wallets, builders, cohorts and segments, positions, liquidations, per-coin metrics, HL candles. Half of the whole reference.
onchain15Wallets, tracing, PnL and balances; token search, screening, holders and transfers; labels. Carries the API's only non-GET route.
polymarket11Prediction-market directory, per-outcome probability candles, order books, event tape, settlements, archive discovery, and two trader routes (a wallet's profile, smart-money signals).
archive3The bulk Parquet archive — the manifest, the free daily samples, and the gated store. Two of the three need no credential.
schema3The live OpenAPI document, Swagger UI and ReDoc. All three under /v1; the bare paths 404 by design.
stream1A 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 /v1 namespaces 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 /v1 route declares a response model, so every 200 in the document is an undeclared {}. components.schemas holds exactly two entries, and both are error types.
  • It is behind the key gate. The credential check covers the whole /v1/ prefix, /v1/openapi.json included, 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.

On this page