hntavirus.com API
Public, read-only HTTP API for hantavirus surveillance data. Cases, news, WHO Disease Outbreak News, AI-written daily briefings and raw datasets. Free for research and journalism — please credit the site and upstream sources.
Base URL
https://hntavirus.com
Auth
none (public)
Format
JSON · GeoJSON · CSV · XML
CORS
open on /api/dataset/*, /api/cases
Public endpoints
| Method | Endpoint | |
|---|---|---|
| GET | /api/stats | Example |
| GET | /api/cases | Example |
| GET | /api/cases/by-country/{iso} | |
| GET | /api/country/{iso} | Example |
| GET | /api/news | Example |
| GET | /api/who-don | |
| GET | /api/sources | Example |
| GET | /api/timeseries | Example |
| GET | /api/briefing | Example |
| GET | /api/dataset/cases.geojson | |
| GET | /api/dataset/cases.csv | |
| GET | /api/dataset/news.json | |
| GET | /feed.xml | |
| GET | /sitemap.xml | |
| GET | /sitemap-news.xml |
GET/api/stats+
High-level dashboard counts.
cURL
curl https://hntavirus.com/api/stats
Response
{
"total": 107,
"confirmed": 24,
"suspected": 21,
"deaths": 9,
"locations": 30,
"lastOnset": 1778025600000
}GET/api/cases+
All case features as GeoJSON, paginated server-side and merged.
cURL
curl https://hntavirus.com/api/cases
Response
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "Point",
"coordinates": [8.6054, 47.4847]
},
"properties": {
"OBJECTID": 1,
"STATUS": "CONFIRMED",
"ONSET": 1778025600000,
"DEATH": null,
"LASTLOCATION": "ZURICH",
"SOURCE": "https://www.bag.admin.ch/...",
"Exposure_Group": "MV Hondius, Disembarked April 24th",
"DETAILS": "Departed ship, Swiss national, confirmed case"
}
}
]
}GET/api/country/{iso}+
Stats, recent cases, recent news, WHO DON entries, aggregate timeline.
cURL
curl https://hntavirus.com/api/country/{iso}Response
{
"stats": {
"iso": "CH",
"total": 2,
"confirmed": 1,
"suspected": 1,
"deaths": 0,
"newsCount": 0,
"donCount": 0
},
"recentCases": [
{
"objectId": 1,
"status": "CONFIRMED",
"location": "ZURICH",
"onset": 1778025600000,
"death": null,
"age": null,
"sex": 1,
"lon": 8.605,
"lat": 47.484
}
],
"recentNews": [],
"recentWho": [],
"aggregate": [
{ "day": "2026-05-12", "cases": 2, "confirmed": 1, "suspected": 1, "deaths": 0, "newsCount": 0 }
]
}GET/api/news+
Latest news ordered by pub_date DESC.
cURL
curl 'https://hntavirus.com/api/news?lang=es&limit=5'
Response
{
"source": "d1",
"items": [
{
"id": "978acd2b",
"title": "French and Spanish hantavirus evacuees test positive...",
"url": "https://www.sbs.com.au/news/article/...",
"source": "sbs.com.au",
"domain": "sbs.com.au",
"country": "AU",
"lang": "en",
"image": "https://...",
"pubDate": "2026-05-11T23:45:00.000Z",
"origin": "gdelt"
}
]
}GET/api/sources+
Live status of each upstream data source.
cURL
curl https://hntavirus.com/api/sources
Response
{
"sources": [
{ "source": "who_don", "ok": true, "lastRunAt": "2026-05-12T00:16:15.000Z", "count": 8, "ms": 1222 },
{ "source": "gdelt", "ok": true, "lastRunAt": "2026-05-12T00:16:15.000Z", "count": 35, "ms": 22142 },
{ "source": "promed", "ok": true, "lastRunAt": "2026-05-12T00:16:15.000Z", "count": 0, "ms": 17147 },
{ "source": "arcgis", "ok": true, "lastRunAt": "2026-05-12T00:16:15.000Z", "count": 107, "ms": 16878 }
]
}GET/api/timeseries+
Daily series for charts.
cURL
curl https://hntavirus.com/api/timeseries
Response
{
"kind": "cases",
"iso": null,
"days": 7,
"series": [
{ "day": "2026-05-06", "value": 3 },
{ "day": "2026-05-07", "value": 1 }
]
}GET/api/briefing+
AI-written daily briefing in the requested locale.
cURL
curl 'https://hntavirus.com/api/briefing?locale=es'
Response
{
"ok": true,
"source": "cached",
"briefing": {
"locale": "es",
"day": "2026-05-12",
"body": "Hasta hoy se han notificado...",
"generatedAt": "2026-05-12T01:15:00Z"
}
}Quick examples
cURL
# Stats curl https://hntavirus.com/api/stats # News (Spanish) curl 'https://hntavirus.com/api/news?lang=es&limit=5' # Country dashboard curl https://hntavirus.com/api/country/CH # Briefing (German) curl 'https://hntavirus.com/api/briefing?locale=de' # Dataset download curl -o cases.geojson \ https://hntavirus.com/api/dataset/cases.geojson
JavaScript
const r = await fetch( "https://hntavirus.com/api/country/CH" ); const data = await r.json(); console.log(data.stats.confirmed);
Python
import requests cases = requests.get( "https://hntavirus.com/api/dataset/cases.geojson" ).json() print(len(cases["features"]))
Errors
All error responses follow a consistent JSON shape: { "error": "human description" }
| Status | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad request body |
| 404 | Not found |
| 429 | Too many requests (Cloudflare default protection) |
| 500 | Server error |
| 502 | Upstream source failure |
Versioning, rate limits & attribution
- Current version:
v1(implicit). Breaking changes will move to/api/v2/*with a deprecation period. Schema additions are non-breaking. - Rate limits are soft, enforced by Cloudflare. Expect
429only under abuse. - Cache headers: most endpoints emit
Cache-Control: public, s-maxage=300, stale-while-revalidate=600. Bypass with?fresh=1where supported. - If you use the data publicly, please link back to hntavirus.com and credit upstream sources (ArcGIS / WHO DON / GDELT / ProMED / r/ContagionCuriosity).
Contact & issues
Issues, data corrections → open a GitHub issue or contact via the press page. Maintained by hntavirus.com.