Market Data
Exchange market data for crypto: historical OHLC bars, latest prices, and a live tick stream.
API key requiredStarter and aboveMarket data is not included on the free plan. Calls count against your plan's monthly request allowance like any other endpoint.
Restricted use
This data is licensed for your own internal use. You may not redistribute, republish, resell, or expose it on a public surface. Every response carries the terms in a redistribution object — they apply to cached copies too.
Coverage
Read the catalog rather than assuming: coverage is a pinned archive window, not listing-to-present history, and only intervals we actually hold are advertised.
| Market | Crypto spot |
| Symbols | 36 USDT pairs — BTCUSDT, ETHUSDT, SOLUSDT, … |
| Intervals | 1m; 5m on selected symbols |
| Equities | Not available |
GET /v1/market/instruments
The catalog. Each instrument reports its available intervals and its archive_window_start / archive_window_end.
curl -H "Authorization: Bearer $TNL_API_KEY" \
https://theneuralledger.com/v1/market/instrumentsGET /v1/market/bars
Historical OHLC. Windows are half-open [from,to) and aligned to the interval.
| Name | Required | Description |
|---|---|---|
symbol | yes | One or more symbols, repeated or comma-separated. Max 20. |
interval | yes | 1m or 5m. Must be one the instrument advertises. |
from / to | yes | UTC ISO-8601. Maximum window 32 days. |
venueId | no | Optional. Defaults to the supported spot venue; read it from /instruments. |
limit | no | Rows per upstream page. Max 5000. |
curl -H "Authorization: Bearer $TNL_API_KEY" \
"https://theneuralledger.com/v1/market/bars?symbol=BTCUSDT&interval=1m\
&from=2026-08-01T00:00:00Z&to=2026-08-01T06:00:00Z"Pagination is handled for you — the response contains the whole window, with pages reporting how many upstream pages were walked. If a window is too large to complete, truncated is true; narrow the range rather than assuming the data ends there.
Gaps are explicit. There is no forward-fill, no synthetic rows, no zero-price padding. coverage[] reports expected_bars, present_bars, complete, and any gaps — a missing minute is reported as missing, not invented.
GET /v1/market/coverage
The same query as /bars but returns coverage only, without rows. Use it to check what exists before pulling a large window.
GET /v1/market/latest
Latest observed price per symbol.
curl -H "Authorization: Bearer $TNL_API_KEY" \
"https://theneuralledger.com/v1/market/latest?symbol=BTCUSDT,ETHUSDT"Each record carries source_age_ms and a stale boolean, computed from the source timestamp, not our receipt time. Check stale before using a price. A quote that stopped updating starts reporting stale: true on its own; we will never present a stale quote as live.
GET /v1/market/stream
Server-sent events: tick, bar_close, heartbeat, plus gap and status.
curl -N -H "Authorization: Bearer $TNL_API_KEY" \
"https://theneuralledger.com/v1/market/stream?symbol=BTCUSDT"event: tick
data: {"symbol":"BTCUSDT","price":76385.11,"tick_type":"quote",
"occurred_at":"2026-09-17T06:04:40.781Z","bid":76385.11,"ask":76385.12}bar_close is provisional, not history. It is derived from observed ticks and is labelled canonical_status: "provisional", complete: false. Its volume covers observed trades only. Do not store it as settled history — refetch the interval from /bars once the archive catches up.
Handle gap events. Replay is bounded, not durable. If we lose our upstream position beyond the replay window we emit a gap event rather than silently continuing, and resynchronise. Treat a gap as "refetch this range", not as a quiet period.
Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
403 | Your plan does not include market data, or the record is restricted |
404 | Unknown instrument, or an interval that symbol does not have |
400 | Bad window — to before from, over 32 days, or malformed timestamps |
503 | Upstream backpressure. Honour Retry-After. |
Practical notes
Symbols, intervals and archive bounds come from /instruments — hard-coding them will break when coverage changes. For backfills, pull in windows and check coverage per window rather than assuming a continuous range. And keep the stale and canonical_status checks in your integration: they are the difference between a price you can act on and one you cannot.