Changelog

Notable changes to the ByteTree API’s public contract.

The Global Trends universe key in grouping data changed from globalTrends to global-trends-200, aligning the MCP tool layer’s vocabulary with the universe slugs used across the REST API. At the same time, Global Trends gained its own sector dimension config, so sector no longer falls back to default.

What changed

Compatibility

Breaking for MCP clients holding the old key: globalTrends/* slugs and universe: "globalTrends" no longer match any data — re-run list_grouping_configs to refresh. On the REST surface, which already speaks the customer universe slugs, the only visible change is global-trends-200/sector now resolving to Global Trends’ own config rather than returning the macro fallback (no fallback: true) — see Universes.

2026-06-12 — splits endpoints withdrawn from the public API

GET /api/splits and GET /api/splits/:symbol are no longer part of the public API surface — they have moved to ByteTree’s internal operations layer, and their documentation pages have been retired.

Why consumers don’t need them

All public OHLCV is split-adjusted by default — the splits ledger remains the internal input that drives the adjustment, so charts, scores, and returns are unaffected by corporate actions without any consumer-side handling. See Data Model for how the adjustment works and ?raw=true on GET /api/prices/:symbol for the forensic raw view.

Compatibility

Breaking for consumers of the two splits endpoints: requests to these paths now return 401. All other endpoints are unaffected.

2026-06-10 — BYT-337: API-key authentication is live

Key enforcement is now in force. Every documented endpoint requires an API key — sent as Authorization: Bearer <key> — with one exception: GET /api/health stays open as a liveness check. The Authentication page documents the full model.

What changed

Compatibility

Breaking for keyless consumers: all reads except GET /api/health now require a key. Obtain a key through your ByteTree.io account and send it as a bearer token — no other request changes are needed.

2026-05-26 — BYT-327: ByteTree MCP docs refresh — naming convention, 90-day series default, 800 KB response guard

The public ByteTree MCP documentation gets a clarity pass on three already-shipped behaviours. No engine or MCP behaviour change — this is a docs-only update.

What’s clearer now

Compatibility

Documentation-only update. No engine or MCP behaviour change.

2026-05-22 — BYT-321: weekly rolling high/low window moves 30-week → 20-week

The four persisted weekly rolling high/low metrics move from a 30-week to a 20-week window and are renamed accordingly:

localMax30wlocalMax20w, localMin30wlocalMin20w, caprMax30wcaprMax20w, caprMin30wcaprMin20w.

What changed

Compatibility

Breaking for consumers that read the weekly raw high/low fields by name: update …30w…20w. The deviation fields, all daily windows (…20d / …30d), and the 200-week entries are unaffected.

2026-05-08 — BYT-285: documenting /api/fx/:symbol/prices

The canonical close-only FX price series endpoint shipped under BYT-281 is now documented. See the endpoint page.

Why now

BYT-278’s polymorphic-FX docs cutover deliberately scoped to BYT-274’s veneer surface and skipped the dedicated FX price route. This entry closes that doc gap.

Shape

GET /api/fx/:symbol/prices returns { symbol, count, data: [{ date, close }, ...] } with optional from / to ISO date filters. Close-only by design — FX is conventionally rendered as line series and the endpoint reflects that. 404 when the symbol has no FX records.

The polymorphic /api/prices/:symbol returns the same shape for FX symbols; the new dedicated route exists for FX-only consumers that want a zero-ambiguity surface within /api/fx/*.

Compatibility

Documentation-only update. No engine or API behaviour change.

2026-05-07 — BYT-299: trend-regime transition event log

A new public, no-auth endpoint GET /api/metrics/regime-transitions returning the cross-asset event log of trend-regime changes. See the endpoint page.

What’s new

Compatibility

Additive. No effect on existing endpoints.

2026-05-07 — BYT-298: cross-sectional metric distribution endpoint

A new public, no-auth endpoint GET /api/metrics/distribution returning per-timestep summary statistics (and, where applicable, histograms) of any allow-listed metric across the asset population. See the endpoint page.

What’s new

Compatibility

Additive. No effect on existing endpoints.

2026-05-07 — BYT-297: dataset-overview endpoint /api/summary

A new public, no-auth endpoint that returns a single-screen dataset overview — asset counts grouped by (type, status), per-type PriceData date envelopes, and an FX-collection summary. See the endpoint page.

What’s new

Compatibility

Additive. No effect on existing endpoints.

2026-05-05 — BYT-283: split-adjusted OHLCV by default, raw access via opt-in

/api/prices/:symbol now returns split-adjusted OHLCV by default — open, high, low, close, and volume are all derived from our own pure-function adjustment of RawPriceData against the internal splits ledger, idempotent and immune to upstream retroactive rewrites. The previous “raw close + sidecar metadata.rawClose” pattern is replaced by a clean toggle.

What changed

Three-layer data model

A new conceptual reference page Data Model explains the three layers — RawPriceData (forensic archive, not exposed), PriceData raw fields (the provider’s evolving view, mutable), and own-computed split-adjusted OHLCV (idempotent, default) — and which view a given consumer wants.

FX

FX pairs aren’t subject to splits, so adjusted and raw views are identical. The /api/fx/* namespace and the polymorphic FX rows on /api/assets and /api/metrics therefore expose only the default values.

Compatibility

Breaking semantics for raw consumers. The fields closeUsd, capr, and marketCapUsd previously held raw values; they now hold split-adjusted values. Any consumer that needs the previous raw semantics must migrate to closeRawUsd, caprRaw, or marketCapRawUsd. There are no public consumers as of the cutover.

The OHLCV change on /api/prices/:symbol is also a semantics flip — the field names are unchanged. Consumers that explicitly want raw OHLCV must add ?raw=true.

2026-05-05 — BYT-274: polymorphic FX synthesis on /api/assets and /api/metrics

Asset and metric endpoints now resolve FX-pair symbols through a fallback path so polymorphic consumers (clients iterating across mixed asset types — stocks, crypto, FX) can use a single resolution path.

What changed

A dedicated /api/fx namespace ships alongside the polymorphic veneer as the canonical zero-ambiguity surface for FX score and metric data:

List-form metrics endpoint

The pre-existing GET /api/metrics/latest (no :symbol) gains a ?type=fx branch that returns FX-pair records derived from rate data. The endpoint returns a symbol-keyed object as data rather than an array — see the endpoint page for the envelope.

Compatibility

Additive. Pre-existing /api/assets and /api/metrics consumers see no change in behaviour for stock, crypto, etf, index, or commodity symbols. The new fx value on ?type= and the FX-symbol fallback paths extend the resolution surface without altering existing rows.

/api/rates, /api/rates/sparklines, and /api/rates/:pair remain scoped to raw OHLC rate data — no scores, no metrics. Consumers wanting computed FX metrics should use /api/fx/*.

2026-05-02 — BYT-268: ByteTrend score bin histograms on GroupMetric

Group metric responses now carry per-variant score histograms — byteTrendBins — so consumers can render distribution shape without re-deriving from the underlying assets list. Surfaces automatically on all three /api/universes read paths.

Field

byteTrendBins is a nested object with one key per ByteTrend score variant:

KeyTypeDescription
local200wnumber[6]Score histogram for Weekly Local — bins[i] = count of assets at score i
local30dnumber[6]Score histogram for Daily Local
capr200wnumber[6]Score histogram for Weekly CAPR
capr30dnumber[6]Score histogram for Daily CAPR

For each variant, sum(bins) ≤ assetCount — the gap is the number of group members whose score is null (e.g. asset hasn’t accumulated the long window yet).

"byteTrendBins": {
  "local200w": [4, 7, 27, 3, 17, 47],
  "local30d":  [11, 15, 16, 17, 10, 37],
  "capr200w":  [23, 16, 15, 16, 13, 22],
  "capr30d":   [40, 10, 18, 11, 4, 23]
}

Endpoints

Visible on every read path that returns GroupMetric rows — see Universe Groups → ByteTrend Score Bins for the canonical field reference.

Compatibility

Additive. The field is omitted (byteTrendBins: undefined) on responses that read pre-existing storage rows — callers should treat absent bins as “not yet populated”, not as zero counts.

Forward-only — backfill caveat

The daily 04:00 UTC group aggregator populates byteTrendBins going forward. GroupMetric rows aggregated before 2026-05-02 do not have the field — including the 2026-05-02 row itself, which was aggregated by the cron that ran before the engine deploy. Two paths to populate stored rows:

  1. Natural propagation — wait for the next daily aggregator run; that day’s row onwards carries bins.
  2. Manual re-aggregation — ByteTree operators can rewrite stored rows for a date range on request. Not run by default; full historical backfill is opt-in.

Time-series consumers reading multi-month responses will therefore see byteTrendBins populated only for dates from the cutover forward unless a manual backfill has been run.

2026-05-01 — pagination envelope harmonisation

Consumer-paginated list endpoints now return a richer envelope. GET /api/assets and GET /api/splits add total, limit, and offset alongside the existing count and data. This was the harmonisation pass scoped into BYT-252 that didn’t ship with the original splits cutover; closing the loose end now while the contract is still fresh. (The splits endpoints were later withdrawn from the public API — see the 2026-06-12 entry.)

Envelope

{
  "count":  10,
  "total":  4287,
  "limit":  10,
  "offset": 0,
  "data":   [ /* records on this page */ ]
}

See Response Conventions → Paginated list envelope for the canonical reference.

Endpoint changes

Unchanged

Compatibility

Additive. Callers that read only count and data are unaffected — the new fields appear alongside.

2026-04-30 — BYT-252: public splits API

Closes the BYT-238 trilogy phase 3. Two new public endpoints expose the corporate-actions data layer that drives adjusted-close computation. (Both were later withdrawn from the public API — see the 2026-06-12 entry.)

Endpoints

Data shape

Default projection: symbol, date, numerator, denominator, ratio, source. The ratio field denormalises numerator / denominator for query convenience — reverse splits have ratio < 1. Operations fields (firstSeenAt, confirmedAt, metadata) are hidden by default and opt-in via ?fields=.

Pipeline

A daily 02:00 UTC cron pulls the upstream stock-split calendar over a rolling ±90-day window into a new splits collection. Each ingested split is auto-reconciled against the price-anomaly review queue from BYT-251 phase 2 — a 'likely-split' anomaly within ±3 calendar days of a confirmed split is auto-acknowledged, populating splitId on the anomaly and confirmedAt on the split.

Trilogy completion

2026-04-28 — BYT-238 phase 1: adjusted-close backfill, monthly refresh

Time-series metrics (MAs, slopes, rolling highs/lows, ByteTrend scores, deviations, drawdowns, returns, volatility, Sharpe, beta) are now computed on adjusted close instead of raw close. Closes the hidden corruption that unaccounted-for splits introduced into trend computation (the “BKNG-style” failure: a 1-for-6 split or large dividend silently steps the entire historical series, breaking MA crossings, ATH tracking, and drawdown depth).

Rationale

The prices endpoints have always surfaced adjusted close as close (raw close in metadata.rawClose). Metrics computation was reading raw close, which meant any unrecorded split corrupted every windowed metric until the split worked its way out of the longest window. Aligning metrics with the adjustment model the prices endpoints already use means scores and drawdowns survive splits cleanly.

Renamed

OldNew
allTimeHighUsdallTimeHighAdjUsd

The new name makes the adjustment model explicit. drawdownATH keeps its name; its semantics shift to ”% below adjusted-close all-time high”.

Semantic shift (same keys)

Every time-series metric below — keys, units, and ranges unchanged — is now computed on adjusted close:

Backtest impact. Historical series for any asset that has split (or paid a large enough dividend to register in the adjustment) will differ from pre-cutover values. Backtests that join pre- and post-2026-04-28 metrics across a split will see a one-time step on the cutover day. Affected today: 211 stocks and 1 index. Commodities and crypto are unaffected — the engine sets adjClose = close for those types, so compute paths remain uniform but values are identical to pre-cutover.

Stayed on raw close

These three fields represent today’s quoted state, not a trend over time:

Added (infrastructure)

Follow-ups

2026-04-28 — BYT-241: legacy field cleanup + uniform window-suffix convention

The BYT-240 dual-write window has closed. Legacy field names emitted alongside the canonical BYT-240 surface have been removed, and a uniform window-suffix convention now applies to every window-bearing metric across the API.

Rationale

Renamed

Underlying MAs (pair-label sweep — suffix now denotes actual window):

OldNew
localMaShort200wlocalMaShort30w
caprMaShort200wcaprMaShort30w
localMaLong30dlocalMaLong200d
caprMaLong30dcaprMaLong200d

MA slopes (4 weekly + 4 daily, all newly suffixed to match their underlying MA):

localMaLong200wSlope, localMaShort30wSlope, caprMaLong200wSlope, caprMaShort30wSlope, localMaLong200dSlope, localMaShort30dSlope, caprMaLong200dSlope, caprMaShort30dSlope (was localMaLongSlope, localMaShortSlope, caprMaLongSlope, caprMaShortSlope).

Rolling highs/lows:

OldNew
localMaxlocalMax30w
localMinlocalMin30w
caprMaxcaprMax30w
caprMincaprMin30w

Trend regime / age / pending:

OldNew
confirmedRegimeCaprconfirmedRegimeCapr200w
pendingRegimeCaprpendingRegimeCapr200w
pendingRegimeCountpendingRegimeCount200w
trendAgetrendAge200w

Deviations (suffix the long MA they reference):

OldNew
devFromLocalMaLongdevFromLocalMaLong200w
devFromCaprMaLongdevFromCaprMaLong200w

Other:

OldNew
volumeConfirmationvolumeConfirmation30d
scoreVelocity5dscoreVelocity5d200w (now tracks byteTrendLocal200w)

Assets endpoint denormalised fields:

OldNew
byteTrendCaprbyteTrendCapr200w
trendRegimeCaprtrendRegimeCapr200w
changeCaprchangeCapr200w

GroupMetrics aggregates: legacy unsuffixed avgByteTrendFast/Local/Capr, medianByteTrendLocal, pctScore{5,0}{Local,Capr} removed; use the suffixed equivalents listed in Universe Groups.

Added

Removed (no replacement)

Docs corrections

Preserved under existing names

See the BYT-240 entry for the prior cutover.

2026-04-22 — BYT-240: ByteTrend score rename, VWAP removal

Four collision-free ByteTrend scores replace the previous six, naming window into the identifier. The legacy VWAP-weighted weekly infrastructure has been removed.

Rationale

Canonical scores

FieldUI LabelWindows
byteTrendLocal200wLocal (Weekly)200w / 30w / 30w on local close
byteTrendLocal30dLocal (Daily)200d / 30d / 20d on local close
byteTrendCapr200wCAPR (Weekly)200w / 30w / 30w on CAPR
byteTrendCapr30dCAPR (Daily)200d / 30d / 20d on CAPR

Each carries *Rules, change*, trendRegime*, and consec*5/consec*0 companions on the same suffix.

Added

Removed

Semantic shift (same keys)

Migration

The engine dual-wrote canonical and legacy names during the BYT-240 → BYT-241 transition window. Dual-write closed at BYT-241 (2026-04-28); only the canonical names are emitted now. See the BYT-241 entry for the full removal list.