> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kuru.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Exchange Stats

> Read public exchange analytics and the opt-in Stats page response.

`GET /api/v1/stats` is public and read-only. No wallet or API key is required.
The page response below requires the new API and Jobhub page-publication release;
this reference does not establish deployment availability.

```http theme={null}
GET /api/v1/stats?range=24h
GET /api/v1/stats?range=30d&market=0xc9de998e272d59a19cea3783c8dd44f87a86405d
```

## Parameters

| Parameter | Meaning |
| - | - |
| `range` | Required for the page view: `24h`, `7d`, `30d`, `90d`, `all`. |
| `market` | Optional exact Kuru market address, normalized to lowercase. Omit for all markets. |

Without `range`, the existing `timeframe` / `marketAddress` analytics view and its
response contract are unchanged. Do not mix the two parameter sets. Invalid,
empty, duplicate or unknown parameters return 400; unknown market addresses return
404\. Errors use the existing error envelope and request ID.

## Page response

The page view returns an object with `data` containing:

* `range`, `bucket`, `market`, `updatedAt`, and every published market in `markets`.
* `volume`, `marketVolume`, `accounts`, `capital`, `revenue`, and `throughput`.
* `spreads`, including historical costs, the latest depth snapshot, and explicit
  `spreadAvailability` / `depthAvailability` maps.
* `metadata`, including chain identity, actual range coverage, the prior range,
  and independent section freshness.

Market entries use `id` (the address), `base`, `quote`, `logoUrl` and `listedAt`.
They are ordered by all-time volume, ties by address. All markets remain available
in selectors; any visual Other grouping belongs to the client. `listedAt` is null
until an authoritative listing timestamp is materialized. Catalog creation time
must not be presented as the listing date. Use `metadata.range.historyFrom` only
as a data-since date.

Dollar-valued fields are plain-dollar JSON numbers; counts and bps are numbers.
The backend serializes from exact arithmetic. Unknown values are nullable; never
convert them to zero. Existing analytics callers retain exact x18 string fields.

## Buckets and coverage

`24h` uses hourly buckets, `7d` and `30d` daily buckets, `90d` Monday-UTC weekly
buckets, and `all` calendar-month buckets. All chart points use the same ordered
bucket-start grid. Trader counts describe trailing unique root accounts ending
at each bucket's observed end; subaccounts are grouped by root.

Existing rolling windows and completed-hour data cutoffs remain unchanged. No
live current-hour bucket is added. Rolling ranges can intersect partial first
and last buckets, so do not enforce the seeded mock's fixed point counts.
Unavailable history is not padded with zeros.

`updatedAt` is the recorded activity publication time. The data cutoff and actual
coverage are in `metadata.range`; independent quote/depth clocks remain available.
Previous periods are null until fully observed. All-time has no prior period;
prior amounts remain null. Do not interpret a missing baseline as zero or New.
TVL previous is the qualified custody value at range start.
Annualize fees over covered seconds rather than the start of a partial month.

## Metric meanings

Volume counts each canonical fill once. Fees are actual allocated protocol
trading fees, excluding builder fees and incentive netting. Throughput counts
observed fills/sec; a taker matching several makers produces several fills.
The whole `marketVolume` object is exchange-wide even when `market` is selected;
`metadata.marketVolumeScope` states this explicitly. Other is a source-backed
remainder when all inputs are known and null when coverage is missing.
Capital is exchange-wide reconciled physical custody valued in USDC, while flows
are external USDC deposits and positive withdrawals. DAU/WAU/MAU count distinct
root accounts; missing trailing history leaves the corresponding count null.

## Venue comparisons

Venue IDs are `kuru`, `binance`, `bybit`, `jupiter`. Jupiter is a routed-swap
reference on Solana. It does not provide equivalent resting-book depth here.
Spread sizes are 1,000, 5,000 and 10,000 USDC. The spread table uses historical
round-trip cost averages, not the latest midpoint-spread sample. Existing
synchronized complete-case matching and fee/identity qualifications are retained.
Missing qualified cohorts remain unavailable. When spread publication lags
activity, the latest measured average remains visible with its own period in
`spreads.range` and independent freshness. Use per-venue market counts, not catalog
size. The common `marketCount` is null when comparison coverage differs.

Depth bands are 10, 50 and 100 bps from each book's midpoint. Curves use a shared
5-bps grid through 100 bps. Truncated, stale or unsupported values remain null.
Stale, unsupported and entirely unknown curves are empty. On a partial curve, an
unknown side also stays null at the origin. Exclude unavailable values from
rankings and leave chart gaps. Inspect availability reasons rather than assuming missing
liquidity is zero. Depth is independent of the selected range.

The client may poll every 60 seconds. Publications retain their existing job
cadence and completed-hour resolution; use per-section freshness to qualify them.

Page metrics use one database snapshot; mapped page responses are cached directly.
Cache hits still refresh freshness and withdraw expired depth amounts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.