Docs·Public Data API

Public Data API

Authentication and rate limits

Every endpoint is public, read-only and serves stored data only — never a provider call; a key is optional and changes the rate limit and nothing else.

Version
1.4
Updated
2026-09-26
Source
Public Data API library

Authentication#

Credentials
QuestionAnswer
Which endpoints need credentials?None. Every endpoint under /api/v1 is public and read-only.
Which accept an optional credential?All of them, as an X-API-Key request header. It changes the rate limit and nothing else — not the data, not the fields, not which endpoints answer.
How is a key obtained?By asking. Keys are issued by hand and held in this deployment’s configuration — there is no self-service portal. A key that was not issued for the environment you are calling is not recognised there.
What happens to an unrecognised key?The request is served, and rate-limited as anonymous. The response says so: x-thehood-api-key-status: unrecognised. Nothing is rejected and no data changes.
Are cookies or bearer tokens accepted?No. CORS advertises access-control-allow-origin: * with no allow-credentials, and the only request headers accepted on a preflight are content-type, if-none-match and x-api-key.
Is any endpoint write-capable?No. Every route exports GET and OPTIONS only.

Stored data only#

Stored data only
The APIRule
ServesOnly data already stored in The Hood’s own database — the indexer’s views, read over a read-only connection
Never callsA provider on your behalf — no RPC node, price feed, explorer or social API is reached by any /api/v1 request. Chain head is never read
Never fetches on a missData we have not stored is refused with API_V1_DATA_NOT_STORED, naming what is stored. It is not fetched, back-filled or proxied
Never exposesOur provider keys, endpoints or their error text — in a body, a header or an error
X-API-KeyA key for this API’s rate limit. It unlocks no provider and no extra data

What is public, and what is not#

Rate limits and keys#

Limits
TierIdentified byRequests per minute
anonymousThe first entry of X-Forwarded-For, else X-Real-IP, else one shared bucket60
freeAn X-API-Key header carrying a key issued for this deployment. An unrecognised value is counted as anonymous, in the caller’s own IP bucket.600
pro, businessAn issued key configured onto that tier600

The counter lives in memory per function instance, so the effective limit is the figure above multiplied by however many instances are serving, and it resets when an instance is recycled. That is stated rather than hidden: a limit that is quietly ten times what it claims is a limit nobody can reason about. It still does the job it exists for, which is stopping one client opening a hundred concurrent connections against the reader from a single instance.

Headers on every response, including the 429
HeaderValue
x-ratelimit-limitThe tier’s limit
x-ratelimit-remainingRequests left in this window, floored at 0
x-ratelimit-resetUnix seconds at which the window ends
x-thehood-api-tieranonymous or the keyed tier
x-thehood-api-key-statusabsent (no header sent), recognised, or unrecognised (sent, not honoured, counted as anonymous)

A refused request is a 429 with code API_V1_RATE_LIMITED, and its details carry path, tier, limit, remaining, resetAt, resetAtIso, retryAfterSeconds — the exact wait, in the body — plus apiKeyStatus, apiKeyLabel and apiKeyFingerprint, the first 8 hex characters of the key’s SHA-256. The key itself is never echoed, in the body or anywhere else; hash your own copy to confirm which one was used.