Free ETF Flows API
Spot BTC and ETH ETF holdings read from issuer files, with net flows computed as the day-over-day change in coins held times an exchange reference price. Raw holdings are always included so you can verify the math.
Endpoints
/api/markets/etf-flows?asset=btc|eth&days=90Per-fund daily rows, newest first.
/api/markets/etf-flows/csvEverything as CSV.
Honest Limits
- We read primary issuer files only. Some issuers gate downloads behind bot protection, so per-fund coverage grows as files stay reachable rather than launching complete.
- Flow is computed, not reported: Δ coins held × our reference price at collection. Both inputs are stored per row.
- No weekend rows; issuer files update on trading days.
Response Shape
Every endpoint returns the same JSON envelope: { data, updatedAt, source, docs }. The data field is an array of records with these fields:
| Field | Type | Description |
|---|---|---|
| date | string (date) | File date |
| ticker | string | Fund ticker (IBIT, ETHA...) |
| issuer | string | Issuer name |
| asset | string | btc or eth |
| holdings | string | null | Coins held per the issuer file |
| flowUsd | string | null | Computed net flow vs prior day |
| aumUsd | string | null | Holdings × reference price |
Rows upsert daily after US close. A null flow means no prior-day baseline existed yet.
Numeric values arrive as strings where precision matters (prices, rates); parse with your language's decimal type for accounting-grade math. Rate limiting is fair-use per IP; a 429 response includes a Retry-After header. No authentication or API key needed. Attribution is appreciated: xoomar.com/markets.
Need more headroom? A free account raises your limit to 120 requests a minute with an X-API-Key header.
Frequently Asked Questions
Why is coverage incomplete?
How is the flow number computed?
When does it update?
What are the rate limits?
Data on this page is provided for informational purposes only and is not financial advice. See our editorial policy.