Endpoints
Every endpoint lives under /v1 on https://api.tillacrypto.com. Data calls need a key; service calls do not. <tier> is free, builder, pro, max or enterprise.
Data — your key, your tier
GET /v1/<tier>/raw/<lane> — what the venues published
Lanes: 1min 5min 10min 30min hour daily weekly monthly quarterly — your tier holds a subset; GET /v1/inventory lists it.
| Param | Meaning |
|---|---|
series | Comma-separated names, at most 200 (GET /v1/inventory?layer=raw&lane=1min lists yours). A pattern works too: btc_ (everything of BTC), _close (every market's close), eth_rsi_. |
markets + fields | Instead of series: markets=btc,eth,sol&fields=close,volume asks for exactly that grid (btc_close, btc_volume, eth_close ...). markets alone = everything of those markets. A whole category is one word: markets=crypto&fields=close is every coin's close, markets=stocks&fields=close,volume every US stock and ETF — also fx and macro. |
start, end | YYYY-MM-DD or YYYY-MM-DD HH:MM[:SS], both inclusive. No start = the newest rows up to end. |
period | Instead of start: 1d 7d 30d 2m 3m 6m 1y 2y 3y or all, counted back from today. Your tier's history still applies. |
limit | Rows per answer, at most 50,000 (the default). |
format | json (default), csv, ndjson or parquet. |
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/free/raw/hour?series=btc_close,eth_close&start=2026-10-01&limit=3"
Exactly what you want, nothing more — the same call with the grid, or a pattern:
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/pro/raw/hour?markets=btc,eth,sol&fields=close,volume&period=6m"
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/max/raw/hour?series=*_close&period=30d"
{ "tier": "free", "layer": "raw", "lane": "hour", "series": ["btc_close","eth_close"],
"rows": 3, "more": true, "next_start": "2026-10-01 03:00:00",
"floor": "...", "clipped": "", "delivery": "...",
"data": [["2026-10-01 00:00:00", 63920.5, 2611.2], ...] }
Paging: when more is true, call again with start=next_start — the next page starts exactly after the last row you got, never repeating one. The same facts ride in the headers on every format: X-More, X-Next-Start, X-Tier, X-Tilla-Floor, X-Tilla-Clipped.
GET /v1/<tier>/market/<market> — one market, and everything connected to it
Every series of one market your tier holds, on one clock, in one call — no series list to write. Switch markets by changing the name: /market/btc, /market/nvda, /market/eurusd, /market/gold. GET /v1/markets lists all of them, with what each tier holds of it.
| Param | Meaning |
|---|---|
lane | 1min (default), hour, daily ... - any lane your tier holds |
layer | raw (default), derived, node, deep, or all (raw and derived side by side) |
related | 1 adds the connected markets: Bitcoin brings its ETFs (IBIT, FBTC, GBTC, BITO), the miners and treasury stocks; a stock brings its index and sector ETFs; an FX pair brings every pair sharing a currency |
fields | only these fields of each market: fields=close with related=1 = the close of BTC and of everything connected to it |
period or start / end | the window, as on every data call |
offset | a market can hold more than 200 series: the answer's series_next_offset is the next page of columns |
limit, format | as on every data call |
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/pro/market/btc?lane=hour&related=1&period=6m"
One stock, all stocks, one coin, all crypto — the same call, one word:
/v1/pro/market/aapl?lane=1min&period=30d one stock, every series of it
/v1/pro/raw/1min?markets=stocks&fields=close every US stock and ETF's close
/v1/pro/market/btc?lane=1min&period=30d one coin, every series of it
/v1/pro/raw/1min?markets=crypto&fields=close every coin's close
/v1/pro/market/crypto?lane=1min&period=1d every series of every coin (columns page with offset=)
GET /v1/markets — every market, no key
Every market we carry — crypto, US stocks and ETFs, FX, macro — with its category, its related markets, how many series each tier holds of it, and the lanes it lives on.
GET /v1/<tier>/derived/<lane> — indicators computed from the raw
Lanes: 1min 5min 10min 15min 30min 1hour 4hour 8hour daily 30day weekly monthly quarterly. Same parameters and answer as raw. Every derived answer also carries three columns, tilla_canary_1 to _3, for our own bookkeeping. They are not market data — drop them.
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/free/derived/daily?series=btc_ema_20&limit=5"
GET /v1/<tier>/node/<lane> — our own Bitcoin node (Max and above)
Raw node lanes 10min 30min hour daily weekly monthly quarterly, and derived node lanes 1hour 4hour 8hour daily 30day weekly monthly quarterly. Same parameters and answer.
GET /v1/<tier>/deep/hour — the deep history, before the aligned set
Hourly raw prices from each market's own first bar up to 2023-08-10, where the aligned set begins: FX from 2002, crypto from each coin's listing (BTC and ETH 2017), US stocks, ETFs and the macro ETF proxies from 2020. The same series names as raw/hour, and your tier reads every deep series it holds at raw/hour with no history floor. Same parameters and answer. GET /v1/inventory?layer=deep&lane=hour lists yours.
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/free/deep/hour?series=btc_close&start=2018-01-01&end=2018-01-02"
GET /v1/<tier>/export/<layer>/<lane> — a whole window in one file (Pro and above)
layer is raw, derived, node or deep. Streams every row of the window in one answer, no page cap. Params: series (or markets + fields), start, end, period, format = csv (default), ndjson or parquet. The rows count against your rows per day.
GET /v1/<tier>/tick — your whole tier, live, one request a minute
Every series your key holds, on every lane that closed at a boundary, in one answer: per lane its bar, due, complete, sold, series and values. Ask once a minute, a few seconds after the minute. ?at=YYYY-MM-DD HH:MM asks a given boundary (ask the minute before once more and you also catch the cells that publish a minute late); ?lanes=raw/1min,derived/5min asks again only for lanes still being written.
GET /v1/<tier>/resume/<layer>/<lane>?since=… — fill the gap since you stopped
Every series your key holds on one lane, every bar from since to now, streamed in one request (ndjson default, csv, parquet).
How long it takes (measured 2026-10-28 through the public URL with the official client): a week of every raw series takes about 35 seconds on Max (9.6 million values), 27 seconds on Builder and 3 seconds on Free. Derived is far bigger: a week of every derived series on Builder is 225 million values and takes about 6 minutes, and longer on Pro and Max, so months of derived history take hours. For a long history, ask for the derived lanes or markets you need (markets=btc,eth), or start the client from a recent date and let it tick forward.
GET /v1/<tier>/changes?since=… — our heal, applied to your copy
Every cell our own checks repaired, filled or re-walked since since (the hourly audit, the two-hourly sweep, the day close) that your key holds, with its value now. Apply them and your copy is corrected when ours is. Pass the answer's until back as the next since.
The official client does all three into a database of its own, resuming from where it stopped:
python tilla_dashboard.py --keep tilla.db # resume, tick every minute, heal every 10 minutes (starter package)
Bulk — your whole window, straight from our database (Pro and above)
There are no copies to go stale: a bulk pull is the export and resume calls above, read straight from the same database the live tick writes, and only what your tier holds over your tier's whole window. It streams from the first byte (measured: first byte 0.04 s, ~10 MB/s through the public address), in csv, ndjson or parquet. Take a whole lane, or one slice with ?markets=crypto (or stocks, fx, macro, or ids like btc,aapl):
/v1/pro/export/raw/1min?markets=crypto&period=1y&format=parquet
/v1/pro/resume/derived/1hour?since=2025-10-15&format=parquet
Or let the official client walk every lane your key holds into one local database, and keep it current afterwards:
curl -H "X-API-Key: <key>" "https://api.tillacrypto.com/v1/<tier>/resume/raw/1min?since=2025-10-15&format=csv" > raw_1min.csv
python tilla_dashboard.py --keep tilla.db # picks up where it stopped, ticks and heals forever
GET /v1/<tier>/stream — live, as each bar lands
Server-Sent Events. Params: layer (default raw), lanes (comma-separated, default 1min), series, since. Every event's id is layer/lane/label; reconnect with Last-Event-ID (or since) and missed bars are replayed. A keepalive comes every 15 seconds.
curl -N -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/max/stream?lanes=1min&series=btc_close"
GET /v1/inventory — exactly what your key holds
No params: your lanes per layer, with how many series each. ?layer=raw&lane=1min: every series there, grouped by the table it lives in. ?tier=free previews a lower tier.
GET /v1/usage — your budget right now
Your tier, history days, per-minute and per-day limits, rows and tables used today.
Service — no key
| Call | Answers |
|---|---|
GET /v1/ping | liveness |
GET /v1/status | the newest 1min bar and the tiers served |
GET /v1/health | the newest bar of every lane, every layer |
GET /v1/tiers | the public tiers: price, history, limits, size |
GET /v1/calls?tier=pro&format=csv | every call with its ready URL for your tier, and every error - a sheet (or json), no key |
GET /v1/samples | the free samples of every tier (one tick, and one whole day), no key |
GET /v1/sample/<tier>.csv · .db · GET /v1/sample/<tier> | one tick of everything that tier holds - the newest value of every series on every lane - as a sheet, as SQLite, or the tier at a glance (JSON). Tiers: free, builder, pro, max |
GET / · GET /v1 | this whole API as one JSON index |
GET /openapi.json · GET /llms.txt | machine-readable, generated from the API itself |
Account — called by this website with your signed-in session
| Call | Does |
|---|---|
POST /v1/demo_key | a free key with no account, one per address per day |
POST /v1/free_key | your account's free key |
POST /v1/my_key | your key; ?peek=1 checks without minting, ?rotate=1 replaces it, ?claim=1 shows a just-bought key once |
POST /v1/checkout · POST /v1/portal | subscribe, or manage and cancel |
POST /v1/enterprise_inquiry | talk to us about Enterprise |
The July shape — still served
GET /v1/latest, GET /v1/data and GET /v1/sync?since= read one raw table by name: series= (or cols=) and table= such as crypto_1min, forex_1h or macro_1d (suffix 1min 5min 10min 30min 1h 1d 1w 1m 1q).
curl -H "X-API-Key: tk_live_xxx" \
"https://api.tillacrypto.com/v1/latest?series=btc_close,eth_close"
For AI agents — the MCP server
TILLA ships an MCP server, so Claude, Cursor or any MCP client can query the API directly with your key: it can read what your key holds, the newest values, any window, your usage and the tiers. Set TILLA_API_KEY and add python tilla_mcp.py as a server; the full setup is at tillacrypto.com/mcp.
Three ways to use it
- Follow live —
GET /v1/<tier>/stream, or poll the window call with nostartonce a bar. - Pull history — the window call with a
start, paging withnext_startuntilmoreisfalse. - Seed, then stay current — export or resume the window once (Pro and above), then call the window from your newest bar on a timer.