# Market Data API - Historical Tick, OHLCV, Futures, Databento (`nabeelbaghoor/historical-market-data-api`) Actor

Historical market data from your own Databento account: tick trades, order book (MBO, MBP-10), top of book, OHLCV bars, instrument definitions and statistics for CME futures, US equities and OPRA options, plus datasets, symbology, a free cost preview and exact 1e-9 prices. Bring your own key.

- **URL**: https://apify.com/nabeelbaghoor/historical-market-data-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Developer tools, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 market data record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Market Data API - Historical Tick, OHLCV, Futures, Databento

Pull historical market data from your own Databento account into a dataset, a spreadsheet or a warehouse: tick by tick trades, full order book, top of book, OHLCV bars, instrument definitions and statistics for CME futures and options, US equities, OPRA options, ICE and Eurex, with exact prices and nanosecond timestamps on every row. Uses your own Databento API key, previews the cost before it streams anything, and charges only for rows that carry data.

### What it collects

- **Market data records** from the Databento Historical API in any documented schema: trades, MBO (market by order, L3), MBP-1 and MBP-10 (top of book and 10 levels of depth), TBBO, BBO 1s and 1m, OHLCV bars at 1 second, 1 minute, 1 hour and 1 day, instrument definitions, statistics (settlement, open interest, cleared volume), trading status and auction imbalance.
- **Exact prices and timestamps**: Databento stores prices as integers in units of 1e-9 and timestamps as UNIX nanoseconds. Each row has the price as a number, the exact nine-place decimal in `pricesExact`, every timestamp in ISO 8601 with nanoseconds plus a `<field>_ns` column with the integer, and the documented null sentinels turned into null.
- **Cost preview**: the cost in US dollars, record count and billable size Databento reports for a request, before anything is streamed. The records mode runs the same check against a ceiling you set and stops if the request would cost more.
- **Symbology resolution**: raw symbols such as ESM2 or AAPL to instrument IDs and back, parent symbols (ES.FUT) and continuous contracts (ES.c.0), with the date range each mapping holds and the symbols that were not found.
- **Dataset metadata**: dataset codes with their venues, publishers, the schemas of a dataset, the fields of a schema, the available start and end per schema, the data condition per day (available, degraded, pending, missing) and unit prices in US dollars per GB.
- Read only, pay per result, bring your own key.

### How to use it

1. Copy an API key from the API keys page of the Databento portal (32 characters, starting with `db-`). Paste it into the **API key** field, which is stored as a secret, or set the `DATA_API_KEY` environment secret.
2. Run the default **Datasets** mode to see the dataset codes your key reaches.
3. Run **Cost preview** with a dataset, symbols, schema and time range. It costs nothing on the Databento side.
4. Run **Market data records** with the same input. The actor checks the cost against your maximum, then streams up to your maximum results.

### Input

| Field | What it does |
| --- | --- |
| What to read | Datasets (default), publishers, schemas, fields, dataset date range, dataset condition, unit prices, cost preview, market data records or symbology resolution. |
| Dataset | A dataset code such as `GLBX.MDP3`, `XNAS.ITCH`, `OPRA.PILLAR` or `EQUS.MINI`. |
| Symbols | Up to 2,000 symbols, one per line, or `ALL_SYMBOLS`. |
| Schema | trades, mbo, mbp-1, mbp-10, tbbo, bbo-1s, bbo-1m, ohlcv-1s, ohlcv-1m, ohlcv-1h, ohlcv-1d, definition, statistics, status or imbalance. |
| Start, End | `YYYY-MM-DD`, ISO 8601 such as `2022-06-06T14:30` (UTC unless a zone is given) or UNIX nanoseconds. The end is exclusive. |
| Input and output symbology type | raw_symbol, instrument_id, parent or continuous. |
| Field list encoding | Fields mode: json, csv or dbn. |
| Maximum results | Row cap for the run, sent to Databento as the documented `limit` in the records mode. |
| Maximum Databento cost (USD) | Records mode: the run stops before streaming if Databento estimates more. 0 turns the check off. |
| API key | Your Databento API key, as a secret input, or the `DATA_API_KEY` secret. |

### Costs on the Databento side

- Databento bills **time series data** to your own account, per byte it streams, at the dataset's unit price. New accounts get free credits. Metadata, cost estimates and symbology are free.
- The records mode always sends your maximum results as the documented `limit`, so Databento stops sending, and billing, at that many records. Repeating the same streaming request is billed again; for large or repeated pulls Databento recommends its batch download in the portal.
- Your Databento license terms for each dataset apply to how you use and redistribute the data. Exchange data such as CME and OPRA usually carries display and redistribution restrictions; this actor delivers data to you only.

### FAQ

#### What is a historical market data API used for?

Getting exchange data at full granularity into your own code. A quant backtests a futures strategy on CME Globex trades and MBP-10 depth. An analyst pulls daily OHLCV bars for a list of US stocks into a spreadsheet. A risk team loads settlement prices and open interest from the statistics schema. A data engineer maps raw symbols to instrument IDs before joining feeds.

#### Which data source does this actor read?

The Databento Historical HTTP API at hist.databento.com, documented at databento.com/docs under API reference - Historical. It calls the metadata routes (list_publishers, list_datasets, list_schemas, list_fields, list_unit_prices, get_dataset_condition, get_dataset_range, get_record_count, get_billable_size, get_cost), timeseries.get_range in JSON encoding and symbology.resolve. The docs and the live host were checked on 2026-10-05.

#### Do I need a Databento account?

Yes. This actor is bring-your-own-key and never ships one. Create a Databento account, copy a key from the API keys page and paste it in. A missing or refused key ends the run cleanly with a message saying which it was.

#### How are prices and timestamps formatted?

Databento prices are fixed-precision integers where one unit is 0.000000001. The actor asks Databento to scale them (pretty_px) and keeps the exact decimal string, for example `"4108.500000000"`, in `pricesExact`, with the same value as a number in the field itself. Timestamps arrive as ISO 8601 with nine fractional digits (pretty_ts); a `ts_event_ns` style column carries the exact UNIX nanoseconds. Undefined prices and timestamps are null.

#### How do I keep the Databento bill under control?

Run the cost preview first, keep the maximum results low while testing, and leave the maximum Databento cost at a value you are happy with. The records mode asks Databento for the cost of the exact request, limit included, and streams nothing if it is higher.

#### Can I get continuous futures or a whole futures chain?

Yes. Set the input symbology type to continuous for symbols such as `ES.c.0` (front month by calendar) or `ES.v.0` (by volume), or to parent for `ES.FUT` (every ES future) or `ES.OPT` (every ES option).

#### Can this actor change anything in my Databento account?

No. It reads only and never submits batch jobs. The key is sent only as HTTP basic auth to hist.databento.com, is never logged, and is stripped from any error text.

#### How is it priced?

Pay per result: one price per market data record, cost preview or metadata row. Requests that find nothing are free. Databento bills the data itself separately to your own account.

### Example output

```json
{
  "mode": "records",
  "modeLabel": "Market data records",
  "recordType": "marketData",
  "found": true,
  "dataset": "GLBX.MDP3",
  "schema": "trades",
  "id": "GLBX.MDP3:1",
  "name": "ESM2",
  "symbol": "ESM2",
  "instrumentId": 3403,
  "publisherId": 1,
  "tsEvent": "2022-06-06T00:00:00.070033767Z",
  "tsRecv": "2022-06-06T00:00:00.070314216Z",
  "price": 4108.5,
  "size": 1,
  "side": "A",
  "action": "T",
  "value": 4108.5,
  "rtype": 0,
  "depth": 0,
  "flags": 0,
  "ts_in_delta": 18681,
  "sequence": 157862,
  "ts_recv": "2022-06-06T00:00:00.070314216Z",
  "ts_recv_ns": "1654473600070314216",
  "ts_event": "2022-06-06T00:00:00.070033767Z",
  "ts_event_ns": "1654473600070033767",
  "pricesExact": { "price": "4108.500000000" },
  "retrievedAt": "2026-10-05T09:14:52.118Z",
  "note": null
}
```

The record is the one in the provider's own get_range example. OHLCV rows fill `open`, `high`, `low`, `close` and `volume`; MBP rows carry `levels` and fill `bidPrice`, `askPrice`, `bidSize` and `askSize` from the top level; a cost preview fills `costUsd`, `recordCount` and `billableSizeBytes`; a symbol mapping fills `symbol`, `resolvedSymbol`, `start` and `end`.

### Keyword map

market data API, historical market data, tick data API, futures data API, CME data, order book data, level 2 market data, OHLCV bars API, stock market data API, options data OPRA, Databento API, Databento historical, Databento Python alternative, backtesting data.

# Actor input Schema

## `mode` (type: `string`):

Datasets lists the dataset codes your key can see, with their venues, and needs nothing else, so it is the default. Market data records streams the data itself and is billed by Databento to your account; run Cost preview first, which is free on the Databento side. Resolve maps symbols to instrument IDs and back for free. The other modes list publishers, schemas, fields, the available date range, daily data condition and unit prices.

## `dataset` (type: `string`):

The dataset code, PUBLISHER.DATASET. For example GLBX.MDP3 (CME Globex futures and options), XNAS.ITCH (Nasdaq TotalView), OPRA.PILLAR (US equity options), EQUS.MINI (US equities mini), DBEQ.BASIC, XNYS.PILLAR, IFEU.IMPACT (ICE Europe), XEUR.EOBI (Eurex). The datasets mode lists the ones your key sees.

## `symbols` (type: `array`):

Cost preview, records and resolve. Up to 2,000 symbols in the input symbology type, one per line, such as ESM2, AAPL, ES.FUT or ES.c.0. ALL_SYMBOLS selects every instrument in the dataset, which can be large and costly.

## `schema` (type: `string`):

Records, cost preview and fields. The record format to read. Not every dataset carries every schema; the schemas mode lists a dataset's own.

## `start` (type: `string`):

Inclusive start, as YYYY-MM-DD (midnight UTC), an ISO 8601 date-time such as 2022-06-06T14:30 (UTC unless a zone is given) or UNIX nanoseconds. Records filter on ts_recv where the schema has it. Datasets, condition and resolve use the date part.

## `end` (type: `string`):

Exclusive end, in the same forms. Leave empty to let Databento forward fill it from the start's resolution.

## `stypeIn` (type: `string`):

How the symbols are written.

## `stypeOut` (type: `string`):

Records and resolve. The symbology to map to; must be a valid combination with the input type (raw symbol to instrument ID is the usual one).

## `fieldsEncoding` (type: `string`):

Fields mode. The encoding whose fields to list. JSON matches what the records mode returns.

## `maxResults` (type: `integer`):

The most rows this run returns and charges for. In the records mode it is sent as the documented limit, so Databento stops sending, and billing, at this many records.

## `maxCostUsd` (type: `number`):

Records mode. Before streaming, the actor asks Databento for the cost of the request (free) and stops without streaming if it is above this many US dollars. Databento bills the data to your own account. Set 0 to turn the check off.

## `apiKey` (type: `string`):

Your own Databento API key, from the API keys page of the Databento portal (32 characters, starting with db-). Stored as a secret. You can instead set the DATA_API_KEY environment secret.

## Actor input object example

```json
{
  "mode": "datasets",
  "dataset": "GLBX.MDP3",
  "symbols": [
    "ESM2"
  ],
  "schema": "trades",
  "start": "2022-06-06T14:30",
  "end": "2022-06-06T14:35",
  "stypeIn": "raw_symbol",
  "stypeOut": "instrument_id",
  "fieldsEncoding": "json",
  "maxResults": 100,
  "maxCostUsd": 1
}
```

# Actor output Schema

## `records` (type: `string`):

One row per market data record, cost preview, symbol mapping or metadata item.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "dataset": "GLBX.MDP3",
    "symbols": [
        "ESM2"
    ],
    "start": "2022-06-06T14:30",
    "end": "2022-06-06T14:35"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/historical-market-data-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "dataset": "GLBX.MDP3",
    "symbols": ["ESM2"],
    "start": "2022-06-06T14:30",
    "end": "2022-06-06T14:35",
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/historical-market-data-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "dataset": "GLBX.MDP3",
  "symbols": [
    "ESM2"
  ],
  "start": "2022-06-06T14:30",
  "end": "2022-06-06T14:35"
}' |
apify call nabeelbaghoor/historical-market-data-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/historical-market-data-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/19E78l6LKeVUBcnQ4/builds/InK83rY6n6nHHCWsa/openapi.json
