# Travel Risk Report — Weather, Health, Crime & Disaster Advisory (`ryanclinton/travel-risk-report`) Actor

Comprehensive travel risk assessment tool that queries 8 data sources in parallel — geocoding, NOAA weather alerts, weather forecasts, GDACS disaster alerts, WHO Global Health Observatory indicators, UK police crime data, Interpol red notices, and REST Countries profiles — to produce a composite...

- **URL**: https://apify.com/ryanclinton/travel-risk-report.md
- **Developed by:** [ryan clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Stats:** 1 total users, 1 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

$200.00 / 1,000 analysis runs

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Travel Risk Report

Travel risk assessment for any destination in under 90 seconds — built for corporate travel managers, security teams, and tour operators who need a quantified, multi-source briefing before approving travel. Enter a city, country, or region and receive a composite risk score (0–100) with a formal advisory level, plus sub-scores for active alerts, health risks, and security conditions.

The actor queries 8 intelligence data sources in parallel — NOAA weather alerts, GDACS global disaster feeds, WHO Global Health Observatory indicators, UK police crime data, Interpol red notices, REST Countries geopolitical profiles, real-time weather forecasts, and Nominatim geocoding — then applies 4 independent scoring models to produce a single travel risk briefing. Every run delivers structured, machine-readable output that integrates directly into travel approval workflows, HR systems, or risk dashboards.

### What data can you extract?

| Data Point | Source | Example |
|---|---|---|
| 🧭 Composite risk score | 4 scoring models | `62` (scale 0–100) |
| 🚨 Travel advisory | Risk thresholds | `RECONSIDER_TRAVEL` |
| ⛈ Active weather alerts | NOAA NWS | `"3 severe thunderstorm warnings active"` |
| 🌋 Disaster alerts | GDACS | `"1 orange-level earthquake alert"` |
| 🏥 Health risk score | WHO GHO | `55` (HIGH) |
| 🔒 Security risk score | Crime + Interpol | `48` (ELEVATED) |
| 🌡 Destination hazard score | NOAA + GDACS combined | `22` |
| 💉 WHO health signals | WHO GHO indicators | `"Malaria risk present"` |
| 🚔 Crime record count | UK Police data | `18` recent crime records |
| 🔴 Interpol red notices | Interpol API | `3` notices linked to region |
| 📍 Coordinates | Nominatim geocoder | `{ "lat": -1.2921, "lon": 36.8219 }` |
| 📋 Actionable recommendations | Scoring engine | `"Register with embassy, avoid high-crime areas"` |

### Why use Travel Risk Report?

Building a travel risk briefing by hand means manually consulting government advisory pages, checking NOAA and GDACS feeds, reviewing WHO country health profiles, and cross-referencing crime statistics — easily two hours of research per destination, with no standardized output. At the scale corporate travel teams operate (dozens of trips per month, many destinations), manual research is not viable.

This actor automates the entire multi-source aggregation process, scoring each risk dimension against calibrated models and delivering a decision-ready advisory in a single API call.

- **Scheduling** — run on a recurring schedule to monitor high-risk destinations and receive fresh advisories before each travel window
- **API access** — trigger risk assessments from Python, JavaScript, or any HTTP client to integrate with your HR or travel approval system
- **Parallel data retrieval** — all 8 data sources are queried simultaneously via `Promise.allSettled`, so results return in roughly the same time as the slowest single source
- **Monitoring** — configure Slack or email alerts to notify your security team when an advisory level changes or a new EMERGENCY alert fires
- **Integrations** — connect to Zapier, Make, Google Sheets, or webhooks to push risk scores into travel management platforms

### Features

- **8 data sources queried in parallel** — Nominatim geocoder, NOAA weather alerts, OpenWeather forecast, GDACS disaster alerts, WHO GHO indicators, UK Police crime data, Interpol red notices, and REST Countries profiles all run concurrently via `Promise.allSettled` with graceful failure handling
- **4 independent scoring models** — Destination Risk, Active Alerts, Health Risk, and Security Risk each run separate calibrated algorithms before being averaged into a composite score
- **Composite score (0–100)** — equal 25% weighting across all four dimensions gives a balanced risk picture that no single data source can dominate
- **Formal advisory levels** — SAFE, EXERCISE_CAUTION, RECONSIDER_TRAVEL, and DO_NOT_TRAVEL — mirrors the language used by government travel advisory systems
- **Severity-weighted alert scoring** — NOAA extreme alerts score 15 points vs. 5 for moderate; GDACS red alerts score 25 points vs. 5 for green, preventing minor alerts from inflating scores
- **WHO health indicator analysis** — evaluates 7 health dimensions: life expectancy, mortality rates, malaria risk, tuberculosis incidence, HIV prevalence, sanitation coverage, and safe drinking water access
- **Life expectancy threshold at 60 years** — triggers a critical health flag; below 70 years triggers a moderate flag, with each scaled separately in the health risk model
- **Gini coefficient proxy for healthcare access** — countries with Gini above 45 receive an additional inequality penalty reflecting uneven healthcare distribution
- **No-data penalty for WHO data** — destinations with no WHO health records receive a 15-point unknown-risk penalty rather than a falsely optimistic zero score
- **Geopolitical region scoring** — Middle East, Central/Eastern Africa, and South/Southeast Asia carry calibrated regional risk premiums derived from the REST Countries `subregion` field
- **Many-borders instability signal** — countries with 6 or more land borders trigger an additional security flag as a proxy for regional instability
- **Actionable recommendations generated automatically** — each output includes 2–5 specific recommendations triggered by the actual risk signals found, not generic advice
- **Raw data included** — up to 15 weather alerts, 10 disaster alerts, 14 forecast records, 20 WHO indicators, 20 crime records, 10 Interpol notices, and 3 country profiles are included in the output for audit and downstream processing

### Use cases for travel risk assessment

#### Corporate travel management and duty of care

HR and travel teams at mid-to-large organizations must document risk assessments for every international trip to satisfy duty-of-care obligations. This actor produces a structured, timestamped report per destination that can be attached to travel approval records or stored in a travel management system. Run it as part of your approval workflow: score below 25 auto-approves, above 50 triggers a security review.

#### Executive protection and pre-advance briefings

Protection teams preparing advance work for C-suite travel need a rapid, quantified baseline before conducting their own ground assessments. This actor delivers crime density (from UK Police data), Interpol activity in the region, geopolitical stability signals, and real-time disaster alerts in one call — typically replacing 60–90 minutes of manual research per destination.

#### Insurance underwriting and premium setting

Travel insurance underwriters assessing policy risk for specific destinations can use the composite score and sub-scores as a structured input to pricing models. The health risk sub-score captures disease burden directly from WHO data. The security sub-score captures crime and criminal-network exposure via Interpol notices. Both feed cleanly into actuarial spreadsheets.

#### Tour operator and travel agency risk monitoring

Tour operators running routes to emerging destinations need to monitor evolving conditions — a region that was EXERCISE_CAUTION six months ago may now warrant RECONSIDER_TRAVEL due to new GDACS disaster alerts or deteriorating crime statistics. Schedule this actor weekly per active destination to detect advisory-level changes before they affect customers on the ground.

#### NGO and humanitarian field deployment planning

Operations teams deploying staff to conflict or disaster-affected regions need a rapid safety baseline before making deployment decisions. The health sub-score flags sanitation and disease risks relevant to field workers. The security sub-score uses Interpol activity and crime data. The active alerts dimension captures real-time disasters directly from GDACS.

#### Travel app development and risk data enrichment

Developers building travel applications, corporate booking tools, or risk dashboards can call this actor via the Apify API to enrich destination data with structured risk scores. The output is fully machine-readable and includes both summary scores and raw data arrays for any further processing layer.

### How to run a travel risk assessment

1. **Enter your destination** — Type a city, country, or region into the Destination field. Examples: "Lagos", "Pakistan", "Southeast Asia". Specific city names give more precise geocoding and better location-based crime data.
2. **Add travel dates (optional)** — Enter a date range like "2026-06-01 to 2026-06-14". This is recorded in the output for reference but does not filter the data — run the actor close to your departure date for the most current alert data.
3. **Add traveler nationality (optional)** — Enter a country name or ISO code like "US" or "United Kingdom". This is stored in the output for context and helps downstream tools apply visa or entry-requirement logic.
4. **Click Start and wait** — The actor queries all 8 sources in parallel. Most runs complete in 60–120 seconds. Results appear in the Dataset tab as a single JSON record with your composite score, advisory level, and full sub-scores.

### Input parameters

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `destination` | string | Yes | — | City, country, or region to assess (e.g., `"Nairobi"`, `"Colombia"`, `"Southeast Asia"`) |
| `travelDates` | string | No | null | Travel dates or date range (e.g., `"2026-04-15 to 2026-04-25"`) — stored in output for reference |
| `travelerNationality` | string | No | null | Traveler nationality or passport country (e.g., `"US"`, `"United Kingdom"`) — stored for downstream processing |

#### Input examples

**Standard corporate travel assessment:**
```json
{
  "destination": "Lagos",
  "travelDates": "2026-06-10 to 2026-06-17",
  "travelerNationality": "US"
}
````

**Quick destination screen (no travel context):**

```json
{
  "destination": "Karachi"
}
```

**Regional risk sweep:**

```json
{
  "destination": "Central America",
  "travelDates": "2026-09-01 to 2026-09-30",
  "travelerNationality": "UK"
}
```

#### Input tips

- **Use city names for best precision** — city-level queries return more targeted crime data and geocoding; country names work well for health and geopolitical scores
- **Run close to departure** — NOAA and GDACS data reflects conditions at run time; a run from two weeks before travel will not capture alerts that emerge later
- **Batch multiple destinations separately** — run one destination per actor call; the output structure is one report per run, making it easy to compare destinations side by side

### Output example

```json
{
  "destination": "Lagos",
  "coordinates": { "lat": 6.5244, "lon": 3.3792 },
  "travelDates": "2026-06-10 to 2026-06-17",
  "travelerNationality": "US",
  "generatedAt": "2026-03-20T09:14:33.000Z",
  "compositeScore": 61,
  "advisory": "RECONSIDER_TRAVEL",
  "recommendations": [
    "Register with embassy, avoid high-crime areas, maintain situational awareness",
    "Consult travel medicine clinic, ensure vaccinations up to date",
    "Carry medical kit, verify hospital locations, consider medical evacuation insurance",
    "Purchase travel insurance with natural disaster coverage"
  ],
  "allSignals": [
    "22 crime records — high crime density",
    "4 Interpol red notices linked to region",
    "Significant health risks: low life expectancy or high disease burden",
    "Malaria risk present",
    "High tuberculosis rates",
    "High inequality (Gini: 51) — uneven healthcare access",
    "1 GDACS disaster alerts active"
  ],
  "destinationRisk": {
    "score": 64,
    "hazardScore": 5,
    "healthScore": 22,
    "securityScore": 30,
    "riskLevel": "HIGH",
    "signals": [
      "22 crime records — high crime density",
      "4 Interpol red notices linked to region"
    ]
  },
  "activeAlerts": {
    "score": 25,
    "weatherAlerts": 1,
    "disasterAlerts": 1,
    "totalAlerts": 2,
    "alertLevel": "ADVISORY",
    "signals": [
      "1 NOAA weather alert(s) active",
      "1 GDACS disaster alert(s) active"
    ]
  },
  "healthRisk": {
    "score": 68,
    "indicators": 14,
    "criticalFlags": 11,
    "riskLevel": "HIGH",
    "signals": [
      "Malaria risk present",
      "High tuberculosis rates",
      "High inequality (Gini: 51) — uneven healthcare access"
    ]
  },
  "securityRisk": {
    "score": 66,
    "crimeRecords": 22,
    "interpolNotices": 4,
    "riskLevel": "HIGH",
    "signals": [
      "22 crime records — high crime density",
      "4 Interpol red notices — significant security concern"
    ]
  },
  "rawData": {
    "weatherAlerts": [ { "event": "Heat Advisory", "severity": "Moderate", "area": "Lagos Metro" } ],
    "disasterAlerts": [ { "alertlevel": "green", "eventtype": "FL", "country": "Nigeria" } ],
    "weatherForecast": [ { "date": "2026-03-20", "temperature": 34, "windSpeed": 18 } ],
    "whoIndicators": [ { "indicator": "WHOSIS_000001", "value": "53.2" } ],
    "crimeRecords": [ { "category": "violent-crime", "location": { "street": "Lagos Island" } } ],
    "interpolNotices": [ { "forename": "J.", "name": "ADELEKE", "nationality": "NGA" } ],
    "countryProfile": [ { "name": { "common": "Nigeria" }, "region": "Africa", "subregion": "Western Africa", "borders": ["BEN","NER","CMR","TCD"] } ]
  }
}
```

### Output fields

| Field | Type | Description |
|---|---|---|
| `destination` | string | The destination string passed as input |
| `coordinates.lat` | number | Latitude from Nominatim geocoding |
| `coordinates.lon` | number | Longitude from Nominatim geocoding |
| `travelDates` | string or null | Travel dates as entered, or null if not provided |
| `travelerNationality` | string or null | Traveler nationality as entered, or null |
| `generatedAt` | string | ISO 8601 timestamp of report generation |
| `compositeScore` | number | Composite risk score 0–100 (equal 25% weight across 4 models) |
| `advisory` | string | SAFE, EXERCISE\_CAUTION, RECONSIDER\_TRAVEL, or DO\_NOT\_TRAVEL |
| `recommendations` | string\[] | 2–5 actionable recommendations triggered by specific risk signals |
| `allSignals` | string\[] | Merged signal strings from all 4 scoring models |
| `destinationRisk.score` | number | Holistic destination risk score 0–100 |
| `destinationRisk.hazardScore` | number | Natural hazard sub-score (max 30) from NOAA + GDACS |
| `destinationRisk.healthScore` | number | Health sub-score (max 25) from WHO indicators |
| `destinationRisk.securityScore` | number | Security sub-score (max 30) from crime + Interpol |
| `destinationRisk.riskLevel` | string | LOW, MODERATE, ELEVATED, HIGH, or EXTREME |
| `destinationRisk.signals` | string\[] | Risk signals detected by destination risk model |
| `activeAlerts.score` | number | Real-time alert severity score 0–100 |
| `activeAlerts.weatherAlerts` | number | Count of active NOAA weather alerts |
| `activeAlerts.disasterAlerts` | number | Count of active GDACS disaster alerts |
| `activeAlerts.totalAlerts` | number | Total active alert count |
| `activeAlerts.alertLevel` | string | NONE, ADVISORY, WATCH, WARNING, or EMERGENCY |
| `activeAlerts.signals` | string\[] | Alert signal descriptions |
| `healthRisk.score` | number | WHO-derived health risk score 0–100 |
| `healthRisk.indicators` | number | Number of WHO health indicators analyzed |
| `healthRisk.criticalFlags` | number | Count of critical health flag triggers |
| `healthRisk.riskLevel` | string | LOW, MODERATE, ELEVATED, HIGH, or CRITICAL |
| `healthRisk.signals` | string\[] | Health risk signals (malaria, TB, sanitation, etc.) |
| `securityRisk.score` | number | Crime and geopolitical security score 0–100 |
| `securityRisk.crimeRecords` | number | Number of crime records retrieved |
| `securityRisk.interpolNotices` | number | Number of Interpol red notices for the region |
| `securityRisk.riskLevel` | string | LOW, MODERATE, ELEVATED, HIGH, or EXTREME |
| `securityRisk.signals` | string\[] | Security risk signals |
| `rawData.weatherAlerts` | array | Up to 15 raw NOAA weather alert records |
| `rawData.disasterAlerts` | array | Up to 10 raw GDACS disaster alert records |
| `rawData.weatherForecast` | array | Up to 14 raw weather forecast records |
| `rawData.whoIndicators` | array | Up to 20 raw WHO health indicator records |
| `rawData.crimeRecords` | array | Up to 20 raw crime records |
| `rawData.interpolNotices` | array | Up to 10 raw Interpol red notice records |
| `rawData.countryProfile` | array | Up to 3 raw REST Countries records |

### How much does it cost to run a travel risk assessment?

Travel Risk Report uses **pay-per-run pricing** — you pay approximately **$0.25–$0.60 per destination assessment** depending on alert data volume. Platform compute costs are included.

| Scenario | Destinations | Cost per run | Total cost |
|---|---|---|---|
| Quick test | 1 | $0.30 | $0.30 |
| Weekly monitoring (5 destinations) | 5 | $0.35 avg | ~$1.75 |
| Monthly travel program (20 destinations) | 20 | $0.35 avg | ~$7.00 |
| Quarterly review (100 destinations) | 100 | $0.35 avg | ~$35.00 |
| Enterprise fleet (500 destinations/month) | 500 | $0.35 avg | ~$175.00 |

You can set a **maximum spending limit** per run to control costs. The actor stops when your budget is reached.

Compare this to enterprise travel risk platforms like International SOS or WorldAware, which typically charge $5,000–$25,000+ per year in subscription fees. For teams running under 500 assessments per month, Travel Risk Report delivers comparable structured data at a fraction of the cost with no annual commitment.

### Travel risk assessment using the API

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("ryanclinton/travel-risk-report").call(run_input={
    "destination": "Lagos",
    "travelDates": "2026-06-10 to 2026-06-17",
    "travelerNationality": "US"
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"Destination: {item['destination']}")
    print(f"Advisory: {item['advisory']}")
    print(f"Composite score: {item['compositeScore']}/100")
    print(f"Health risk: {item['healthRisk']['riskLevel']} ({item['healthRisk']['score']}/100)")
    print(f"Security risk: {item['securityRisk']['riskLevel']} ({item['securityRisk']['score']}/100)")
    print(f"Recommendations: {'; '.join(item['recommendations'])}")
```

#### JavaScript

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

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("ryanclinton/travel-risk-report").call({
    destination: "Lagos",
    travelDates: "2026-06-10 to 2026-06-17",
    travelerNationality: "US"
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
    console.log(`${item.destination}: ${item.advisory} (score: ${item.compositeScore}/100)`);
    console.log(`Active alerts: ${item.activeAlerts.totalAlerts} (${item.activeAlerts.alertLevel})`);
    console.log(`Signals: ${item.allSignals.join(" | ")}`);
}
```

#### cURL

```bash
## Start the actor run
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~travel-risk-report/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"destination": "Lagos", "travelDates": "2026-06-10 to 2026-06-17", "travelerNationality": "US"}'

## Fetch results (replace DATASET_ID from the run response)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"
```

### How Travel Risk Report works

#### Phase 1: Parallel data retrieval from 8 sources

The actor dispatches 8 sub-actor calls simultaneously using `Promise.allSettled`, which means all sources are queried in parallel and no single slow source blocks the others. Failed sub-actor calls are caught gracefully — the corresponding data array is set to empty, and the scoring models treat absent data as either zero contribution or, in the case of WHO data, apply a 15-point unknown-risk penalty. The 8 sources are: Nominatim geocoder (for coordinates), NOAA NWS (weather alerts), OpenWeather (7-day forecast), GDACS (global disaster alerts), WHO Global Health Observatory (health indicators), UK Police API (crime records), Interpol (red notices), and REST Countries (country metadata and geopolitical profiles).

#### Phase 2: Four independent scoring models

Four scoring functions run against the collected data in sequence:

**Destination Risk model** combines natural hazard scoring (max 30 points: NOAA extreme alerts score 5 pts each, GDACS red/orange alerts score 5 pts each), health scoring (max 25 points from WHO life expectancy thresholds and disease indicators), security scoring (max 30 points from crime density, Interpol activity, and subregion classification), and weather severity (max 15 points for temperatures above 45°C or below −20°C, and wind speeds above 60 km/h). The four sub-scores sum to a max of 100.

**Active Alerts model** isolates real-time emergency signals. NOAA alerts are weighted by severity (extreme: 15 pts per alert, severe: 10 pts, moderate: 5 pts, capped at 50). GDACS alerts are weighted by level (red: 25 pts, orange: 15 pts, green: 5 pts, capped at 50). An EMERGENCY alert level from this model alone can trigger a DO\_NOT\_TRAVEL advisory regardless of other scores.

**Health Risk model** evaluates WHO GHO indicator strings and values against 7 named health dimensions. Life expectancy below 60 years adds 5 critical flags; below 70 years adds 2. Disease indicators (malaria, tuberculosis, HIV) add 2 flags each. Sanitation and drinking water coverage below 50% each add 3 flags. The Gini coefficient from REST Countries adds an inequality penalty up to 20 points. WHO data absence incurs a 15-point unknown-risk penalty.

**Security Risk model** scores crime record volume (max 40 points at 2 pts per record), Interpol red notice count (max 30 points at 5 pts per notice), and regional geopolitical factors (max 30 points based on subregion strings: Middle East +3, Central/Eastern Africa +4, Southern/Southeast Asia +2, country with 6+ borders +3).

#### Phase 3: Composite advisory generation

The four model scores are averaged with equal 25% weighting to produce a composite score. Advisory thresholds are: DO\_NOT\_TRAVEL (75+, or EMERGENCY active alert), RECONSIDER\_TRAVEL (50–74, or EXTREME security risk level), EXERCISE\_CAUTION (25–49), SAFE (0–24). Recommendation strings are generated conditionally — only recommendations relevant to the specific risk signals found are included in the output.

#### Phase 4: Output assembly

The actor assembles coordinates from the Nominatim geocoder result, merges all signal strings from the four models into `allSignals`, includes the raw data arrays (truncated for output size), and pushes the complete report as a single dataset record. Run time is typically 60–120 seconds, limited by the slowest of the 8 parallel sub-actor calls.

### Tips for best results

1. **Use specific city names over country names for security data.** Crime records and geocoding are most precise at city level. "Nairobi" returns more targeted crime data than "Kenya".

2. **Run the actor within 48 hours of departure for time-sensitive trips.** NOAA weather alerts and GDACS disaster data are real-time. A run from last week will not reflect alerts that have been issued since.

3. **Cross-reference the DO\_NOT\_TRAVEL advisory with official government sources.** This actor's advisory mirrors government language but is not a government source. For legal duty-of-care purposes, always document official advisories (US State Department, UK FCDO, DFAT) alongside this report.

4. **Use the `rawData` arrays for detailed audit trails.** Each `rawData` field contains the underlying records that drove the scores. If a score seems unexpectedly high or low, inspect the raw WHO indicator values or crime category breakdowns in those arrays.

5. **Schedule monitoring runs for active destinations.** Use Apify's built-in scheduler to run weekly assessments for any destination where you have personnel deployed. Configure a webhook to notify your security team if `advisory` changes from the previous run.

6. **Combine with company-level research for full pre-travel briefings.** The travel risk assessment covers destination-level conditions. Pair it with [Company Deep Research](https://apify.com/ryanclinton/company-deep-research) for country-specific business environment intelligence if the trip involves high-value negotiations or sensitive business activities.

7. **For destinations with zero WHO data, treat health scores conservatively.** The 15-point unknown-risk penalty is intentional — absence of WHO data typically reflects poor health data infrastructure in the destination country, which is itself a health risk signal.

### Combine with other Apify actors

| Actor | How to combine |
|---|---|
| [Company Deep Research](https://apify.com/ryanclinton/company-deep-research) | After scoring destination risk, run a deep research report on the local operating environment for business travel context |
| [Location Risk Report](https://apify.com/ryanclinton/location-risk-report) | Drill into a specific facility address within a destination city for site-level risk beyond the city composite score |
| [AML Entity Screening](https://apify.com/ryanclinton/aml-entity-screening) | Screen local business partners or counterparties in high-risk destinations before meetings |
| [Website Content to Markdown](https://apify.com/ryanclinton/website-content-to-markdown) | Convert government travel advisory pages into clean markdown for LLM summarization alongside this actor's structured scores |
| [NOAA Weather Alerts](https://apify.com/ryanclinton/noaa-weather-alerts) | Run the NOAA actor directly for real-time weather monitoring of a destination between full travel risk report runs |
| [Sanctions Network Analysis](https://apify.com/ryanclinton/sanctions-network-analysis) | For high-risk destinations, screen attendees or hosts against sanctions lists before confirming travel |
| [B2B Lead Qualifier](https://apify.com/ryanclinton/b2b-lead-qualifier) | For sales travel, qualify in-country prospects before deciding whether a destination visit is commercially viable |

### Limitations

- **Health data reflects population-level WHO statistics, not traveler-specific risks.** Individual vaccination status, pre-existing conditions, and travel medicine needs require consultation with a doctor, not this actor.
- **Crime data uses UK Police API records** as a proxy for crime density. This source is most accurate for UK destinations; for non-UK cities, it provides a signal but not a precise local crime rate.
- **Interpol red notices do not indicate country-specific criminal activity.** The notices are searched by country query and represent international fugitive notices, not a measure of local criminal network density.
- **No JavaScript-rendered data sources.** All 8 sub-actors use HTTP-based API calls. Live government advisory pages that require browser rendering are not scraped.
- **Regional queries (e.g., "Southeast Asia") produce broader, less precise scores** than city-level queries. Geocoding for regions is approximate and crime data may not return meaningful results.
- **GDACS and NOAA data reflects conditions at run time.** The actor does not forecast future risk — it reports current conditions. For trips weeks in the future, re-run the actor closer to departure.
- **The scoring models are calibrated for relative comparison, not absolute certainty.** A score of 35 versus 38 is not a meaningful difference. Use advisory levels (SAFE / EXERCISE\_CAUTION / etc.) as the primary decision signal.
- **No real-time conflict monitoring.** The actor does not query armed conflict databases (ACLED, UCDP) or monitor active geopolitical events beyond what GDACS covers. For conflict zones, consult specialist security providers.
- **Sub-actor failures are handled gracefully but silently.** If one of the 8 data sources fails to return data, its score contribution is zeroed (or the no-data penalty applied). Check `rawData` arrays in the output to verify which sources returned results.

### Integrations

- [Zapier](https://apify.com/integrations/zapier) — trigger a travel risk assessment automatically when a new trip is added to your travel management system and push the advisory level to a Slack channel
- [Make](https://apify.com/integrations/make) — build a multi-step approval workflow: run this actor, evaluate the composite score, and route the result to a security review queue or auto-approve low-risk trips
- [Google Sheets](https://apify.com/integrations/google-sheets) — export destination risk scores and advisory levels to a tracking spreadsheet for travel program reporting
- [Apify API](https://docs.apify.com/api/v2) — integrate travel risk scoring directly into booking tools, HR systems, or travel approval apps via REST API
- [Webhooks](https://docs.apify.com/platform/integrations/webhooks) — fire a webhook to your security team's incident management system when a run completes with a RECONSIDER\_TRAVEL or DO\_NOT\_TRAVEL advisory
- [LangChain / LlamaIndex](https://docs.apify.com/platform/integrations) — feed the structured risk report into an LLM pipeline to generate natural-language travel briefing narratives for executives

### Troubleshooting

**Composite score seems lower than expected for a known high-risk destination.** The scoring models weight 8 data sources that may not all return data for every destination. Check the `rawData` arrays: if `whoIndicators`, `crimeRecords`, or `interpolNotices` are empty, those dimensions contributed zero points or the unknown-risk penalty rather than real data. For regions with poor WHO data coverage, the health score may understate actual risk — treat the unknown-risk penalty (visible as a 15-point health score floor) as confirmation of limited data, not low risk.

**Run takes longer than 120 seconds.** The actor's timeout per sub-actor call is 120 seconds. If one of the 8 data sources is slow or unavailable, the entire run waits for that timeout before completing gracefully. On average, runs complete in 60–90 seconds. Runs approaching 120 seconds typically indicate a slow external API rather than an actor issue.

**`advisory` shows EXERCISE\_CAUTION for a destination you believe is SAFE.** The geopolitical region scoring in the Security Risk model applies region-level premiums to broad areas like "Middle East", "Central Africa", and "South/Southeast Asia". A city in one of these macro-regions will carry a baseline security premium even if local conditions are calm. Review `securityRisk.signals` to identify which flags fired, and cross-reference with official government advisory pages.

**Empty `crimeRecords` array for a non-UK destination.** The UK Police API is a UK-centric data source used as a proxy signal. For destinations outside the UK, this array will commonly be empty and contributes zero to the security score — the Interpol and geopolitical components carry the security dimension instead.

**`coordinates` field shows `{ "lat": 0, "lon": 0 }`.** The Nominatim geocoder did not return a result for your destination query. Try rephrasing with a more specific city or country name. This does not affect scoring — coordinates are metadata only and are not used in the risk calculation.

### Responsible use

- This actor queries publicly available data from NOAA, GDACS, WHO, Interpol, UK Police, REST Countries, and OpenWeather APIs.
- Travel risk scores are decision-support tools, not authoritative government advisories. Always cross-reference with official sources before making travel decisions that affect the safety of others.
- Do not use this actor to discriminate against individuals based on their nationality or country of origin.
- Comply with applicable data protection regulations when storing or sharing generated risk reports that may include personal travel information.
- For guidance on web scraping and API data legality, see [Apify's guide](https://blog.apify.com/is-web-scraping-legal/).

### FAQ

**How accurate is the travel risk score for my destination?**
The composite score is as accurate as the underlying data sources allow. For well-covered destinations (major cities, countries with full WHO data), all 4 scoring models contribute data and the score is reliable for relative risk comparison. For remote or data-sparse destinations, check the `rawData` arrays — empty arrays indicate data gaps, and the no-data penalty for WHO data will be visible as a 15-point health score floor.

**What triggers a DO\_NOT\_TRAVEL advisory?**
A composite score of 75 or above, or an EMERGENCY active alert level from NOAA/GDACS, triggers DO\_NOT\_TRAVEL regardless of the other scores. Reaching 75 composite requires high scores across multiple dimensions — typically active disaster alerts combined with elevated crime exposure and critical health risks.

**How current is the travel risk data?**
NOAA weather alerts and GDACS disaster data are real-time at run time. WHO health indicator data is updated annually. Crime data reflects recent UK Police records. Interpol notices are current at query time. For the most current assessment, run the actor within 48 hours of travel.

**Does this travel risk report replace official government travel advisories?**
No. This actor provides data-driven risk quantification from 8 open data sources. It does not replace official advisories from the US State Department, UK FCDO, Australian DFAT, or equivalent bodies. For duty-of-care documentation, record both this actor's output and the relevant official advisory.

**Can I assess travel risk for a region instead of a specific city?**
Yes. Enter a region like "Southeast Asia", "West Africa", or "Central America". The actor queries all sources using that text. Scores will be less precise than city-level assessments because geocoding and crime data are optimized for specific place names, but health and geopolitical scores will still reflect the broad region.

**How long does a typical travel risk assessment run take?**
Most runs complete in 60–90 seconds. The actor queries all 8 sources in parallel, so total run time is approximately equal to the slowest single source call. Allow up to 120 seconds for destinations where one or more data sources is slow to respond.

**What health indicators does the WHO scoring cover?**
The health model evaluates 7 indicator dimensions: life expectancy (critical flag below 60 years), mortality rates, malaria risk, tuberculosis incidence per 100,000, HIV prevalence above 1%, sanitation infrastructure coverage below 50%, and safe drinking water access below 50%. The Gini coefficient from REST Countries adds an inequality proxy for uneven healthcare access.

**How is this different from commercial travel risk platforms?**
Enterprise travel risk platforms like International SOS or WorldAware cost $5,000–$25,000+ per year and include human analyst support. This actor delivers comparable structured multi-source data at $0.25–$0.60 per assessment with no subscription commitment, making it suited for teams that need programmatic, API-accessible risk scoring rather than analyst-curated reports.

**Can I schedule this actor to monitor destinations automatically?**
Yes. Use Apify's built-in scheduler to run the actor on a daily or weekly schedule for each active destination. Configure a webhook to notify your security team when the advisory level changes or a new EMERGENCY alert fires.

**What happens if one of the 8 data sources fails during a run?**
The actor uses `Promise.allSettled`, which means individual sub-actor failures do not abort the run. A failed source contributes empty data to its scoring model — the score contribution from that model drops to zero (or applies the no-data penalty for WHO data). The run completes with whatever data was successfully retrieved. Check the `rawData` arrays to identify which sources returned results.

**Is it legal to use this data for travel risk decisions?**
All 8 data sources are publicly accessible APIs — NOAA, GDACS, WHO GHO, UK Police, Interpol public notices, REST Countries, OpenWeather, and Nominatim. Using public data for internal risk assessment is legal in all major jurisdictions. Sharing reports containing personal travel information is subject to GDPR and applicable data protection laws.

**Can I use the travel risk score in an automated travel approval system?**
Yes, and this is a primary design intent. Call the actor via the Apify API, evaluate `advisory` and `compositeScore` in your approval logic, and route results to your approval workflow. Recommended thresholds: SAFE auto-approves, EXERCISE\_CAUTION triggers a manager sign-off, RECONSIDER\_TRAVEL or DO\_NOT\_TRAVEL triggers a security team review.

### Help us improve

If you encounter issues, you can help us debug faster by enabling run sharing in your Apify account:

1. Go to [Account Settings > Privacy](https://console.apify.com/account/privacy)
2. Enable **Share runs with public Actor creators**

This lets us see your run details when something goes wrong, so we can fix issues faster. Your data is only visible to the actor developer, not publicly.

### Support

Found a bug or have a feature request? Open an issue in the [Issues tab](https://console.apify.com/actors/travel-risk-report/issues) on this actor's page. For custom solutions or enterprise integrations, reach out through the Apify platform.

# Actor input Schema

## `destination` (type: `string`):

City, country, or region to assess (e.g., 'Nairobi', 'Colombia', 'Southeast Asia').

## `travelDates` (type: `string`):

Optional travel dates or date range (e.g., '2026-04-15 to 2026-04-25').

## `travelerNationality` (type: `string`):

Optional traveler nationality or passport country for visa/entry context.

## Actor input object example

```json
{
  "destination": "Tokyo"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "destination": "Tokyo"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/travel-risk-report").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 = { "destination": "Tokyo" }

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/travel-risk-report").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 '{
  "destination": "Tokyo"
}' |
apify call ryanclinton/travel-risk-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/travel-risk-report",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Travel Risk Report — Weather, Health, Crime & Disaster Advisory",
        "description": "Comprehensive travel risk assessment tool that queries 8 data sources in parallel — geocoding, NOAA weather alerts, weather forecasts, GDACS disaster alerts, WHO Global Health Observatory indicators, UK police crime data, Interpol red notices, and REST Countries profiles — to produce a composite...",
        "version": "1.0",
        "x-build-id": "0HydM66HyvFch1XXK"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ryanclinton~travel-risk-report/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ryanclinton-travel-risk-report",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/ryanclinton~travel-risk-report/runs": {
            "post": {
                "operationId": "runs-sync-ryanclinton-travel-risk-report",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/ryanclinton~travel-risk-report/run-sync": {
            "post": {
                "operationId": "run-sync-ryanclinton-travel-risk-report",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "destination"
                ],
                "properties": {
                    "destination": {
                        "title": "Destination",
                        "type": "string",
                        "description": "City, country, or region to assess (e.g., 'Nairobi', 'Colombia', 'Southeast Asia').",
                        "default": "Tokyo"
                    },
                    "travelDates": {
                        "title": "Travel Dates",
                        "type": "string",
                        "description": "Optional travel dates or date range (e.g., '2026-04-15 to 2026-04-25')."
                    },
                    "travelerNationality": {
                        "title": "Traveler Nationality",
                        "type": "string",
                        "description": "Optional traveler nationality or passport country for visa/entry context."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
