Discover API

The Discover API helps LLM agents and programmatic clients find relevant datasets using natural language queries. Unlike the Search endpoint, Discover returns enriched metadata including column schemas, canonical questions, and relevance scores designed for machine consumption.

Authentication

The Discover endpoint requires authentication. Pass your API key in the Authorization header. See the Authentication guide to get your key.

Request
GET /v1/discover?q=inflation+data
Authorization: Bearer od_live_your_key_here

Parameters

ParameterTypeDefaultDescription
qstringrequiredNatural language query describing the data you need
providerstringnullFilter by provider slug (e.g. bls, census)
categorystringnullFilter by category or subject tag
formatstringnullFilter by data format
statusstring"ready"Filter by dataset status
limitint (1-20)5Maximum number of results
include_columnsbooltrueInclude column schemas in each result

Response Shape

Each result includes enriched metadata that goes well beyond basic search results. Null fields are omitted for a clean payload. Here is what a typical response looks like:

{
"results": [
{
"name": "Life Expectancy",
"provider": "owid",
"path": "/v1/datasets/owid/life-expectancy",
"description": "Life expectancy data by country...",
"rows": 19504,
"format": "auto",
"categories": ["demographics", "health"],
"temporal_granularity": "annual",
"geographic_scope": "country",
"canonical_questions": [
"How has life expectancy changed over the past 50 years?"
],
"methodology_summary": "Compiled from UN Population Division...",
"columns": [
{
"name": "life_expectancy",
"type": "float",
"sample_values": ["28.15", "37.93", "51.02"],
"distinct_count": 996,
"display_name": "Life Expectancy (years)",
"value_range": {"min": 18.2, "max": 86.37}
}
],
"available_views": [
{"name": "latest", "description": "Most recent life expectancy by country"},
{"name": "by-country", "description": "Time series by country"}
],
"relevance": 0.94,
"semantic_score": 0.82,
"quality_score": 0.87,
"is_enriched": true
}
],
"total": 3,
"query": "life expectancy by country",
"processing_time_ms": 142,
"available_categories": ["demographics", "economics", "education", "health", "labor"]
}

Key fields

  • columns - Column schemas with types, sample values, display names, value ranges, and units. Use these to construct follow-up queries without a separate columns introspection call.
  • available_views - Named views that pre-aggregate or transform the raw data. Saves a separate /views call.
  • available_categories (top-level) - All platform category slugs, so agents know what category= values are valid.
  • canonical_questions - Example questions the dataset can answer. Useful for LLM agents deciding which dataset to query.
  • sample_rows - Up to 5 representative rows (when available), letting agents evaluate data format without a SQL call.
  • path - The API path to fetch actual data rows from this dataset.
  • relevance / semantic_score / quality_score - Scoring breakdown to help agents rank and select datasets programmatically.
  • is_enriched - Whether LLM-generated metadata (categories, canonical questions, methodology) is available for this dataset.

Batch Discover

Run multiple queries in a single call. Results are deduplicated across queries, so datasets matching multiple topics appear once with full metadata.

POST /v1/discover/batch
curl -X POST 'https://api.tryopendata.ai/v1/discover/batch' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"queries": ["healthcare spending", "life expectancy", "drug prices"],
"limit_per_query": 3,
"deduplicate": true
}'

The response includes query_results (per-query dataset references with relevance) and datasets (deduplicated full metadata). This is useful for multi-agent workflows where a main thread discovers everything upfront and dispatches agents with pre-identified datasets.

Finding Datasets

Pass a natural language query describing the data you are looking for. The endpoint combines text search with semantic similarity to find the best matches.

Request
GET /v1/discover?q=county+level+poverty+rates
Authorization: Bearer od_live_...
Response
{
"results": [
{
"name": "Small Area Income and Poverty Estimates",
"provider": "census",
"path": "/v1/datasets/census/saipe",
"relevance": 0.91,
...
}
],
"total": 2,
"query": "county level poverty rates",
"processing_time_ms": 98
}

Using Column Schemas for Follow-up Queries

The column schemas in discover results give you everything you need to construct a data query without an extra API call. Here is a two-step workflow:

Step 1: Discover the dataset

Request
GET /v1/discover?q=monthly+employment+statistics&provider=bls
Authorization: Bearer od_live_...

Step 2: Query using column info from the response

The response tells you the column names, types, and sample values. Use that to build a filtered query:

Request
GET /v1/datasets/bls/employment?filter[year][gte]=2020&sort=-year&limit=50
Authorization: Bearer od_live_...

Filtering Results

Narrow discover results by provider, category, or format:

Request
# Only BLS datasets
GET /v1/discover?q=employment&provider=bls
Authorization: Bearer od_live_...
# Only economics category
GET /v1/discover?q=prices&category=economics
Authorization: Bearer od_live_...

Lighter Responses

If you only need dataset-level metadata and want to skip column schemas, set include_columns=false for a smaller payload:

Request
GET /v1/discover?q=inflation&include_columns=false
Authorization: Bearer od_live_...

Discover vs Search

 /v1/search/v1/discover
AuthNot requiredRequired
AudienceHuman users, web UILLM agents, programmatic clients
MetadataBasic (name, description, provider)Enriched (columns, questions, methodology)
ScoringText relevanceSemantic + quality scoring
FacetsYesNo
ViewsNoYes (available_views per dataset)
BatchNoYes (POST /v1/discover/batch)

Related

Search datasets

Search for datasets or run quick actions