# Global Health & Epidemic Statistics Scraper (`ninhothedev/global-health-stats-scraper`) Actor

$0.5/1K 🔥 Global health stats scraper! Country epidemic counters, historical curves & vaccination data. No key. JSON, CSV, Excel or API in seconds. Feed dashboards & research ⚡

- **URL**: https://apify.com/ninhothedev/global-health-stats-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Global Health & Epidemic Statistics Scraper

Scrape **country-level epidemic counters, vaccination coverage curves, daily historical time series and continent rollups** into one flat table — no API key, no login, no proxy required.

The Actor pulls from the free public [disease.sh](https://disease.sh) v3 API (the aggregation layer over Johns Hopkins CSSE, Our World in Data vaccination data and world population figures) and turns its nested JSON into clean, one-row-per-record datasets you can export as **CSV, JSON, Excel, XML or feed straight into a BI tool**.

***

### ⚠️ Read this first: how fresh is this data?

**Be aware that these are historical, largely frozen pandemic-era datasets — not a live outbreak feed.** We would rather tell you up front than have you discover it after a run. Measured on **28 July 2026**:

| Mode | Data coverage actually observed | Status |
|---|---|---|
| `countries` | Cumulative totals per country; `updated` field re-stamped **2026-07-28T17:57:28Z** | Timestamp is live, **the numbers are not** — `todayCases` / `todayDeaths` came back null/zero for **all 231 countries** |
| `historical` | **2020-01-22 → 2023-03-09** (1,143 days) | Frozen. Johns Hopkins CSSE stopped collecting on 10 March 2023 |
| `vaccine` | **2021-06-13 → 2025-07-21** (1,500 days available) | Frozen at the tail; recent days repeat the same cumulative dose count |
| `continents` | 6 continents, same cumulative basis as `countries` | Frozen, timestamp re-stamped |

In plain words: the `updated` field will always look like "a few minutes ago" because the disease.sh servers restamp their cache — but the underlying counters have not moved since the global COVID-19 reporting programmes wound down. **Treat this as an archive of the pandemic, which is exactly what makes it useful** for teaching, retrospective epidemiology, dashboard prototyping and reproducible research: the numbers are stable, complete and free.

If you need *currently updated* official health indicators (immunization coverage, life expectancy, mortality, NCDs, health-system metrics), use the sibling Actor described below.

### How this differs from `who-gho-scraper`

They are complementary, not duplicates:

| | **who-gho-scraper** | **global-health-stats-scraper** (this one) |
|---|---|---|
| Source | WHO Global Health Observatory (official WHO indicator API) | disease.sh v3 (JHU CSSE + OWID aggregation) |
| Shape | **Indicator time series** — pick an indicator code, get country-year values with WHO dimensions | **Country-level epidemic counters, curves and continent rollups in one flat schema** |
| Content | Thousands of health indicators: life expectancy, immunization, TB, malaria, NCDs, health financing | Pandemic case/death/test/recovery counters, per-million rates, CFR, vaccine doses, continent aggregates |
| Granularity | One row per indicator × country × year | One row per country (current) or per country × **day** |
| Recency | Updated by WHO on its own reporting cycle | Frozen archive — see the table above |

Use `who-gho-scraper` for official WHO indicator research. Use **this** Actor when you want the flat, daily-granular epidemic counter table with per-million normalisation and ready-made day-over-day diffs.

***

### Modes

Every mode was probed against the live API before shipping; retired disease.sh sub-APIs (`/v3/influenza/*`, `/v3/gov/*` — both return **404**) are deliberately **not** offered, so no mode can silently return nothing.

#### 1. `countries` — current per-country counters (default)

One row per country: cases, deaths, recovered, active, critical, tests, plus population, ISO codes, coordinates, flag URL, per-million rates and a computed case-fatality percentage. 231 countries available.

#### 2. `historical` — daily time series

The disease.sh timeline is a **dict keyed by a `M/D/YY` string** (`"3/9/23"` = 9 March 2023). This Actor un-pivots it into proper chronological rows with ISO dates and computes `new_cases` / `new_deaths` day-over-day diffs for you (first row is `null`, never a fake zero).

#### 3. `continents` — rollups

Six continent aggregates with the member-country list included.

#### 4. `vaccine` — vaccination coverage curves

Cumulative doses administered per country and day, with `new_doses` diffs.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `countries` | `countries`, `historical`, `continents` or `vaccine` |
| `countries` | array | `["Germany","USA","Brazil"]` | Country names or ISO-2/ISO-3 codes. Empty = all countries (`countries` mode) |
| `lastDays` | integer | `30` | Days of history for `historical` / `vaccine` (max `1500` = full series) |
| `continentFilter` | string | – | `Europe`, `Asia`, `Africa`, `North America`, `South America`, `Australia-Oceania` |
| `maxItems` | integer | `500` | Row cap (max `5000`) |

```json
{
  "mode": "historical",
  "countries": ["Germany", "USA", "Brazil"],
  "lastDays": 90,
  "maxItems": 1000
}
```

### Output

`countries` mode:

```json
{
  "type": "country",
  "country": "Germany",
  "iso2": "DE",
  "iso3": "DEU",
  "continent": "Europe",
  "population": 83883596,
  "latitude": 51,
  "longitude": 9,
  "flag_url": "https://disease.sh/assets/img/flags/de.png",
  "cases": 38828995,
  "today_cases": null,
  "deaths": 183027,
  "today_deaths": null,
  "recovered": 38240600,
  "active": 405368,
  "critical": null,
  "tests": 122332384,
  "cases_per_million": 462891,
  "deaths_per_million": 2182,
  "tests_per_million": 1458359,
  "active_per_million": 4832.51,
  "critical_per_million": null,
  "case_fatality_pct": 0.471,
  "updated": "2026-07-28T17:57:27Z",
  "source": "disease.sh",
  "scraped_at": "2026-07-28T18:07:27Z"
}
```

`historical` mode:

```json
{
  "type": "historical",
  "country": "Germany",
  "province": "mainland",
  "date": "2023-03-09",
  "cases": 38249060,
  "deaths": 168935,
  "recovered": 0,
  "new_cases": 7829,
  "new_deaths": 127,
  "source": "disease.sh",
  "scraped_at": "2026-07-28T18:07:28Z"
}
```

`vaccine` mode returns `doses_administered` + `new_doses`; `continents` mode returns the aggregate counters plus the `countries` member list. Every field is nullable — missing upstream values stay `null` instead of being faked as `0`.

### Use cases

- **Public health dashboards** — a stable, key-less backing dataset for Grafana / Power BI / Looker Studio prototypes with per-million normalisation already computed.
- **Epidemiology research** — reproducible cumulative and incident curves for 231 countries over the full 2020–2023 window, with the `M/D/YY` timeline properly parsed.
- **Data journalism** — cross-country comparisons of case-fatality rates, testing intensity and vaccination rollout speed, exportable to CSV in one click.
- **Teaching datasets** — a clean, frozen, well-documented time series for statistics, data-science and public-health courses; results never shift under students' feet mid-semester.

### Pricing

Roughly **$0.50 per 1,000 rows** on the Apify platform, plus the usual platform compute. A full `countries` run is 231 rows; a 90-day, 3-country `historical` run is 270 rows.

### Notes & limits

- The upstream API is free and key-less but rate-limited; requests are batched (up to 20 countries per historical call) and paced.
- `province` is usually `mainland`; a handful of territories are reported separately upstream.
- `recovered` is `0` for many countries after mid-2021 — that is an upstream reporting artefact, not a scraper bug.
- Unknown country names return no data for that country; the run raises a clear error if **nothing** was scraped.

### Related Actors

- [WHO GHO Scraper](https://apify.com/ninhothedev/who-gho-scraper) — official WHO indicator time series
- [OpenFDA Scraper](https://apify.com/ninhothedev/openfda-scraper) — drug, device and adverse-event records
- [Clinical Trials Scraper](https://apify.com/ninhothedev/clinical-trials-scraper) — ClinicalTrials.gov study registry
- [Country Profiles Scraper](https://apify.com/ninhothedev/country-profiles-scraper) — country reference data

### Legal

Data originates from public, freely accessible endpoints. disease.sh aggregates Johns Hopkins CSSE, Our World in Data and Worldometer figures; check their terms and cite the original sources in any publication. No personal data is collected.

# Actor input Schema

## `mode` (type: `string`):

Which dataset to scrape. 'countries' returns the current per-country epidemic counters (cases, deaths, tests, per-million rates). 'historical' returns one row per country and day (cumulative cases/deaths/recovered plus day-over-day diffs). 'continents' returns continent-level rollups. 'vaccine' returns the vaccination coverage time series (doses administered per country and day).

## `countries` (type: `array`):

Country names or ISO-2/ISO-3 codes to include, for example 'Germany', 'DE' or 'DEU'. Used by the 'countries', 'historical' and 'vaccine' modes. Leave empty in 'countries' mode to get every country; in 'historical' mode an empty list falls back to Germany, USA and Brazil. Ignored in 'continents' mode.

## `lastDays` (type: `integer`):

How many days of history to request for the 'historical' and 'vaccine' modes. 30 returns the last 30 days, 1500 returns the full available series. Ignored by the 'countries' and 'continents' modes.

## `continentFilter` (type: `string`):

Optional continent name to restrict the results, for example 'Europe', 'Asia', 'Africa', 'North America', 'South America' or 'Australia-Oceania'. Works in every mode; in 'historical' and 'vaccine' mode it expands to all countries of that continent.

## `maxItems` (type: `integer`):

Maximum number of dataset rows to push. One row equals one country (countries mode), one continent (continents mode) or one country-day (historical and vaccine modes). Keeps long multi-country time series under control.

## Actor input object example

```json
{
  "mode": "countries",
  "countries": [
    "Germany",
    "USA",
    "Brazil"
  ],
  "lastDays": 30,
  "maxItems": 500
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "countries": [
        "Germany",
        "USA",
        "Brazil"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/global-health-stats-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "countries": [
        "Germany",
        "USA",
        "Brazil",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/global-health-stats-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "countries": [
    "Germany",
    "USA",
    "Brazil"
  ]
}' |
apify call ninhothedev/global-health-stats-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ninhothedev/global-health-stats-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/QioMPbUaG5OxCPyhm/builds/WpAYamkWxbrFs7VGI/openapi.json
