Querying Datasets
The reliable way to query Storywrangler is discovery-first: read the registry metadata, then construct queries from what it says actually exists. Never guess entity IDs, granularities, or date ranges.
Step 1 — discover datasets
GET /registry/ → all datasets (latest version each)
GET /registry/{domain}/{dataset} → one dataset's metadata
The per-dataset response contains everything needed to build a valid query:
level_order— the on-disk hive nesting, in order, with a type tag and default per level:
Levels typed[ {"column": "ngram_size", "type": "partition", "default_value": 1}, {"column": "granularity", "type": "partition", "default_value": "daily"}, {"column": "country", "type": "entity", "default_value": "Afghanistan"}, {"column": "date", "type": "time", "default_value": "2020-01-01"} ]partitionorfilterare the dimensions you may pass as query parameters; omitted ones fall back todefault_value.filter_values— the valid values per dimension, introspected from the data itself (e.g.{"ngram_size": [1, 2], "granularity": ["daily", "weekly"]}). A value outside this list returns an empty result, not an error.manifest.availability— min/max time coverage per entity and granularity. Check it before requesting a date range:{"United States": {"daily": {"min": "2024-01-01", "max": "2026-04-20"}}}endpoint_schema— the output shape: endpoint type (e.g.types-counts) and which columns hold types and counts.
Step 2 — resolve entities
Entity identifiers are namespaced (wikidata:Q30 = United States). To map
human names or local IDs to canonical entity IDs:
GET /registry/{domain}/{dataset}/adapter
→ [{"local_id": "united_states", "entity_id": "wd:Q30", "entity_name": "United States", ...}]
Step 3 — query an instrument
Each domain router exposes some subset of these instruments (see the per-domain endpoint reference sections for exact paths, parameters, and response shapes):
- Top n-grams — highest-count types for an entity over a date range.
Returns
{"data": [{"types": ..., "counts": ...}], "metadata": {...}}. - Term series — a per-term time series (date, counts, rank). Wikimedia's variant can include the top contributing Wikipedia articles per date. Batch variants accept comma-separated terms.
- Allotaxonometer — rank-turbulence divergence between two systems
(two entities, two date ranges, or both), computed in Rust. Returns the
diamond-plot histogram, wordshift contributions, and divergence metrics.
System-2 parameters use a
2suffix (entity2,dates2,sex2, ...).
With the SDK, the dataset-scoped client wires the discovery steps together:
wiki = client.dataset("wikimedia", "ngrams")
wiki.filters # step 1: what can I slice on?
wiki.availability # step 1: what dates exist?
wiki.allotax(entity="wikidata:Q30", entity2="wikidata:Q145",
dates="2026-05-01", dates2="2026-05-01",
ngram_size=1, granularity="daily")
Performance guidance
- Term lookups are case-sensitive.
COVIDandcovidare different terms. - Wikimedia term-series has a fast and a slow path. Terms in the precomputed vocabulary (~65K terms) return in tens of milliseconds; arbitrary terms fall back to scanning daily partition files (~3–5 s). Prefer vocabulary terms for interactive use.
- Skip what you don't need.
include_articles=falseon term-series is roughly 2× faster — only request articles when the user drills in. - Window the series.
window=0returns full history; usewindow=30orwindow=90when only recent data is needed. - Batch when comparing terms. The batch term-series endpoint fetches many sparklines in one request; missing terms come back as empty arrays, never errors.
- The
Server-Timingresponse header breaks down where query time went.
Error semantics
Structured error codes on the detail object:
404 DATA_NOT_AVAILABLE— the dataset is registered but its files are not on this server.500 QUERY_FAILED— the query itself failed; check parameters againstfilter_values.504 QUERY_TIMEOUT— the query exceeded the time limit; narrow the date range or use a coarser granularity.
An empty data/series array with a 200 status usually means the filter
values were valid types but matched nothing — re-check filter_values and
availability.