Summary

Returns a single-screen overview of the dataset — asset counts grouped by (type, status), per-type price-data date envelopes, and an FX-collection summary. Built for tools that need a quick “what does this dataset look like?” answer without unwinding to the symbol level.

Request

curl https://api.bytetree.io/api/summary

Query Parameters

NameTypeRequiredDescription
formatstringNoResponse format: json (default), csv, or toon

Response

FieldTypeDescription
generatedAtstringISO timestamp of the priceData section, which is the stalest part of the response — the precompute time when served from the snapshot, or the request time when computed live. Deliberately not the request clock: it must never look fresher than the data it describes. On a degraded response (see below) it falls back to the request time and describes nothing
assetsobject[]Asset counts grouped by (type, status) — only non-empty pairs appear, an absent pair means zero
assets[].typestringOne of stock, crypto, etf, index, commodity
assets[].statusstringOne of pending, active, inactive
assets[].countnumberNumber of assets in this (type, status) bucket
priceDataobject[]Per-type date envelopes from the price-data collection. Empty array when priceDataDegraded is present
priceData[].typestringOne of stock, crypto, index, commodity (FX is reported separately under fx)
priceData[].earliestDatestring or nullISO YYYY-MM-DD of the oldest record for this type
priceData[].latestDatestring or nullISO YYYY-MM-DD of the most recent record for this type
priceData[].totalRecordsnumberTotal row count across all symbols of this type
priceDataDegradedbooleanPresent only when true. The priceData section could not be produced for this request — see Degraded price data. Absent on healthy responses; don’t test for false
fxobjectSingle object (not array) summarising the FX collection
fx.recordsnumberTotal row count of FxData
fx.earliestDatestringISO YYYY-MM-DD of the oldest FX record
fx.latestDatestringISO YYYY-MM-DD of the most recent FX record
{
  "generatedAt": "2026-05-07T13:23:39.271Z",
  "assets": [
    { "type": "commodity", "status": "active", "count": 32 },
    { "type": "crypto",    "status": "active", "count": 3 },
    { "type": "index",     "status": "active", "count": 1 },
    { "type": "stock",     "status": "active", "count": 211 }
  ],
  "priceData": [
    { "type": "commodity", "earliestDate": "2005-01-03", "latestDate": "2026-05-07", "totalRecords": 168129 },
    { "type": "crypto",    "earliestDate": "2009-10-05", "latestDate": "2026-05-07", "totalRecords": 12043 },
    { "type": "index",     "earliestDate": "2005-01-03", "latestDate": "2026-05-07", "totalRecords": 5662 },
    { "type": "stock",     "earliestDate": "2005-01-03", "latestDate": "2026-05-07", "totalRecords": 1050910 }
  ],
  "fx": { "records": 264447, "earliestDate": "2005-01-03", "latestDate": "2026-05-07" }
}

Degraded price data

priceData spans the full price history — tens of millions of rows — so it is served from a snapshot the engine precomputes after each pipeline run rather than aggregated per request. generatedAt carries that snapshot’s timestamp.

If the snapshot is ever unavailable (the window before the first write, or a run that skipped it), the server attempts a bounded live aggregation instead. Should that also fail to finish inside its time budget, the response degrades rather than hangs or errors:

{
  "generatedAt": "2026-07-21T18:07:44.812Z",
  "assets": [ "..." ],
  "priceData": [],
  "priceDataDegraded": true,
  "fx": { "records": 264447, "earliestDate": "2005-01-03", "latestDate": "2026-05-07" }
}

The endpoint still returns 200, and assets and fx are unaffected — only priceData is dropped.

On a degraded response generatedAt is the request time, not a snapshot time — there is no snapshot to report. It describes nothing about priceData, which is empty. Read it as meaningful only when priceDataDegraded is absent.

Why the flag matters: without it, "priceData": [] is ambiguous — it could mean the dataset genuinely holds no price data. priceDataDegraded: true says “temporarily unavailable, ask again”, which is a different thing to show a user. Test for the flag’s presence, not for false — it is omitted entirely on healthy responses.

Degraded responses are sent with Cache-Control: no-store so the next call re-checks immediately instead of serving an empty section for a minute.

Caching

Healthy responses include Cache-Control: public, max-age=60. generatedAt reflects the moment the priceData section was computed, not the request moment, so it can legitimately be older than the cache window.

Degraded responses (see above) are sent no-store and are never cached.

Surface boundary

/api/summary is intentionally dataset-wide. For per-symbol coverage and field-level detail use:

Engine-state and task-log information is not exposed here; that surface is private.

Notes