REST API
HTTP endpoints for querying and analyzing historical events. All responses are JSON.
https://historank.fun/api/v1
Auth & rate limits
No authentication required. All endpoints are public and read-only.
| Header | Value | Meaning |
|---|---|---|
X-Cache | HIT / MISS | Whether the response was served from cache |
Cached responses (X-Cache: HIT) do not count against the rate limit.
Interactive docs
The full OpenAPI reference with live try-it-out is available at /docs.
Endpoints
GET/events
Query events across all four AI models with filtering, sorting, and pagination.
GET /api/v1/events?decade=1940&search=normandy&sort=-gemini_historical_significance_rating&limit=10
GET/events/{id}
Fetch a single event by its numeric ID.
GET /api/v1/events/4821
GET/events/aggregate
Aggregate events by one or more fields. Supports running totals and partitioned cumulative calculations.
aggregate: count · avg · min · max · sum · weighted_avg
GET /api/v1/events/aggregate?group_by=decade&aggregate=count&filter_gt=year:-500&filter_lt=year:1
GET/events/word-count
Word frequency analysis across the description field. Stop words excluded. Supports all standard filter params.
GET /api/v1/events/word-count?category=War&limit=50
GET/events/distinct/{field}
All distinct values for a field across the full dataset.
GET /api/v1/events/distinct/main_category
GET/models/{model_name}/events
Query events scoped to one AI model. Returns clean field names without the model prefix. Supports all the same params as /events.
model_name: gemini · deepseek · claude · chatgpt
GET /api/v1/models/gemini/events?century=19&sort=-historical_significance_rating
GET/models/{model_name}/events/aggregate
Aggregate events scoped to one model. Bare field names are auto-prefixed.
GET /api/v1/models/claude/events/aggregate?group_by=country_name&aggregate=count&filter_gt=count:20
GET/models/{model_name}/events/significance-buckets
Histogram of historical significance ratings for a model, grouped into buckets of configurable width.
GET /api/v1/models/deepseek/events/significance-buckets?bucket_size=10
GET/models/{model_name}/events/word-count
Word frequency across all tags for a model. Multi-word tags are tokenized; stop words excluded.
GET /api/v1/models/chatgpt/events/word-count?limit=100
GET/models/{model_name}/events/distinct/{field}
Distinct values for a field scoped to a specific model. Bare field names are auto-prefixed.
GET /api/v1/models/gemini/events/distinct/country_name
Filter params
All filter params use field:value format. Comma-separate for multiple conditions.
| Param | Operator | Example |
|---|---|---|
filter_gt | field > value | filter_gt=year:-100 |
filter_lt | field < value | filter_lt=year:1 |
filter_eq | field = value | filter_eq=main_category:War |
filter_ne | field != value | filter_ne=main_category:War |
filter_in | field IN (…) | filter_in=year:1939|1940|1945 |
filter_nin | field NOT IN (…) | filter_nin=main_category:War|Politics |
On aggregate endpoints, filter_gt/filter_lt on count, value, aggregated_value, or cumulative_value become HAVING clauses.
Date formats
| Format | Example | Notes |
|---|---|---|
| CE date | 1939-09-01 | Standard ISO 8601 |
| BC date | 0044-03-15 BC | Append space + BC |
| BC shorthand | -44-03-15 | Negative year prefix |
year param | year=-44 | BC years are negative integers |
decade param | decade=-40 | 44 BC → decade -40 |
century param | century=-100 | 44 BC → century -100 |
Sorting: prefix any field with - for descending. NULLs always sort last.
AI models
| Model | model_name | Field prefix |
|---|---|---|
| Gemini | gemini | gemini_ |
| DeepSeek | deepseek | deepseek_ |
| Claude | claude | claude_ |
| ChatGPT | chatgpt | chatgpt_ |
Model-specific fields: title · historical_significance_rating · historical_significance_explanation · tags · location · country_name · latitude · longitude