Coinbase Exchange candle-window mechanics.
Coinbase's Exchange API accepts granularities 60, 300, 900, 3600,
21600, and 86400 seconds. Its candle endpoint returns newest-first rows
and documents a 300-candle maximum. Because start and end are inclusive,
Bourse requests at most 299 intervals per page, then merges non-overlapping
pages back into Coinbase's newest-first wire order.
Unified callers use ETH/USD; the authored dash symbol pattern routes it to
Coinbase's ETH-USD product id. Native product ids remain available on the
generated raw endpoint functions.
Live observation on 2026-08-11 established that the current forming bucket appears once it contains a trade. Intervals without ticks are omitted, as the provider documentation states; callers must not assume a dense time series.
Summary
Functions
Merges paged raw responses, deduplicating and retaining the requested chronological range.
Builds inclusive, non-overlapping request pages when limit exceeds 300.
Types
@type metadata() :: %{ start_ms: non_neg_integer(), end_ms: non_neg_integer(), limit: pos_integer() }
@type page() :: %{ params: map(), start_ms: non_neg_integer(), end_ms: non_neg_integer() }
Functions
Merges paged raw responses, deduplicating and retaining the requested chronological range.
@spec pagination(map(), map(), non_neg_integer()) :: {:single, map()} | {:paginate, [page()], metadata()}
Builds inclusive, non-overlapping request pages when limit exceeds 300.
Single-page requests come back as {:single, params} with the window pair
completed: Coinbase ignores BOTH start and end whenever either one is
missing and silently answers with the most recent page, so a half-open
window must never reach the wire.