GET /api/summary 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
| Name | Type | Required | Description |
|---|---|---|---|
format | string | No | Response format: json (default), csv, or toon |
Response
| Field | Type | Description |
|---|---|---|
generatedAt | string | ISO 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 |
assets | object[] | Asset counts grouped by (type, status) — only non-empty pairs appear, an absent pair means zero |
assets[].type | string | One of stock, crypto, etf, index, commodity |
assets[].status | string | One of pending, active, inactive |
assets[].count | number | Number of assets in this (type, status) bucket |
priceData | object[] | Per-type date envelopes from the price-data collection. Empty array when priceDataDegraded is present |
priceData[].type | string | One of stock, crypto, index, commodity (FX is reported separately under fx) |
priceData[].earliestDate | string or null | ISO YYYY-MM-DD of the oldest record for this type |
priceData[].latestDate | string or null | ISO YYYY-MM-DD of the most recent record for this type |
priceData[].totalRecords | number | Total row count across all symbols of this type |
priceDataDegraded | boolean | Present 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 |
fx | object | Single object (not array) summarising the FX collection |
fx.records | number | Total row count of FxData |
fx.earliestDate | string | ISO YYYY-MM-DD of the oldest FX record |
fx.latestDate | string | ISO 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:
/api/assets— asset rows with metadata and latest score/api/prices,/api/prices/:symbol— price coverage by symbol/api/fx,/api/fx/:symbol— FX scores and metrics/api/metrics/latest,/api/metrics/:symbol/latest— computed metric coverage
Engine-state and task-log information is not exposed here; that surface is private.
Notes
- Requires an API key.
- Designed as the single tool call backing the public ByteTree MCP’s
summarise_dataset— concise enough for an LLM to ingest in one round-trip.