/api/sd/etf/funds
GETPartialPARTIAL

Spot ETF funds

One row per registered fund of an asset: issuer, as-of date, holdings, net assets, shares, NAV, market price, premium, fee and CoinBoss-computed flow, or the reason the fund cannot be collected.

GET/api/sd/etf/funds
Partial coverage. Partial coverage: several large issuers do not offer a public machine-readable disclosure that can be collected from a server. Their funds are listed as unavailable, and totals cover the remaining funds only. Compare `funds_covered` / `funds_total` before comparing totals with other sources.

Request

Query parameters

NameTypeRequiredDefaultAllowed valuesDescription
assetstringRequired—BTC, ETH, SOL, HYPEUnderlying asset, case-insensitive. `coin` is accepted as an alias. Example: BTC

Example request

curl -s "https://www.coinboss.com/api/sd/etf/funds?asset=BTC"

Response fields

The field table is generated from real responses, so it lists exactly what the endpoint returns. Paths use a[] for array items and {*} for objects keyed by a dynamic name such as a coin or an exchange.

FieldTypeUnitDescription
successboolean—true when the request succeeded. On failure the body is `{ success: false, code, error, request_id }`.
schemastring—Schema id of this response. It changes only when an existing field changes meaning or type.
nownumbermsServer time when the response was built.
assetstring—Underlying asset.
as_ofstring—Newest issuer as-of date among covered funds.
expected_as_ofstring—Most recent US trading day whose publication deadline has passed.
funds_totalnumber—Funds registered for the asset.
funds_coverednumber—Funds with fresh issuer data.
fundsarray—One row per registered fund, including funds that cannot be collected.
funds[]object—One row per registered fund, including funds that cannot be collected.
funds[].tickerstring—Fund ticker.
funds[].issuerstring—Fund issuer id.
funds[].namestring—Fund name.
funds[].statusstring—OK, STALE, ERROR or UNAVAILABLE.
funds[].as_of_datestring|null—Issuer as-of date of the row.
funds[].holdings_coinnumber|nullcoinCoins held, as disclosed by the issuer.
funds[].holdings_usdnumber|nullUSDMarket value of the holdings, as disclosed by the issuer.
funds[].ref_pricenumber|nullUSDReference price per coin used by the issuer.
funds[].aum_usdnumber|nullUSDNet assets of the fund.
funds[].aum_srcstring|null—How net assets were obtained: `reported`, `nav_x_shares` or `holdings_mv_sum`.
funds[].shares_outnumber|nullsharesShares outstanding.
funds[].shares_srcstring|null—How shares outstanding were obtained: `reported` or derived from net assets and NAV.
funds[].navnumber|nullUSDNet asset value per share.
funds[].market_pricenumber|nullUSDClosing market price per share.
funds[].premium_pctnumber|null%Premium (+) or discount (−) of market price to NAV, as published by the issuer.
funds[].fee_pctnumber|null%Sponsor fee per year; `null` when not published.
funds[].flow_usdnumber|nullUSDNet creation / redemption of the fund on its flow date. CoinBoss method.
funds[].flow_sharesnumber|nullsharesChange in shares outstanding.
funds[].flow_coinnullcoinChange in coin holdings; includes fee accrual paid in coin, informational only.
funds[].flow_methodstring|null—Formula used: `shares_x_nav` or `aum_nav_ratio_t1`.
funds[].flow_as_ofstring|null—Date the flow is booked on.
funds[].flow_obs_datestring|null—As-of date of the newer of the two rows used.
funds[].flow_prev_datestring|null—As-of date of the older of the two rows used.
funds[].flow_notestring|null—Why the flow is missing or special (for example `no_previous_row`, `multi_day_gap`).
funds[].is_staleboolean|null—True when the data is older than its fresh window.
funds[].source_urlstring|null—Issuer endpoint the row was collected from (lineage only).
funds[].observed_atnumber|nullmsTimestamp given by the source for the data.
funds[].received_atnumber|nullmsTime the CoinBoss collector received the data.
funds[].unavailable_reasonstring|null—Reason code when the fund cannot be collected.
funds[].unavailable_detailstring|null—Explanation when the fund cannot be collected.
coverageobject—What is and is not included in the numbers. Compare this before comparing totals with another source.
coverage.included_exchangesarray—Sources whose fresh data is included.
coverage.included_exchanges[]string—Sources whose fresh data is included.
coverage.unavailablearray—Sources that could not be included, each with a reason. They are never counted as 0.
coverage.unavailable[]object—Sources that could not be included, each with a reason. They are never counted as 0.
coverage.unavailable[].exchangestring—Exchange id (lower case).
coverage.unavailable[].issuerstring—Fund issuer id.
coverage.unavailable[].reasonstring—Machine-readable reason code.
coverage.unavailable[].detailstring—Human-readable explanation of the reason.
coverage.stale_excludedarray—Rows left out because their last update is outside the fresh window. empty in the samples used to generate this table
methodobject—Plain-text statement of the formulas used for this response, one entry per field.
method.holdings_coin_totalstring—Formula note for `holdings_coin_total`, plain text.
method.aum_usd_totalstring—Formula note for `aum_usd_total`, plain text.
method.net_flow_usdstring—Formula note for `net_flow_usd`, plain text.
method.net_flow_missingstring—Formula note for `net_flow_missing`, plain text.
method.flow_coinstring—Formula note for `flow_coin`, plain text.
method.premium_pctstring—Formula note for `premium_pct`, plain text.
method.is_stalestring—Formula note for `is_stale`, plain text.
method.unitsstring—Formula note for `units`, plain text.
metaobject—Lineage and freshness of this response.
meta.schemastring—Schema id of this response. It changes only when an existing field changes meaning or type.
meta.sourcearray—Upstream public endpoints the data was collected from.
meta.source[]object—Upstream public endpoints the data was collected from.
meta.source[].exchangestring—Exchange id (lower case).
meta.source[].endpointstring—Public endpoint of the source the collector reads (shown for lineage; clients never call it).
meta.observed_atnumbermsTimestamp given by the source for the data.
meta.received_atnumbermsTime the CoinBoss collector received the data.
meta.fetched_atnumbermsTime this response was assembled.
meta.windowstring—Time window the numbers cover.
meta.qualitystring—FRESH, PARTIAL, STALE, BROKEN or UNAVAILABLE, judged from data timestamps and coverage.
meta.is_staleboolean—True when the data is older than its fresh window.
meta.cache_ttl_snumbersCache lifetime of this response.
meta.fallbackstring—What the endpoint returns when the collector or a source fails.

Generated 2026-11-11 23:00 UTC from 3 real responses.

Example response

/api/sd/etf/funds?asset=BTC · Real response captured 2026-11-13 03:58:17 UTC. Long arrays and maps are shortened for display: funds had 12 items; meta.source had 5 items; coverage.unavailable had 7 items.

  • {
    • "success": true,
    • "schema": "coinboss.sd.etf/1",
    • "now": 1794542297570,
    • "asset": "BTC",
    • "as_of": "2026-11-12",
    • "expected_as_of": "2026-11-11",
    • "funds_total": 12,
    • "funds_covered": 5,
    • "funds": [
      • { … 30 },
      • { … 30 }
      ],
    • "coverage": {
      • "included_exchanges": [ … 5 ],
      • "unavailable": [ … 2 ],
      • "stale_excluded": []
      },
    • "method": {
      • "holdings_coin_total": "sum of issuer-reported coin holdings over covered (non-stale) funds only; NOT a whole-market total, see funds_covered/funds_total",
      • "aum_usd_total": "sum of fund net assets (USD) over covered funds; aum_src per fund: reported | nav_x_shares (NAV x shares outstanding) | holdings_mv_sum (sum of issuer holdings …",
      • "net_flow_usd": "own method, per fund between two consecutive issuer as-of rows: shares_x_nav = (shares_out[t] - shares_out[t-1]) x NAV[t], dated t; aum_nav_ratio_t1 (issuer pub…",
      • "net_flow_missing": "covered funds not included in net_flow_usd and why: no_previous_row (needs two consecutive issuer rows), t1_booking_available_next_trading_day (Franklin: flow o…",
      • "flow_coin": "holdings_coin[t] - holdings_coin[t-1]; includes daily sponsor-fee accrual paid in coin, informational only",
      • "premium_pct": "issuer-reported premium/discount to NAV in percent; null when the issuer does not publish it",
      • "is_stale": "fund as_of_date older than the trading day before expected_as_of (expected_as_of = latest NYSE trading day whose T+1 16:00 UTC publication deadline has passed)",
      • "units": "holdings in coins; aum/flow in USD; nav/market_price in USD per share; fee_pct/premium_pct in percent"
      },
    • "meta": {
      • "schema": "coinboss.sd.etf/1",
      • "source": [ … 2 ],
      • "observed_at": 1794441600000,
      • "received_at": 1794537318126,
      • "fetched_at": 1794542297570,
      • "window": "latest",
      • "quality": "PARTIAL",
      • "is_stale": false,
      • "cache_ttl_s": 300,
      • "fallback": "collector failure keeps the last issuer row with its real as_of_date; a fund whose as_of_date is more than 1 trading day behind the expected as-of is flagged is…"
      }
    }

Verified samples

Besides the example above, the probe calls this endpoint with these parameters and checks the schema each time.

ParametersHTTPLatencyResult
asset=ETH2003 msPass PARTIAL
asset=HYPE2004 msPass PARTIAL
asset=DOGE4002 msPass returns the expected error

Checked 2026-11-13 03:58:17 UTC

Details

Authentication
None. Public endpoint.
Rate limit
1200 requests per minute per IP
Server cache
5m
Edge micro-cache
10s
Update frequency
Three collector rounds per day (02:35, 10:35, 16:35 UTC). Issuers publish once per US trading day, usually the evening of the trade date.
Window
Latest issuer as-of date per fund.
Data sources
Daily disclosures published by the fund issuers themselves (holdings, net assets, shares outstanding, NAV), collected and stored by CoinBoss (sd_etf_fund_daily). Net flow is computed by CoinBoss from those disclosures.
Exchange coverage
Only funds whose issuer publishes machine-readable daily data are covered. `funds_total` and `funds_covered` state how many; every fund that is not covered is listed under `coverage.unavailable` with the reason. Totals are sums over covered funds only (`totals_scope = "covered_funds_only"`), not the whole market.
Pagination
No paging; all registered funds of the asset are returned.
Sorting
Ticker ascending.
Units
Amounts in USD; holdings in units of the underlying coin; NAV and market price in USD per share; `premium_pct` and `fee_pct` in percent.
Method
`aum_src` tells how net assets were obtained: `reported`, `nav_x_shares` (NAV × shares outstanding) or `holdings_mv_sum` (sum of the issuer's holdings market values). `flow_method` tells which flow formula was used.
Timestamps
Unix epoch milliseconds (UTC) unless the field description says otherwise
Response format
json
Stability
Stable
Available since
2026-11-11

Live status

PartialChecked 2026-11-13 03:58:17 UTCHTTP 2004 msSchema matchesNewest data point 83m old

The endpoint reports data quality PARTIAL — Partial coverage: several large issuers do not offer a public machine-readable disclosure that can be collected from a server. Their funds are listed as unavailable, and totals cover the remaining funds only. Compare `funds_covered` / `funds_total` before comparing totals with other sources.

Availability, last 30 days

100% of 407 checks passed

Errors

Failed calls share one shape on every endpoint. The full list is on the errors page. Errors and rate limits →

CodeHTTPMeaningWhat to do
INVALID_PARAM400A required parameter is missing or a value is not accepted. `param` names the parameter when it is known.Do not retry unchanged; fix the request.
UNAUTHORIZED401The `CB-API-KEY` header was sent but the key is unknown or revoked. Public data needs no key — drop the header or use a valid key.Do not retry unchanged.
FORBIDDEN403The route is not part of the public API (internal or account-only).Do not retry.
NOT_FOUND404Unknown route, or the requested coin / exchange / fund does not exist.Do not retry; check the path and identifiers against the catalog.
RATE_LIMITED429More requests than the per-minute limit. `Retry-After` gives the seconds to wait.Wait for `Retry-After`, then retry with backoff.
INTERNAL500Unexpected server error. The message is generic by design; quote `request_id` when reporting it.Retry once after a few seconds; report it with the request id if it persists.
UPSTREAM_FAILED503The data source behind this endpoint did not answer in time. No stale or substitute numbers are returned in its place.Retry with backoff; check the status page.
UNAVAILABLE501 / 503The dataset is temporarily not ready (cache warming) or the endpoint has no lawful public source yet.Retry later; the catalog marks endpoints that are unavailable by design.
REQUEST_FAILED200Some older endpoints answer HTTP 200 with `success: false`. Always check `success`, not only the HTTP status.Depends on the message; treat as a failed request.

Try it

GET/api/sd/etf/fundsPartial
Parameters

string — Underlying asset, case-insensitive. `coin` is accepted as an alias.

Request URLhttps://www.coinboss.com/api/sd/etf/funds?asset=BTC
Choose an endpoint and press “Send request”. The response, headers and timing will appear here.