Skip to main content
Every dataset in the Blockworks API is one of two model kinds. The kind determines the URL shape, the query parameters, and the response structure, but within a kind, every model behaves identically. Learn one tabular endpoint and you have learned them all.

URL shapes

Concretely:

How they relate

Tabular models

A tabular model is a result set with a primary key: one row per entity, holding its current state. Asset identity and metadata, exchange directories, current market metrics, ETF holdings. List endpoint. GET /query/tabular/{model} returns an array of rows. Narrow it with filter operators, order it with sortBy/sortDirection, and walk it with page/pageSize. See Filtering & pagination.
Single-row endpoint. GET /query/tabular/{model}/{id} returns exactly one row. Many models accept alternative identifiers as well as the primary key (for assets, a slug or a symbol also resolves), and metadata.matchedField reports which field the value matched on.

Timeseries models

A timeseries model has a time column, a series key, and one or more metric columns. Every request picks a granularity in the path and a time window in the query string. See Granularity & time ranges.

Series keys

The series key is the value that names one series: the {seriesKey} path segment, or one entry of ?series=. For entity-keyed models (assets, blockchains, protocols, ETFs) it is the primary key of a row in the matching tabular model, usually a UUID such as 1e31218a-e44e-4285-820c-8282ee222035 for Bitcoin. The tabular row endpoint accepts a slug or a symbol and tells you the primary key; the timeseries path does not resolve them.
GET /query/timeseries/asset-price/1d/bitcoin returns 200 with "points": [] and no entity, not 404. An empty series almost always means a slug or symbol was used where the assetID or networkID belongs. Resolve the identifier first with /query/tabular/assets/bitcoin or /query/tabular/blockchains/solana.
Aggregate models (sectors, sub-sectors, exchange regions) key their series by a plain name such as AI or Asia instead. Finding an id lists the lookup table and accepted identifiers for every timeseries model. Single-series endpoint. GET /query/timeseries/{model}/{granularity}/{seriesKey} returns one series. This is the common case: one asset’s price history, one protocol’s revenue.
Multi-series endpoint. GET /query/timeseries/{model}/{granularity} returns several series in one response. Name them with ?series=, a comma-separated list of up to 20 series keys.
For models with a small number of series (sector aggregates, ETF providers, lending protocols), omitting ?series= returns every series at once. Models with high series cardinality (most asset-keyed models) do not support that: omitting ?series= returns 404 with a message telling you to name the series. The catalog’s allowAllSeries flag tells you which is which.

Choosing between them

Reach for tabular

You want a screener, a leaderboard, a directory, or the current value of a metric across many entities. You want to filter, sort, and paginate.

Reach for timeseries

You want a chart, a trend, a return calculation, or a backtest. You know which entities you care about and you need history for them.
The two kinds compose. A common pattern is to use a tabular model to find the entities you care about, then feed their identifiers into a timeseries model as series keys:
1

Find the entities

GET /query/tabular/assets?circulatingMarketcapGte=1000000000&selections=assetID,symbol
2

Pull their history

GET /query/timeseries/asset-price/1d?series=<up to 20 assetIDs>&timeframe=ytd

Shared conventions

Both kinds share the same envelope, the same selections parameter, the same acceptFormat options (json, csv, jsonl), and the same error semantics. See Responses and Errors.