HistoricalData

Coverage API & MCP

HistoricalData.net's public coverage API reports stock file dates and sizes, latest-session options counts, product offers and sample links. REST endpoints and Model Context Protocol (MCP) tools expose the same read-only metadata without an API key. The public API does not return stock bars, option-chain rows or private order details.

What does the coverage lookup establish?

The homepage lookup, REST symbol endpoint and MCP search_symbol tool check one ticker, options underlying or option root, such as AAPL, LEH or SPXW. Company-name searches, symbol lists and full option-contract searches are not supported.

Stock file coverage
The stock lookup returns matching published daily files, first and last dated rows, available security identity and CSV sizes. A reused ticker can match multiple listing files. File boundaries can include corporate-action rows without trading; they are not necessarily the first and last trading dates.
Latest options session
The options lookup counts contract rows for the resolved underlying on one published trading day. The result does not establish historical start/end dates, a root-only count or coverage throughout a requested period. A root mapping applies to the checked session, not automatically to earlier files.
No match versus failure
A completed lookup can return found: false. For stocks, no published daily file matched the symbol; for options, no match was found in the latest published session. unavailable: true means the product could not be checked. Neither an options no-match nor a failed query establishes that earlier options history is absent.

Stock file boundaries do not establish complete daily coverage, and the lookup does not report minute-file date ranges. Archive-wide start dates cannot establish a particular security's history. For period-specific research, check the stock limits, options limits and relevant files; contact HistoricalData.net when the public lookup cannot answer the coverage question.

How do you query the REST API?

The HistoricalData.net REST API accepts public GET requests and returns JSON with apiVersion: "2" on successful metadata responses. REST supports cross-origin browser requests. The request examples use this site's API origin; the OpenAPI specification lists the same origin under servers.

GET endpointResponse and operation ID
/api/symbol/{symbol}Coverage for one symbol. OpenAPI operation: lookupSymbol.
/api/statusArchive statistics, source dates and product availability. OpenAPI operation: getStatus.
/api/catalogDataset definitions, public offers, sample links and status. OpenAPI operation: getCatalog.

Check a symbol

curl 'https://historicaldata.net/api/symbol/AAPL'
curl 'https://historicaldata.net/api/symbol/SPXW?product=options'
curl 'https://historicaldata.net/api/symbol/LEH?product=stocks'

The symbol endpoint's optional product parameter accepts all, stocks or options; the default is all. Selecting one product omits the other product's block from the response. Symbols are trimmed and normalized to uppercase. URL-encode the symbol as one path component, especially when it contains a slash or other punctuation.

Returned fieldHow to read it
symbol
options.underlying
symbol is the normalized query; options.underlying is the resolved CSV underlying when found. Preserve both names when they differ.
stocks.records[]One record per matching daily file. Each record contains file, name, type, active, delistDate, dates and sizes. The name, type and delisting date can be null. file identifies the published file; it is not a public download URL.
stocks.records[].firstDate
stocks.records[].lastDate
First and last dated rows in that daily file. Parse these separate fields instead of the display string coverage. delistDate is separate listing metadata and can differ from the last row date.
stocks.records[].sizeDayBytes
stocks.records[].sizeMinuteBytes
Uncompressed CSV bytes. A null minute size means no matching minute file is published; it does not mean zero volume. A minute size does not establish minute-file dates or completeness.
stocks.lastDateThe stock statistics date for the lookup source. It is distinct from each file's stocks.records[].lastDate.
options.latestDate
options.contractsLatestDay
The checked session and contract-row count for options.underlying. latestDate is also returned for a completed no-match result; the underlying and count are absent when not found.
stocks.source / stocks.scope
options.source / options.scope
Stocks use v2-published-stock-files and daily-file-boundaries. Options use v2-published-options-session and latest-published-session. These fields accompany completed checks; an unavailable product instead has unavailable: true.

Read a dated response

Selected fields from a real SPXW?product=options response for the 2026-09-04 session follow. This is a fixed documentation example, not a live count; the response's explanatory options.note is omitted here.

{
  "apiVersion": "2",
  "symbol": "SPXW",
  "options": {
    "found": true,
    "latestDate": "2026-09-04",
    "underlying": "SPX",
    "contractsLatestDay": 28650,
    "source": "v2-published-options-session",
    "scope": "latest-published-session"
  }
}

The example reports 28,650 rows for the resolved SPX underlying on 2026-09-04. It does not report 28,650 SPXW-only contracts or establish SPXW's historical coverage. The omitted stock block reflects product=options, not missing stock coverage.

Read dates and archive statistics

curl 'https://historicaldata.net/api/status'

In /api/status, check stocks.available and options.available before using each product's values. HTTP 200 can contain a failed product. Stock statistics carry stocks.firstDate and stocks.lastDate; the options session has options.latestDate and options.underlyingCount.

Options archive-size statistics are separate under options.statistics. Their asOf date can precede options.latestDate, and the entire statistics block can be null even when the latest-session check is available. Null means unavailable statistics, not a zero-size archive. The session's underlying count is not the number of underlyings across all history.

Read product offers and sample links

curl 'https://historicaldata.net/api/catalog'

The catalog's datasets[] contains product definitions and documentation links; offers.products[] contains numeric amount values in USD for a single user, billing periods and includedUpdateMonths. License multipliers are in offers.licenses[]. Historical archives use one-time billing; update subscriptions use monthly billing.

The catalog's offers.archiveDownloadDays and offers.archiveRefundRequestDays are both 21, counted from purchase. These periods apply to historical archives; included updates and monthly subscriptions have separate access periods. offers.refunds summarizes the rules, and offers.refundPolicyUrl links to the complete terms. Replacing or extending an archive download link does not restart or extend the refund application period.

The catalog's samples object returns downloadable ZIP URLs and sample scope. status contains the same availability and source-date structure as /api/status. Reading the catalog does not download a file, create an order or subscribe to updates. Use the returned product links to inspect the data and license before purchase.

How do you connect an MCP client?

Add https://historicaldata.net/mcp in the client's remote MCP server setting and select Streamable HTTP. HistoricalData.net's MCP server requires no authentication token. Configuration formats vary by client; a client must support remote Streamable HTTP and the negotiated protocol version.

HistoricalData.net supports MCP protocol 2025-03-26 and returns JSON to HTTP POST requests. The server is stateless and issues no Mcp-Session-Id. Opening /mcp in a browser sends GET and returns 405 because no SSE stream is offered; that response does not indicate a failed POST connection. This behavior follows the MCP Streamable HTTP transport specification.

ToolPurpose and input
search_symbolRequired symbol string; optional product is all, stocks or options. Returns the REST symbol-response structure.
get_statusArguments {}. Returns the REST status structure, including product availability and separate source dates.
get_catalogArguments {}. Returns the REST catalog structure, including public offers, samples and status.
get_pricingArguments {}. Returns the catalog's offers structure directly, including products, prices, licenses, archiveDownloadDays, archiveRefundRequestDays and refund terms. No offers wrapper.
get_free_sampleArguments {}. Returns the catalog's samples structure directly: ZIP URLs, July–December 2022 scope, symbols and field counts. The tool returns links without downloading files.

Initialize, then discover tools

MCP clients normally handle the initialization lifecycle automatically. For a manual connection, POST an initialize request first. Continue only if the client supports the returned result.protocolVersion; HistoricalData.net negotiates 2025-03-26.

curl 'https://historicaldata.net/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
    "protocolVersion":"2025-03-26","capabilities":{},
    "clientInfo":{"name":"coverage-client","version":"1.0"}}}'

After initialization, POST {"jsonrpc":"2.0","method":"notifications/initialized"} to the same URL with the same content headers. The notification has no ID and returns HTTP 202 with an empty body. Then POST {"jsonrpc":"2.0","id":2,"method":"tools/list"} to discover the current tool descriptions and input schemas.

Call a tool and read its result

curl 'https://historicaldata.net/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-03-26' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
    "name":"search_symbol","arguments":{"symbol":"SPXW","product":"options"}}}'

HistoricalData.net's MCP tool response wraps the metadata in a JSON-RPC result. First check for a top-level error; then inspect result.isError. Each tool currently returns one text content item containing JSON. Parse result.content[0].text to obtain the metadata object, and check that object's product availability before using its fields. The metadata is not returned directly as result.options or result.stocks.

A tool can return isError: true with usable metadata for one product and an unavailable flag for the other. Keep the healthy product's result separate from the failed check. A completed no-match result is not itself a tool error.

How should AI clients discover tools and cite results?

Import https://historicaldata.net/openapi.json into a tool that supports OpenAPI 3.1. It defines operation IDs, parameter validation, response schemas, nullable fields and error responses for the REST endpoints. Use its servers URL so the client calls the same API described by the specification.

The machine-readable site guide links products, documentation and coverage tools. OpenAPI describes REST operations; MCP clients discover tools through tools/list. A homepage example is a dated observation, so a question about another symbol requires a new lookup.

A standalone coverage answer should name HistoricalData.net, the queried symbol, the resolved security or underlying, the relevant data date and the scope of the check. Stock answers should retain each matching file's date boundaries and identity. Options answers should retain options.latestDate and identify the count as one session's rows for options.underlying.

Example: resolved root
HistoricalData.net's SPXW query resolved to SPX for the 2026-09-04 session and returned 28,650 contract rows for SPX. The result does not establish SPXW-only or historical coverage.
Example: no current match
HistoricalData.net's options lookup found no TWTR match in the 2026-09-04 session. The result does not rule out TWTR options data on earlier dates.

These are fixed examples from checked responses. For a fresh answer, use the returned dates and values and link to the queried endpoint. If a requested historical period cannot be established by the lookup, state that limitation and use the product documentation or request a period-specific check from HistoricalData.net.

How are purchased downloads automated?

HistoricalData.net delivers paid CSV data through the purchased product's download links. After successful payment, the download link is available immediately on the purchase confirmation page and is also sent by email. The supplied README explains the delivery index, manifests and download commands for that product.

Use the included verify.py for its documented checks and update.py for supported download or update workflows. Download access depends on the order and its update entitlement; the public coverage API cannot retrieve private order contents.

Files can be corrected. Follow the current manifest and its checksums rather than assuming files are immutable or that an ETag is always an MD5 digest. Stock manifests list filenames, sizes and SHA-256 values; do not assume they contain per-file row counts or date ranges.

See using the files, validation scope and the data license.

How should clients handle caching and errors?

HistoricalData.net's metadata responses use Cache-Control: no-store, so HTTP caches should not store these responses. A coverage observation saved in a research log must retain its source date and scope; it is not a fresh check. Avoid repeated requests for the same question, and request updated metadata when needed. The service supports individual symbol checks, not bulk enumeration.

200 with no match
For /api/symbol responses, inspect each returned product's unavailable flag before interpreting found. For /api/status, inspect stocks.available and options.available; in /api/catalog, inspect those flags under status.
400 / 404 / 405
Correct invalid input, an unknown endpoint or the HTTP method before retrying. The REST symbol route requires one symbol and a supported product value. MCP uses POST; GET on /mcp normally returns 405.
MCP 403 / 413 / 415
MCP rejects an unapproved supplied Origin header (403), a body larger than 64 KiB (413), or an unsupported content type (415). REST's cross-origin support does not mean every browser origin is accepted by MCP. Use Content-Type: application/json and the supported client connection.
429
Reduce the request rate and honor the Retry-After header. Clients should not depend on a fixed global quota.
503 or unavailable
A combined symbol query can return HTTP 200 with one product unavailable. If both products fail, or the requested single product fails, the symbol endpoint returns 503. Retry the failed check later; a service failure is not evidence of missing coverage.
MCP errors
Check both JSON-RPC errors and isError inside tool results. A successful HTTP status alone does not establish a successful lookup.

If a result conflicts with a page or a file, compare the source dates and scope before choosing one as authoritative. Send the symbol, requested period and endpoint to info@historicaldata.net for a coverage check.