The dataset catalog: programmatic discovery
The catalog API is your discovery surface. Five endpoints under
GET /api/v1/meta/datasets let you ask, programmatically: what
datasets exist, what columns each one has, what time range each one
covers, and which ones you are entitled to.
GET /api/v1/meta/datasets— List every dataset known to the server.GET /api/v1/meta/datasets/my— List only the datasets your account is entitled to.GET /api/v1/meta/datasets/{dataset_id}/info— One dataset's descriptor (date range, granularity, doc link, vendor).GET /api/v1/meta/datasets/{dataset_id}/columns— One dataset's column schema (name, data type, description per column).GET /api/v1/meta/datasets/{dataset_id}/status— One dataset's publication status.
:::caution Gotcha
The path placeholder {dataset_id} is the
opaque catalog id — a string of the form US####
(e.g. US6014). Parse it as a string. It is not the
human-readable dataset_text_id (e.g. fut_trades_1min).
Substituting the text id returns 404 on the dev API at the
time of writing. The catalog list endpoints
(/meta/datasets and /meta/datasets/my) return
both fields per row; clients must remember the opaque
dataset_id for any follow-up /info,
/columns, or /status call.
:::
The catalog endpoints are the only path-stable surface in the API.
URL-stylized dataset paths under GET /api/v1/data/... can change
when datasets are renamed or split; dataset_text_id values
are the stable identifier. Build your client around the catalog (look
up the text-id for the human name you care about) rather than around
hard-coded URL paths.
Listing every dataset
curl -s -H "X-API-KEY: $ALGOSEEK_API_KEY" \
"https://dev-datasets-api.algoseek.com/api/v1/meta/datasets"
[
{
"dataset_id": "US1033",
"dataset_name": "US Equities Trade and Quote Minute Bar",
"data_group": "Equity",
"vendor": "algoseek"
},
{
"dataset_id": "US1034",
"dataset_name": "US Equities Trade and Quote Extended Minute Bar",
"data_group": "Equity",
"vendor": "algoseek"
},
{
"dataset_id": "US1035",
"dataset_name": "US Equities Trade and Quote Minute Bar Excluding FINRA/TRF Trades",
"data_group": "Equity",
"vendor": "algoseek"
}
]
Each entry has:
dataset_text_id— The URL-friendly stable identifier (e.g.eq_taq_1min).dataset_id— The opaque catalog identifier, a short string of the formUS####(e.g.US1033). Despite the all-digit suffix it is a string, not an integer.dataset_name— Human-readable name.data_group— Coarse category: Equity, Equity Options, Equity Reference, Futures.vendor— Source organisation.
Listing the datasets you can actually use
curl -s -H "X-API-KEY: $ALGOSEEK_API_KEY" \
"https://dev-datasets-api.algoseek.com/api/v1/meta/datasets/my"
[
{
"dataset_id": "US1033",
"dataset_name": "US Equities Trade and Quote Minute Bar",
"data_group": "Equity",
"vendor": "algoseek"
},
{
"dataset_id": "US1035",
"dataset_name": "US Equities Trade and Quote Minute Bar Excluding FINRA/TRF Trades",
"data_group": "Equity",
"vendor": "algoseek"
},
{
"dataset_id": "US1032",
"dataset_name": "US Equities Trade and Quote",
"data_group": "Equity",
"vendor": "algoseek"
}
]
... (response truncated for the guide; full file under responses/cat_meta_datasets_my/body.json)
GET /api/v1/meta/datasets/my returns the same shape as
GET /api/v1/meta/datasets but pre-filtered to the entitled subset. It
is not the same as GET /api/v1/account/my/data-access-rules —
the latter additionally returns start_date, end_date,
and universe_identifiers per entitlement, which the catalog
endpoint does not. For a full picture, call both and join on
dataset_text_id.
Inspecting one dataset
curl -s -H "X-API-KEY: $ALGOSEEK_API_KEY" \
"https://dev-datasets-api.algoseek.com/api/v1/meta/datasets/US6014/info"
{
"dataset_id": "US6014",
"dataset_name": "US Futures Trade Only Minute Bar",
"data_group": "Futures",
"vendor": "algoseek",
"description": "The US Futures Trade 1-Minute Bar is a data feed that provides aggregated trade event-based bars. It includes OHLC (Open, High, Low, Close) information based on trade events. As additional features, the dataset provides total dollar volume and total trades and statistical fields such as count of buy/sell aggressor trades which is useful for analysis of market behavior.",
"dataset_class": "Futures",
"dataset_format": "Market Data",
"time_granularity": "Intraday Bar",
"documentation_link": "https://us-futures-market-data-docs.s3.us-east-1.amazonaws.com/algoseek.US.Futures.Trades.Only.Minute.Bars.pdf",
"start_date": "2010-01-01",
"end_date": null,
"is_time_series": true,
"universe_identifier": "symbol",
"creation_date": "2018-12-11"
}
The info payload adds metadata you cannot get from the list
endpoint:
description— a paragraph describing the dataset.dataset_class,dataset_format,time_granularity— categorisation flags useful for clients that want to display datasets in a faceted UI.documentation_link— a URL to the canonical PDF spec for the dataset.start_date/end_date— the dataset's publication range. Note:end_datecomes back asnullfor ongoing datasets.is_time_series— whether the dataset is time-series-shaped or reference-shaped.universe_identifier— what identifier scheme the dataset uses (symbol,cusip, etc.).
Discovering columns
This is the endpoint that makes column-name filtering tractable.
curl -s -H "X-API-KEY: $ALGOSEEK_API_KEY" \
"https://dev-datasets-api.algoseek.com/api/v1/meta/datasets/US6014/columns"
[
{ "name": "TradeDate", "data_type": "date", "description": "The trading day" },
{ "name": "BarDateTime", "data_type": "date-time", "description": "The timestamp of the bar start (CST)" },
{ "name": "Ticker", "data_type": "string", "description": "Contract name" },
{ "name": "BaseSymbol", "data_type": "string", "description": "Base product name" },
{ "name": "OpenPrice", "data_type": "number", "description": "Price of the first trade" },
{ "name": "HighPrice", "data_type": "number", "description": "Trade with the highest price" },
{ "name": "LowPrice", "data_type": "number", "description": "Trade with the lowest price" },
{ "name": "ClosePrice", "data_type": "number", "description": "Price of the last trade" },
{ "name": "VolumeWeightPrice", "data_type": "number", "description": "Volume-weighted average price" },
{ "name": "TotalQuantity", "data_type": "integer", "description": "Total number of shares traded" },
{ "name": "BuyAggressorQuantity", "data_type": "integer", "description": "The number of shares traded with \"Aggressor on Buy\"" },
{ "name": "SellAggressorQuantity", "data_type": "integer", "description": "The number of shares traded with \"Aggressor on Buy\"" },
{ "name": "TotalTrades", "data_type": "integer", "description": "Total number of trades" },
{ "name": "BuyAggressorTrades", "data_type": "integer", "description": "The number of \"Aggressor on Buy\" trades" },
{ "name": "SellAggressorTrades", "data_type": "integer", "description": "The number of \"Aggressor on Sell\" trades" }
]
Bootstrap-time discovery.
A robust client fetches columns
once at startup for each dataset it intends to use, caches them, and
validates user-provided filter and projection names against the
cached set before issuing the API call. This catches typos and
schema-drift errors locally, with a clear message, instead of
producing a remote 422.
Putting the catalog to work
A common discovery pattern: at startup, learn what the user can actually use. Below is a minimal version.
import os, requests
API_KEY = os.environ["ALGOSEEK_API_KEY"]
BASE = "https://dev-datasets-api.algoseek.com"
session = requests.Session()
session.headers["X-API-KEY"] = API_KEY
# 1. Entitled datasets
r = session.get(f"{BASE}/api/v1/meta/datasets/my", timeout=30)
r.raise_for_status()
my = r.json()
assert isinstance(my, list), my
print(f"Entitled to {len(my)} datasets:")
for d in my:
print(f" {d['dataset_text_id']:36s} {d['dataset_name']}")
# 2. Column schema for each dataset of interest.
# The /columns endpoint takes the opaque catalog dataset_id (a
# string like "US6014"), NOT the human-readable dataset_text_id
# (which would 404 on the dev API).
SCHEMAS = {}
for d in my:
r = session.get(
f"{BASE}/api/v1/meta/datasets/{d['dataset_id']}/columns",
timeout=30,
)
r.raise_for_status()
SCHEMAS[d["dataset_text_id"]] = {c["name"]: c["data_type"] for c in r.json()}
print(f"\nLoaded schemas for {len(SCHEMAS)} datasets.")
For long-running services, refresh the catalog periodically (every 24h is sufficient; schema changes have been observed at sub-annual cadence) and re-validate against entitlements at each refresh. Detect schema changes at refresh time, not at request time during a backfill.