TILLA
TILLA DOCS · ENDPOINTS

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.

ParamMeaning
seriesComma-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 + fieldsInstead 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, endYYYY-MM-DD or YYYY-MM-DD HH:MM[:SS], both inclusive. No start = the newest rows up to end.
periodInstead of start: 1d 7d 30d 2m 3m 6m 1y 2y 3y or all, counted back from today. Your tier's history still applies.
limitRows per answer, at most 50,000 (the default).
formatjson (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.

ParamMeaning
lane1min (default), hour, daily ... - any lane your tier holds
layerraw (default), derived, node, deep, or all (raw and derived side by side)
related1 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
fieldsonly these fields of each market: fields=close with related=1 = the close of BTC and of everything connected to it
period or start / endthe window, as on every data call
offseta market can hold more than 200 series: the answer's series_next_offset is the next page of columns
limit, formatas 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

CallAnswers
GET /v1/pingliveness
GET /v1/statusthe newest 1min bar and the tiers served
GET /v1/healththe newest bar of every lane, every layer
GET /v1/tiersthe public tiers: price, history, limits, size
GET /v1/calls?tier=pro&format=csvevery call with its ready URL for your tier, and every error - a sheet (or json), no key
GET /v1/samplesthe 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 /v1this whole API as one JSON index
GET /openapi.json · GET /llms.txtmachine-readable, generated from the API itself

Account — called by this website with your signed-in session

CallDoes
POST /v1/demo_keya free key with no account, one per address per day
POST /v1/free_keyyour account's free key
POST /v1/my_keyyour key; ?peek=1 checks without minting, ?rotate=1 replaces it, ?claim=1 shows a just-bought key once
POST /v1/checkout · POST /v1/portalsubscribe, or manage and cancel
POST /v1/enterprise_inquirytalk 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