Tables API
The Table API supports fetching large quantities of data. Tables can flexibly filter data of interest and let you pick the exact list of columns for a result. Tables have a much higher limit of 50,000 entries. However, binary data is not unpacked so we recommend you use our SDKs.
Generic Table Query​
GET /tables/{table_code}.{format}?{args}
Tables store data in tabular form as a set of columns. Each column has a specified type and each row has a unique uint64 row_id
. Empty values are represented as JSON null
or empty strings. Tables can grow extremely large, so it's good practice to use filters and the columns
query argument to limit the result size. Table responses are automatically sorted by row_id
. Use client-side sorting if a different sorting order is required.
Row Ids, uniqueness and comparisons​
Please don't treat row ids as globally unique, stable or comparable. Row ids are essentially table sequence numbers that are only unique within a particular version of a table. Lets use two scenarios to explain why that matters:
We use multiple independent indexer instances for scaling the TzPro API to support many concurrent users. Each indexer locally stores its own private database tables. On chain reorgs our indexers roll back history by removing side-chain operations and reverse-updating account balances. That means two different indexers instances may end up seeing two different chain reorg histories. When that happens, these instances will have different row ids for operations and likely also accounts in their individual databases.
The same can happen when we from time to time update the indexer and rebuild databases as result. In this case a previously observed chain reorg will be lost and the database will only contain data about the canonical chain. This means that even the same API instance can return different row ids for the same historic operations when on-chain history was built without knowledge of a reorgs.
As work-around you can use the combination of block height
and operation positions op_l
, op_n
if your application requires a unique id other than a hash.
List of Tables​
Endpoint | Table Content |
---|---|
GET /tables/balance | historic end-of-block balances for all accounts |
GET /tables/chain | running blockchain totals |
GET /tables/supply | running supply totals |
GET /tables/block | blocks (including orphans) |
GET /tables/op | operations (only final) |
GET /tables/account | most recent account balances and state |
GET /tables/contract | smart contracts state at creation |
GET /tables/constant | smart contract global constants |
GET /tables/flow | balance, freezer and delegation flows |
GET /tables/rights | baking and endorsing rights |
GET /tables/snapshot | balances of active delegates & delegators at all snapshot blocks |
GET /tables/income | per-cycle statistics on baker income, efficiency, etc |
GET /tables/gov_election | election metadata (i.e. entire governance cycles) |
GET /tables/gov_proposal | individual proposals |
GET /tables/gov_vote | voting period metadata |
GET /tables/gov_ballot | ballots and proposal operations |
GET /tables/bigmap_types | bigmap identity |
GET /tables/bigmap_values | currently live bigmap values |
GET /tables/bigmap_updates | historic bigmap updates (including copy/alloc) |
Query Arguments​
Tables support the following general query parameters.
Argument | Description |
---|---|
columns optional | Comma separated list of column names to return. Bulk array results will be ordered accordingly. Default is all defined columns for a table. |
limit optional | Maximum number of rows to return. Limited to 50,000, default 500. |
cursor optional | Id (row_id ) of the latest result row returned by a previous call. |
order optional | Result order either asc (default) or desc , sorted by row_id . |
To paginate result sets larger than the maximum limit, include row_id
into the list of columns and use the last value of row_id as cursor in your next call. This will automatically apply an extra filter row_id.gt=cursor
for ascending and row_id.lt=cursor
for descending order. You can of course also apply the relevant row_id filter directly, without using cursor.
Query Filters​
Filter Example
The example below filters blocks by time range from
time.gte=2019-08-01
(inclusive) totime.lte=2019-08-31
(inclusive) and returns columnstime
andheight
. The same effect can be achieved with the range operatortime.rg=2019-08-01,2019-08-31
.
GET /tables/block.json?
columns=time,height&
time.gte=2018-08-01&
time.lte=2018-08-31&
limit=50000
JSON Result​
[
[1533081657000,42672],
[1533081717000,42673],
[1533081777000,42674],
[1533081837000,42675],
[1533081897000,42676],
[1533081957000,42677],
[1533082017000,42678],
[1533082152000,42679],
[1533082287000,42680],
[1533082347000,42681],
[1533082407000,42682],
// ...
]
To filter tables use filter expressions of the form <column>.<operator>=<arg>
. Filters work on any combination of columns regardless of type. For arguments, type encoding rules of the column type apply. Filtering by multiple columns is similar to a logical AND between expressions. For simplicity and performance there are currently no OR expressions or more complex operators available. Comparison order for strings and binary is the lexicographical order over UTF8 (string) or ASCII (binary) alphabets.
Operator | Semantics |
---|---|
= , .eq= | Equal. Matches rows where column values match exactly the filter value. |
.ne= | Not equal. Matches rows where column values do not match the filter value. |
.gt= | Greater than. matches columns whose value is strictly greater than the filter value. |
.gte= | Greater than or equal. matches columns whose value is greater than or equal to the filter value. |
.lt= | Less than. matches columns whose value is strictly smaller than the filter value. |
.lte= | Less than or equal. matches columns whose value is strictly smaller than or equal to the filter value. |
.in= | Inclusion in list. matches columns whose value is equal to one of the filter values. Multiple values must be separated by comma. |
.nin= | Not included in list. matches columns whose value is not equal to one of the filter values. Multiple values may be separated by comma. |
.rg= | Range. matches columns whose value is between the provided filter values, boundary inclusive. Requires exactly two values separated by comma. (This is similar to, but faster than using .gte= and .lte= in combination.) |
.re= | Regexp. matches columns whose value matches the regular expression. Can only be used on string-type columns (not enum or hash). Non-URL-safe characters must be properly escaped. |