/api/sd/basis/history
GETPartialFRESH

Basis history (hourly)

Hourly basis series per exchange and as a cross-exchange aggregate (median, mean, OI-weighted) for one coin.

GET/api/sd/basis/history
Partial coverage. Collection started on 2026-11-11. The response reports `history.available_from`, `n_hours` against `expected_hours` and `complete`; hours without data are absent, not interpolated.

Request

Query parameters

NameTypeRequiredDefaultAllowed valuesDescription
coinstringRequired——Coin symbol, case-insensitive (for example `BTC`). Missing or malformed values return 400. Example: BTC
kindstringOptionalperpperp, spot_perp`perp`: mark price against the index price of the same exchange. `spot_perp`: perpetual price against the spot price of the same exchange.
rangestringOptional24h24h, 7d, 30dLook-back range, one point per hour.
exchangestringOptional——One exchange id. Default: all exchanges. An unknown id returns 400.

Example request

curl -s "https://www.coinboss.com/api/sd/basis/history?coin=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.
coinstring—Coin symbol (upper case).
kindstring—`perp` or `spot_perp`.
rangestring—Look-back range applied.
intervalstring—Spacing of the series points.
exchangestring|null—Exchange id (lower case).
aggregatearray—Cross-exchange aggregate of the section.
aggregate[]object—Cross-exchange aggregate of the section.
aggregate[].tnumbermsStart of the time bucket.
aggregate[].median_pctnumber%Median basis over one primary contract per exchange.
aggregate[].mean_pctnumber%Simple mean over the same set as the median.
aggregate[].oi_weighted_pctnumber%Basis weighted by open interest; rows without an OI weight are left out.
aggregate[].n_exchangesnumber—Exchanges in the aggregate.
seriesarray—One series per exchange.
series[]object—One series per exchange.
series[].exchangestring—Exchange id (lower case).
series[].symbolstring—Contract symbol in CoinBoss storage form.
series[].primaryboolean—True for the contract that represents its exchange in median and mean.
series[].in_aggregateboolean—True when the row passed the inclusion rules.
series[].pointsarray—`[hour start in ms, basis in %]` pairs, oldest first.
series[].points[]array—`[hour start in ms, basis in %]` pairs, oldest first.
series[].points[][]number—`[hour start in ms, basis in %]` pairs, oldest first.
historyobject—How much of the requested range is available.
history.requested_fromnumbermsStart of the requested range.
history.available_fromnumbermsFirst hour stored.
history.available_tonumbermsLast hour stored.
history.n_hoursnumber—Hours available in the range.
history.expected_hoursnumber—Hours the range holds when complete.
history.completeboolean—True when every hour of the requested range is stored.
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[].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.series.pointsstring—Formula note for `series.points`, plain text.
method.aggregate.median_pctstring—Formula note for `aggregate.median_pct`, plain text.
method.aggregate.oi_weighted_pctstring—Formula note for `aggregate.oi_weighted_pct`, plain text.
method.intervalstring—Formula note for `interval`, 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_atnull—Timestamp 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/basis/history?coin=BTC · Real response captured 2026-11-13 04:02:46 UTC. Long arrays and maps are shortened for display: series had 20 items; aggregate had 25 items; meta.source had 20 items; series[].points had 25 items; coverage.included_exchanges had 20 items.

  • {
    • "success": true,
    • "schema": "coinboss.sd.basis/1",
    • "now": 1794542288014,
    • "coin": "BTC",
    • "kind": "perp",
    • "range": "24h",
    • "interval": "1h",
    • "exchange": null,
    • "aggregate": [
      • { … 5 },
      • { … 5 }
      ],
    • "series": [
      • { … 5 },
      • { … 5 }
      ],
    • "history": {
      • "requested_from": 1794452400000,
      • "available_from": 1794452400000,
      • "available_to": 1794538800000,
      • "n_hours": 25,
      • "expected_hours": 24,
      • "complete": true
      },
    • "coverage": {
      • "included_exchanges": [ … 8 ],
      • "unavailable": [ … 2 ],
      • "stale_excluded": []
      },
    • "method": {
      • "series.points": "[hour_ts, (mark_price - index_price) / index_price * 100] from the first collector round after each full hour; hours where the two timestamps were more than 60 …",
      • "aggregate.median_pct": "median over one primary contract per exchange in that hour; excluded: |value| > 10, contracts with no trade in 24 h, exchanges whose index is not a comparable i…",
      • "aggregate.oi_weighted_pct": "sum(value * oi_usd) / sum(oi_usd) over all included contracts that have an OI snapshot for the same hour (oi_history / sd_contract_hourly, single-sided); null w…",
      • "interval": "fixed 1 h buckets, no interpolation; missing hours are simply absent"
      },
    • "meta": {
      • "schema": "coinboss.sd.basis/1",
      • "source": [ … 2 ],
      • "observed_at": null,
      • "received_at": 1794538827406,
      • "fetched_at": 1794542288014,
      • "window": "24h",
      • "quality": "FRESH",
      • "is_stale": false,
      • "cache_ttl_s": 300,
      • "fallback": "history is served as stored; hours without a snapshot are absent, never interpolated"
      }
    }

Verified samples

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

ParametersHTTPLatencyResult
coin=ETH&kind=spot_perp20041 msPass FRESH
coin=BTC&exchange=binance20032 msPass FRESH
coin=BTC&range=1y4001 msPass returns the expected error

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

Details

Authentication
None. Public endpoint.
Rate limit
1200 requests per minute per IP
Server cache
5m
Edge micro-cache
10s
Update frequency
Collector round every 60 seconds; a row is fresh for 180 seconds. Hourly snapshots feed the history.
Window
24h / 7d / 30d, hourly buckets.
Data sources
Mark price, index price and last price published by 21 derivatives exchanges, plus the spot price of the same exchange, collected and stored by CoinBoss (sd_px_latest, sd_px_hourly).
Exchange coverage
21 exchanges. Exchanges that do not publish an index or mark price are listed under `coverage.unavailable`; rows whose two price legs are more than 60 seconds apart return `null`. Rows left out of the aggregate are listed under `coverage.excluded_from_aggregate` with the reason.
Pagination
No paging; `range` bounds the number of points.
Sorting
Time ascending.
Units
All basis values in percent. Prices in the quote currency of the contract (USDT / USDC / USD). `oi_usd` single-sided.
Method
Each point is the snapshot taken in the first ten minutes of the hour. The OI weight of a historical hour is the open interest recorded in that hour; without it `oi_weighted_pct` is `null`.
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 04:02:46 UTCHTTP 2001 msSchema matchesNewest data point 63m old

Collection started on 2026-11-11. The response reports `history.available_from`, `n_hours` against `expected_hours` and `complete`; hours without data are absent, not interpolated.

Availability, last 30 days

100% of 408 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/basis/historyPartial
Parameters

string — Coin symbol, case-insensitive (for example `BTC`). Missing or malformed values return 400.

string · default perp — `perp`: mark price against the index price of the same exchange. `spot_perp`: perpetual price against the spot price of the same exchange.

string · default 24h — Look-back range, one point per hour.

string — One exchange id. Default: all exchanges. An unknown id returns 400.

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