Skip to main content
Every endpoint follows the same conventions for amounts, timestamps, pagination, and errors. The SDK applies all of this at the client boundary; if you call /v1 directly, you own the conversions.

Wire Format and SDK Types

A raw stats response and its SDK equivalent, side by side:
Do not test for a field with === null. An ERC-20 target has no poolId key at all, and a Uniswap v4 target has no tokenId key, so "poolId" in target and optional chaining are the safe checks. See Targets.

Mixed Time Representations

Timestamps are not uniform across the response types. startTime, endTime, and triggeredAt are bigint unix seconds. publishedAt on a claim proof is already a JavaScript Date. Applying Number(x) * 1000 to a Date produces a timestamp in the year 58563.

Every Amount Is a bigint

claimable, cumulativeAmount, accumulatedRewards, tvl, and the APY fields are all bigint. JSON.stringify(1n) throws, so logging and persistence both need a replacer.
In-memory caches like TanStack Query and SWR handle bigint fine. If you persist cache data to localStorage or IndexedDB, add a serializer pair:

Pagination

List endpoints return { data, total }. total is the full match count, not the page size, so paginate on offset until you have collected total rows.
limit defaults to 20 and caps at 100. Asking for more returns a validation error rather than silently truncating. The exception is /v1/users/{address}/balances, where limit defaults to 1000 and caps at 1000.

Caching and Polling

Responses are served from short server-side caches and update on the reward checkpoint cadence of minutes, not seconds. Cache stats reads for 60 seconds or more and keep polling modest. There is no API key, so there is nothing to raise; the ceiling is shared.

Rate Limiting

The API rate limit is 100 requests per 60 seconds, per IP. Exceeding it returns HTTP 429 with code: "RATE_LIMITED". Every response carries standard rate-limit headers, which are a better input for adaptive backoff than a hardcoded number:
Read ratelimit-remaining and slow down before you hit zero; ratelimit-reset is the seconds until the window rolls over. The SDK retries transient failures automatically (network errors, 429, and 5xx) with exponential backoff (baseDelayMs * 2^(attempt - 1), defaulting to 3 attempts and a 200 ms base). Other 4xx responses and aborted requests are never retried. The error only surfaces once the retry budget is exhausted.
Tell us if you expect sustained high-volume traffic. There is no API key, so the limit is per IP and shared; a server-side integration polling on behalf of many users hits it faster than you would expect.

Versioning

Once published, the /v1 contract changes additively only. Fields are never renamed, removed, or retyped. New fields and new endpoints may appear at any time, so parse defensively and ignore fields you do not recognise.

Keep Exploring

Errors

The error envelope, the SDK error classes, and how to handle each one.

API Reference

Every endpoint, parameter, and response schema, generated from the live spec.