Skip to content
API AccessScanner API reference

Requests and errors

Base URL, authentication, response formats, streaming, extra per-IP limits, scan costs and the errors every Scanner API route can return.

This page covers what every route in the Scanner API reference shares. The route pages link back here instead of repeating it. Key setup, scopes, rotation and plan rules are in API keys.

Base URL and authentication

Every path in the reference is served under https://api.scanner.net. Every request carries a secret key in one header, either Authorization: Bearer sk_live_... or x-api-key: sk_live_.... Call the API from a server, never from a browser.

curl "https://api.scanner.net/explorer/address/WALLET_ADDRESS" \
  -H "x-api-key: $SCANNER_API_KEY"

Don't send a key query parameter. A secret key in the URL is refused with API_KEY_IN_URL, an emb_ key together with a secret key is refused with INVALID_INPUT, and any other key value is checked as an embed key and refused with 403 EMBED_KEY_INVALID.

A key is accepted by route group, not by exact path: it works under the groups this reference covers. Account and billing paths return 403 API_KEY_ROUTE_NOT_ALLOWED, and admin routes return 403. A path inside an allowed group that doesn't exist returns 404 NOT_FOUND. A route missing from this reference may still accept a key, but only the routes listed here are documented and supported.

Response formats

Routes return JSON unless the reference says the route streams. There are three JSON shapes, and each route page says which one it uses:

  • Wrapped: { "success": true, "data": { ... } }. The explorer, holdings and wallet finder routes use it.
  • Flat with success: { "success": true, "wallets": [...], "count": 12 }. The KOL, alpha, identities, cross-chain and /v1 routes use it.
  • Bare: the result object itself, with no success field. The scan, detect and bundle routes use it.

Timestamps are ISO 8601 strings unless a field says it is unix seconds or milliseconds. Addresses on Robinhood Chain come back lowercased.

Streaming routes

Routes whose path ends in /stream answer with server-sent events (Content-Type: text/event-stream). Each event is an event: line naming it and a data: line holding JSON:

event: transactions_progress
data: {"fetched":250}

event: complete
data: {"address":"...","fundedBy":[...],"scanComplete":true}

Use curl -N (no buffering) or an SSE client. The final result arrives in the complete event, and the stream then closes.

  • An error found before the stream opens (a bad address, too few scans) is a normal JSON error with an HTTP status.
  • An error after the stream has opened arrives as an error event with the usual error body, { "error", "code", "requestId" }, and the stream closes. The HTTP status is already 200 by then.
  • Some streams send a heartbeat event every 15 seconds while work is running. Ignore it.

Errors

Errors use a standard body:

{ "error": "Invalid Solana address", "code": "INVALID_ADDRESS", "requestId": "..." }

Some errors add fields, listed in the tables. A few routes answer some errors in a different shape. Their route pages say so, so check code only when it is present. Quote requestId when you contact support.

Errors any route can return

These come from key checks and limits that run before the route itself. The route pages list only their own errors.

StatusCodeMeaning
400API_KEY_IN_URLThe key was sent in a URL. Send it in a header, and roll the key.
400INVALID_INPUTThe request carried more than one credential.
401API_KEY_INVALIDThe key doesn't exist.
401API_KEY_REVOKEDThe key was revoked, it expired, or its rotation grace period ended.
403API_KEY_BROWSER_NOT_ALLOWEDThe request came from a browser.
403API_KEY_ROUTE_NOT_ALLOWEDThe path is outside the route groups a key can call, such as account or billing.
403API_KEY_IP_NOT_ALLOWEDThe request IP isn't on the key's allowlist.
403API_PLAN_REQUIREDThe plan doesn't include API access. The body includes upgradeUrl.
403API_KEY_SCOPE_NOT_ALLOWEDThe key is limited to other endpoint groups. The body lists them in allowedRouteGroups.
403FORBIDDENAPI access is switched off for the account.
403EMBED_KEY_INVALIDThe request had a key query parameter. Remove it.
429API_KEY_RATE_LIMITEDThe key or account per-minute limit was reached. The body includes retryAfterSeconds and limit.
429RATE_LIMITEDToo many invalid keys from your IP, or one of the per-IP limits below.
500INTERNAL_ERRORSomething failed on our side. Retry, and contact support with the requestId if it keeps happening.
503INTERNAL_ERRORKey verification is briefly unavailable. Retry after a short delay.
504TIMEOUTThe request ran past the server's time limit, or an upstream data provider timed out.

Errors on paid routes

Routes that spend scans can also return these:

StatusCodeMeaning
402INSUFFICIENT_CREDITSNot enough scans left. Before the charge the body includes credits (your balance) and required.

Robinhood Chain upstream errors

Robinhood Chain explorer and scan routes read from an upstream indexer. When it is down they return 502 UPSTREAM_ERROR. Retry after a short delay.

Rate limits

Every request counts toward the key's and the account's per-minute limit, described in Rate limits. Responses include X-RateLimit-Limit and X-RateLimit-Remaining.

Per-IP limits

A few route groups also have a limit per client IP address, on top of the key limit. These limits are counted per IP, not per key, so several services or customers behind one egress IP share them. When one is reached the route returns 429 RATE_LIMITED, with the standard RateLimit headers.

RoutesLimit per IP
/explorer/*60 requests per minute
/rh/explorer/*60 requests per minute, counted apart from Solana
/wallet-finder/search, /rh/wallet-finder/search30 requests per minute per chain
POST /identities/batch60 requests per minute
GET /holdings/evm/{address}20 requests per minute
GET /scan/cachedThe scan limit, 2,000 requests per 15 minutes by default

Live origin traces (/explorer/address/{address}/origin and the Robinhood Chain equivalent) and the explorer's oldest-first transaction walk have a small extra budget per IP. See those routes.

Cost

Routes spend scans from the plan's allowance at the same price as the dashboard. Everything else is free, but still counts toward the rate limit.

RouteCost
Wallet scan, Solana or Robinhood Chain1 scan at depth 0 (Quick), 2 at depth 1 (Deep), 4 at depth 2 (Max)
Token scan, Solana or Robinhood Chain1 scan, free when a cached result is served
Multi-token scan1 scan per token without a cached result
Funding chain trace1 scan, free when a trace from the last 24 hours is cached
Cross-chain lookup1 scan for a live search, free for stored=1 and cached answers
Cached scan reads, explorer, detection, identities, holdings, wallet finder, KOL, alpha, bundles, /v1Free

Scans are charged before the work starts. A scan that fails is refunded automatically. Each route page gives the exact cache and refund rules.

View this page as Markdown