# Skill: Call the Quant Data API This file teaches an AI agent how to use the Quant Data market-data API end to end. Quant Data provides exchange-licensed US options and equities data: order flow, dealer exposure, implied volatility, dark-pool activity, open interest, market-wide stats, and ticker-tagged news. - Base URL: `https://api.quantdata.us` - MCP server: `https://api.quantdata.us/mcp` - Documentation: https://quantdata.us/api/docs - Full reference for agents: https://quantdata.us/llms-full.txt ## Anti-hallucination rules (read first) These are mandatory. Following them is what makes you useful instead of wrong. 1. Only call endpoints and tools that are listed in this file or in https://quantdata.us/llms-full.txt. Never invent an endpoint name, a tool name, a path, or a parameter. 2. Only use parameter names, field names, operations, and enum values that are documented. If you are unsure whether a field exists, do not pass it. Field-name matching is case-, separator-, and whitespace-insensitive, but the field must be a real documented field. 3. If a user asks for data Quant Data does not provide (crypto, forex, non-US markets, company fundamentals, filings, analyst estimates), say so plainly. Do not fabricate a response or pretend an endpoint exists. 4. Never invent API keys, prices, response values, or numbers. If you do not have a value, retrieve it with a real request or say you do not have it. 5. If you cannot determine the correct endpoint or parameters with confidence, stop and return the documentation URL (https://quantdata.us/api/docs) rather than guessing. 6. Prefer the MCP server when it is available in your environment. It exposes every endpoint as a typed tool, which removes most opportunities to hallucinate request shapes. ## Authentication Every request is authenticated with a single Bearer API key. - Header: `Authorization: Bearer ` - Key format: `qd_` followed by 32 alphanumeric characters (regex `^qd_[0-9A-Za-z]{32}$`). - Keys are created in the dashboard at https://v3.quantdata.us. Treat the key as a secret. Read it from configuration or the environment; never hard-code it and never echo it back to the user. - An active API subscription is required, and the OPRA market-data agreement must be signed (see Errors below). The same key authenticates both the REST API and the MCP server. ## Request conventions - Every endpoint is `POST` with a JSON body and `Content-Type: application/json`. There are no query-string or path parameters and no `GET` endpoints. - Path shape: `https://api.quantdata.us/v1/options/tool/` for options, `https://api.quantdata.us/v1/equities/tool/` for equities. Use the exact path shown on each endpoint's documentation page; a few paths are nested (for example `/v1/options/tool/order-flow/consolidated`), so do not assume the path equals the slug. - An empty body `{}` returns the latest completed trading session for that endpoint. - Common top-level fields (only pass the ones an endpoint documents): - When: `sessionDate` (`YYYY-MM-DD`) or `timeRange` (`{ "startTime": "...Z", "endTime": "...Z" }`, ISO 8601, start inclusive, end exclusive). Omit to get the latest session. - What: `filter` (a convenience object of exact camelCase fields) or `filterExpression` (the boolean DSL below). Both may be present and are combined with AND. - How: `aggregationPeriod`, `includes`, `excludes`, `size`, `sort` (only where documented). - Collection fields accept singular or plural names and a scalar or array value: `{"ticker":"AAPL"}`, `{"tickers":["AAPL","NVDA"]}` both work. - Enum values are UPPER_SNAKE_CASE in requests and responses (for example `CALL`, `PUT`, `BULLISH`). - Units in responses: monetary values are dollars with decimals (not cents), volumes and sizes are integer counts, and timestamps are epoch milliseconds. ## Filter expression DSL `filterExpression` is a recursive boolean tree. - Terminal node: `{ "field": "TICKER", "operation": "=", "values": ["AAPL"] }`. Use `value` for a single value or `values` for several (OR semantics within one terminal). - Compound node: `{ "conjunction": "AND", "filters": [ ...terminals or compounds... ] }`. `conjunction` is `AND` or `OR`. - Operations accept canonical or shorthand spellings: `EQUALS`/`=`, `DOES_NOT_EQUAL`/`!=`, `GREATER_THAN`/`>`, `GREATER_THAN_OR_EQUAL_TO`/`>=`, `LESS_THAN`/`<`, `LESS_THAN_OR_EQUAL_TO`/`<=`. - Limits: maximum nesting depth 5, maximum 100 total terminal filters. ## Pagination and projection (table-shaped endpoints only) The order-flow and equity-prints tools return rows and support these; aggregation and time-series tools do not. - `size`: rows per page, default 50, range 1 to 100. Order Flow Unconsolidated accepts up to 1000. - Cursor: each response includes `nextSearchAfter`. Pass it back verbatim as `searchAfter` on the next request. When `nextSearchAfter` is `null`, the walk is complete. Do not parse or modify the cursor, and do not change the filter, sort, session, or time range mid-walk. - Projection: `includes` (whitelist) or `excludes` (blacklist) of field names, mutually exclusive. Omit both to get every field. ## Rate limits - 240 requests per 60-second sliding window, plus a 20 requests per 1-second burst cap, counted per user (shared across all keys on the account and across REST and MCP). - Every response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (seconds). A `429` also includes `Retry-After`. - On `429`: sleep for at least `Retry-After` seconds, add 50 to 500 ms of jitter, then retry. Pace proactively when `X-RateLimit-Remaining` approaches zero. Stop after 2 to 3 consecutive `429`s rather than hammering. ## Errors Errors use RFC 9457 problem details (`application/problem+json`) with `type`, `title`, `status`, `detail`, and `instance`. Categories: - `400` validation: a field failed validation (see the `errors` array). Fix the field. - `400` bad-request: the body could not be parsed. Send valid JSON with the content type. - `401` authentication: key missing, malformed, unknown, or revoked. Check the key. - `403` authorization: no active API subscription. Direct the user to subscribe. - `403` opra-agreement-required: the OPRA agreement is unsigned. Surface the `agreementUrl`. - `422` data-unavailable: the request was valid but no data exists for those inputs. - `429` rate-limit-exceeded: back off as described above. - `500` internal: a server error; retry later and do not change the request blindly. ## Worked example Request the day's bullish vs bearish option premium leaderboard: ```bash curl -X POST https://api.quantdata.us/v1/options/tool/gainers-losers \ -H "Authorization: Bearer $QUANTDATA_API_KEY" \ -H "Content-Type: application/json" \ -d '{}' ``` Response (shape): ```json { "data": { "AAPL": { "bullishPremium": 6128974.25, "bearishPremium": 4821330.5, "premium": 11402108.75, "premiumRatio": 0.787, "tradeCount": 18472, "volume": 41208 } } } ``` Narrow it to one ticker on a specific session with a filter expression: ```json { "sessionDate": "2026-05-13", "filterExpression": { "conjunction": "AND", "filters": [{ "field": "ticker", "operation": "=", "values": ["AAPL"] }] } } ``` ## Choosing an endpoint Map the user's intent to an endpoint before calling. The routing map in https://quantdata.us/llms.txt covers the common intents (unusual options activity, dealer exposure and GEX, implied volatility and skew, dark pool, open interest, news, and more). The complete endpoint and tool list with paths is in https://quantdata.us/llms-full.txt. If the intent does not map to a listed endpoint, tell the user Quant Data may not cover it and link the docs rather than guessing.