CUCKOOTRADE

Quickstart

No key, no signup. This works right now, from anywhere:

curl 'https://cuckootrade.com/api/v1/alpaca/v2/stocks/bars?symbols=AAPL,CRASH&timeframe=1Day&start=2026-07-01'

Using alpaca-py? Pass url_override="https://cuckootrade.com/api/v1/alpaca" and any non-empty strings as API keys — they're never checked. The API is also self-describing: /api returns a machine-readable index, and /llms.txt summarizes everything for AI coding tools.

API structure & versioning

Every endpoint lives under /api/v1/, and provider-compatible surfaces add the provider's name to the path:

/api/v1/{provider}/<the provider's own path>   ← mimics that provider's wire format
/api/v1/<endpoint>                            ← CuckooTrade-native (e.g. /api/v1/stream)

Everything through the provider segment is CuckooTrade's namespace; everything after it replicates the provider exactly, which is why a client only needs its base URL changed. The v2 in /api/v1/alpaca/v2/stocks/bars is Alpaca's own version, not ours. Three providers are live:

providerbase URLstands in for
alpacahttps://cuckootrade.com/api/v1/alpacadata.alpaca.markets
alphavantagehttps://cuckootrade.com/api/v1/alphavantagewww.alphavantage.co
polygonhttps://cuckootrade.com/api/v1/polygonapi.polygon.io

Two things are versioned, on purpose: the path version (v1) covers the API surface — paths, parameters, error shapes — while the generation parameter covers the data itself. A surface change bumps the path; a data change becomes a new generation, and old generations stay queryable (see determinism).

Provider surface · Alpaca

GET /api/v1/alpaca/v2/stocks/bars

Alpaca-compatible historical OHLCV bars. Regular sessions only (09:30–16:00 ET, NYSE calendar — weekends and US market holidays have no bars; half-days trade as full sessions). Only completed bars are served, so any response you receive is permanently reproducible.

parammeaning
symbolsrequired; comma-separated, max 50. Any well-formed symbol works: curated tickers (AAPL, SPY, …) sit at plausible price levels, everything else gets a stable hash-derived personality.
timeframe[1-59]Min, [1-23]Hour, 1Day, 1Week, [1,2,3,4,6,12]Month. Default 1Day. Coarser bars aggregate exactly from finer ones.
start / endRFC-3339 or YYYY-MM-DD, inclusive. Defaults: last 30 days. Weeks/months clipped by the window are dropped, not served partial.
limittotal bars across all symbols, 1–10000 (default 1000). More data ⇒ next_page_token; pass it back as page_token.
sortasc (default) or desc.
seedcuckoo extension. Any string; returns a different but equally deterministic dataset with the same statistical character. Omit it for the shared default dataset.
generationcuckoo extension. Pins the generator version (currently 1). Responses carry X-Cuckoo-Generation.
adjustment, feed, asof, currencyaccepted and ignored, for Alpaca client compatibility. No corporate actions exist in generation 1.

Also available: /api/v1/alpaca/v2/stocks/{symbol}/bars (single symbol) and /api/v1/alpaca/v2/stocks/bars/latest?symbols=… (last completed bar). Errors are Alpaca-shaped {"code", "message"}, and every message states the valid grammar plus a working example.

Provider surface · Alpha Vantage

GET /api/v1/alphavantage/query

Alpha Vantage's single-endpoint format, faithfully — including its quirks: values are strings, series are keyed newest-first, and errors come back as HTTP 200 with an "Error Message" body, because that is how the real API reports them. apikey accepts anything, including nothing. Intraday is a premium endpoint on Alpha Vantage's free tier; here it's free like everything else.

curl 'https://cuckootrade.com/api/v1/alphavantage/query?function=TIME_SERIES_DAILY&symbol=IBM'
parammeaning
functionrequired: TIME_SERIES_INTRADAY, TIME_SERIES_DAILY, TIME_SERIES_WEEKLY, TIME_SERIES_MONTHLY, or GLOBAL_QUOTE.
symbolrequired; one symbol. Scenario tickers work: symbol=CRASH.
intervalintraday only, required there: 1min, 5min, 15min, 30min, 60min. Labels are interval-end times in US/Eastern.
outputsizecompact (default, last 100 points) or full (~20 years daily; trailing 30 days intraday).
monthintraday only: YYYY-MM serves that calendar month.
apikey, adjusted, extended_hoursaccepted and ignored.
seed / generationcuckoo extensions, same semantics as everywhere else.

Two deliberate deviations from the real thing: only completed bars are served (no partial current day/week/month row — determinism requires it), and sessions are regular-trading-hours only.

Provider surface · Polygon

GET /api/v1/polygon/v2/aggs/ticker/{ticker}/range/…

Polygon's aggregates format: the same envelope (ticker, queryCount, resultsCount, adjusted, results, status, request_id, count), bars as {v, vw, o, c, h, l, t, n} with t in Unix milliseconds, next_url cursor pagination, and {"status": "ERROR"} error bodies. apiKey is accepted and ignored, and status is always OK — synthetic data is never delayed.

curl 'https://cuckootrade.com/api/v1/polygon/v2/aggs/ticker/MSFT/range/1/day/2026-07-01/2026-08-01'
path / parammeaning
range/{multiplier}/{timespan}minute (1–59), hour (1–23), day, week, month (1, 2, 3, 4, 6, 12), quarter (1, 2, 4), year.
{from} / {to}YYYY-MM-DD (inclusive dates) or Unix millisecond timestamps.
sortasc (default) or desc.
limit1–50000 (default 5000); past it, follow next_url.
adjusted, apiKeyaccepted and ignored — no corporate actions exist, so adjusted and unadjusted are the same numbers.
seed / generationcuckoo extensions; carried through next_url automatically.

Also available: /api/v1/polygon/v2/aggs/ticker/{ticker}/prev — the previous session's daily bar, with Polygon's extra "T" field. request_id is a hash of the request rather than a random id, so identical requests stay byte-identical.

The determinism guarantee

Every bar is a pure function of (symbol, timestamp, generation, seed). Identical requests return identical bytes, forever, within a generation — there is no database and no randomness at request time, which is also why fully-specified historical responses ship Cache-Control: immutable. If the generator ever improves, that becomes generation 2; generation 1 stays queryable, so committed fixtures never break.

Scenario tickers

Reserved symbols with scripted, calendar-anchored behavior. Every pattern appears within any 30-day window, so a demo or test never catches a quiet stretch. Responses stay schema-valid — the stress is in the values, never in malformed fields.

tickerbehavior
CRASHsharp ~25% crash mid-month, slow grind recovery
MOONparabolic run-up peaking late in the month, hard correction
FLATzero-range bars pinned at $100.00 — breaks naive autoscaling
GAPPY±5–15% overnight gaps most days, quiet sessions
HALTSminute bars absent during intraday halt windows
SPIKEYsingle-minute wicks that spike and instantly revert
PENNY~$0.30 prices, four decimals, high volatility
CHOPPYhigh volatility, zero net drift
CuckooTrade native

GET /api/v1/stream (SSE)

Server-sent events — curl-able, no WebSocket library needed. It's what drives the live ticker at the top of every page here. Two clocks: clock=demo (default) is an always-open synthetic session whose price is a pure function of wall time, so every viewer sees the same tick at the same instant; clock=real follows the NYSE calendar and emits completed 1-minute bars, staying silent (heartbeats only) while the market is closed. Max 10 symbols and 5 concurrent streams per address; streams close after 15 minutes — reconnect freely.

curl -N 'https://cuckootrade.com/api/v1/stream?symbols=CUCKOO,CRASH'

Rate limits

60 requests per minute sustained per address, with burst headroom to 120 — no key required. Responses carry RateLimit-Limit / -Remaining / -Reset headers, and a 429 tells you exactly how long to back off. Limits are enforced per replica, so the effective ceiling may be somewhat higher than advertised.

Self-hosting

The API is stateless and MIT-licensed. If your CI pipeline shouldn't depend on an external service, run your own instance: clone the repo and start it with pip install -r api/requirements.txt && python api/api.py, or pull the prebuilt container image published alongside the repo. Determinism means a local instance serves byte-identical data to cuckootrade.com for the same generation.

All data is synthetic. Every response is generated and marked with X-Cuckoo-Synthetic: true. CuckooTrade exists to exercise code paths — development, CI, demos, teaching. It is not market data, must never inform a real trade, and is not a backtesting tool: a strategy that profits against synthetic data has learned the generator, not the market.