# FCDO Travel Advice Monitor - Country Guidance Changes (`maydit/fcdo-travel-advice-monitor`) Actor

Monitor official FCDO country guidance, exact warning codes and section changes. Export source text, hashes and saved comparisons for country watchlists. No API key.

- **URL**: https://apify.com/maydit/fcdo-travel-advice-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** News, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 country advice observations

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![Country guidance, with source context — illustrative workflow](https://api.apify.com/v2/key-value-stores/YGxD9JRpduom8Q5Zd/records/fcdo-travel-advice-monitor-5dbb331b9030.png?signature=1DbkgGhvj0c4szQYJeyuo)

### Country guidance, with source context

Maintain a sourced travel-guidance watchlist for research or operational briefings. Each saved row contains one destination, exact FCDO warning codes and selected official guidance sections.

[Open this Actor in Console](https://console.apify.com/actors/U1Isjatjb2eigbULx/input) · [First run](#try-this-actor) · [Results](#result-preview) · [Cost](#usage-and-pricing) · [Full guide](#full-guide)

### Try this Actor

1. **Choose a small scope.** Use the existing **France Entry Requirements and Travel Warnings** example below: one destination, two named sections and at most one saved row.
2. **Run and review.** Open the dataset and check requested-section coverage. Review the run's key-value-store `SUMMARY` for failed destinations, partial coverage and saved-history status.
3. **Use the results.** Export JSON to retain section text, hashes and evidence. Follow the official guidance link when preparing a travel briefing.

**Read this before using the data:** FCDO guidance is directed at UK travellers. A warning about part of a destination is not a countrywide warning, and an empty warning-code array does not mean safe travel. Observation time is not the publisher's update time.

**France Entry Requirements and Travel Warnings** — copy this input into the JSON editor in Console.

```json
{
  "countries": [
    "france"
  ],
  "sections": [
    "entry-requirements",
    "warnings-and-insurance"
  ],
  "maxResults": 1
}
```

### Result preview

The dataset view highlights these columns:

- **Advice ID** · `adviceId`
- **Destination** · `country`
- **Destination slug** · `countrySlug`
- **Guidance title** · `title`
- **Published warning codes** · `alertStatuses`
- **Publisher material update** · `publicUpdatedAt`

Use the original source links and the field definitions below when interpreting the results. CSV works well for flat columns; JSON preserves nested values.

### Usage and pricing

Base result rate on the FREE tier: **$2 per 1,000 country advice observations**. The [Pricing tab](https://apify.com/maydit/fcdo-travel-advice-monitor/pricing) shows your plan's result rate and any Actor Start charge. Set a small result limit for the first run; the requested limit is not a guarantee of that many results.

***

### Full guide

Build a country watchlist from the official GOV.UK Content API. Each row contains one destination, the exact FCDO warning codes and selected guidance sections. Use the source links and section hashes to review changed entry requirements, travel disruption notices or regional warnings. This is a data monitor, not an assessment of whether a journey is safe.

#### Quick start

`{}` and Console prefill request France, Japan and Ukraine. Empty `countries` and `sections` also use these documented fallbacks. Destinations are processed in sorted slug order; `maxResults` limits saved countries, not requested pages. Unknown or failed destinations are listed in SUMMARY. Up to 100 explicitly listed destinations are supported; this Actor does not promise a complete world inventory.

#### Output and interpretation

FCDO guidance is directed at UK travellers. `alertStatuses` preserves published codes such as `avoid_all_travel_to_parts`; a warning about part of a destination is not a countrywide warning. An empty code array does not mean safe travel. `publicUpdatedAt` is the publisher’s material update time; `reviewedAt` can differ or be null. `changeDescription` is the publisher’s note, not an AI summary. Advice may be current even when its last material update is older.

`sections` includes text, source URL, full-source hash, source character count and a truncation flag. Missing selected sections are reported in `missingRequestedSections`. `sectionHashes` and `changedSections` identify content changes; snapshot comparison also covers exact warning codes and publisher update metadata. Formatting whitespace is normalized before hashing. Keyword matching uses complete selected section text and emits literal evidence, including matches beyond displayed truncation. The optional date filter uses the UTC day of `publicUpdatedAt`.

Overview fields: `adviceId`, `country`, `countrySlug`, `title`, `alertStatuses`, `publicUpdatedAt`, `changeDescription`, `url`, `sections`, `changedSections`, `comparisonStatus`, `observedAt`. Export JSON for nested evidence and section arrays. Every row has an observation time; it is not a source publication time.

#### Saved comparisons

Set `comparePrevious: true` to annotate matching rows as new, changed or unchanged. `onlyChanges: true` implies comparison and skips unchanged rows. A first run saves matching observations and logs a baseline warning. `SUMMARY.historyUpdated` confirms the final history write. No-op runs warn and may correctly return zero results.

History scope includes the sorted country list, selected sections, keywords, date filter and `snapshotName`. `maxResults` and display text length do not change the scope. Full source hashes detect edits even when returned text is shortened. `changedSections` is empty on the first observation and lists changed/added/removed selected section slugs on later comparisons.

Only confirmed saved rows advance the named persistent key-value-store history. Failed or charge-rejected writes do not advance it. Prior observations are retained on partial runs. One writer per history scope is required; a final read detects conflicting updates but this is not a transactional lock. Malformed history fails with an actionable error; choose a new `snapshotName`. History is capped at 20,000 identities. A result cap may leave unseen records for a later comparison run.

#### Coverage, failures and charging

No API key or login is required. Public-source requests use SSRF/DNS/redirect safeguards, robots checks and bounded compressed-body decoding. A request takes at most 25 seconds and remains within `maxRunSeconds` (default 240) and the platform deadline minus 25 seconds. Transient failures get at most two retries.

`SUMMARY` reports source coverage, failures, not-reached sources, saved rows, unchanged skips and time/spend limits. Errors and access challenges never become dataset rows. All-source failures fail the run; a successful source with an empty filter result warns. Source, history or budget failures make coverage incomplete. An intentional result/page limit is a bounded request. Do not interpret a partial or truncated observation as complete coverage.

Planned price: **$0.002 per saved record** on FREE/BRONZE, $0.0016 SILVER and $0.0012 GOLD/PLATINUM/DIAMOND, plus a $0.00005 Actor Start event. The Store pricing tab is authoritative. Unchanged skipped records and diagnostic errors do not create dataset charges. Normal platform usage may also apply according to the Store plan.

#### Three exact example inputs

##### France Entry Requirements and Travel Warnings

Export the official France entry requirements and warnings with source links and section hashes.

Use the [copyable first-run input](#try-this-actor) above.

##### Japan Safety and Regional Travel Guidance

Export Japan safety and regional guidance with exact publisher wording and update metadata.

```json
{
  "countries": [
    "japan"
  ],
  "sections": [
    "safety-and-security",
    "regional-risks"
  ],
  "maxResults": 1
}
```

##### Ukraine FCDO Warnings and Regional Guidance

Keep exact FCDO regional warning codes alongside Ukraine warnings and regional guidance.

```json
{
  "countries": [
    "ukraine"
  ],
  "sections": [
    "warnings-and-insurance",
    "regional-risks"
  ],
  "maxResults": 1
}
```

#### Sources and reuse

[GOV.UK Content API](https://content-api.publishing.service.gov.uk/) is documented for applications that reuse and keep government content current. This Actor reads only country advice JSON under `/api/content/foreign-travel-advice/`. [GOV.UK reuse guidance](https://www.gov.uk/help/reuse-govuk-content) and the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/) apply. Output carries attribution. Maps, logos and third-party files are not downloaded.

#### Development

Node 20+, exact apify 3.7.2 and cheerio 1.1.2; basic-ftp 6.2.2 override. Run `npm ci --ignore-scripts` then `npm test`. Use an isolated `CRAWLEE_STORAGE_DIR` for local runs. Local and cloud bounded checks establish sample behavior, not exhaustive coverage or customer demand.

### Help with your run

Open the **Issues** tab on this Actor with the run URL, the input field that caused trouble and what you expected to receive. Remove API keys and private information before posting.

[Explore more Mayd-It Actors](https://apify.com/maydit)

### Understand your run

Open **Run report** in the run’s Output tab for saved-record counts, reported source issues and limits, and suggested next steps. Use **CSV export** to take the saved results into a spreadsheet. The existing JSON results and detailed machine-readable summary remain available.

The report reflects this run’s recorded coverage. A successful run or a saved result does not establish that every possible source record was collected.

# Actor input Schema

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

Up to 100 GOV.UK destination slugs. Omitted or empty uses france, japan and ukraine. Case is normalized. Unknown destinations fail honestly; no fuzzy country guessing.

## `sections` (type: `array`):

Optional subset: warnings-and-insurance, entry-requirements, safety-and-security, regional-risks, health, getting-help. Omitted/empty returns all available supported sections. Missing requested sections are listed separately.

## `keywords` (type: `array`):

Optional case-insensitive ANY phrase match in title, publisher change note or complete selected section text. Matching excerpts identify the source section; a country name alone does not imply a risk.

## `updatedSince` (type: `string`):

Optional real YYYY-MM-DD UTC date. Filters public_updated_at, not the review date or run time.

## `maxSectionCharacters` (type: `integer`):

Return at most this many plain-text characters for each selected section. textTruncated flags shortened text. Hashes and keyword matching use the full source section.

## `maxResults` (type: `integer`):

Maximum unique matching rows saved across the whole run. Normal requested caps are bounded coverage, not source failures.

## `comparePrevious` (type: `boolean`):

Return matching rows with new, changed or unchanged comparison status. Uses a named persistent store. Only confirmed saved rows advance history. The first run establishes observations, and SUMMARY confirms whether history was committed.

## `onlyChanges` (type: `boolean`):

Implies comparison. Unchanged matching observations are skipped without a dataset charge. A first run saves matching observations; subsequent unchanged runs can correctly save zero. No disappearance/deletion inference.

## `snapshotName` (type: `string`):

Use 1-80 letters, digits, underscores or hyphens. History also includes the sorted sources/queries and content filters. Run only one writer at a time for each scope. Start a new name for an incompatible saved baseline.

## `maxRunSeconds` (type: `integer`):

Requests use this budget and the platform deadline minus 25 seconds. Each request is capped at 25 seconds. Partial coverage and spending stops are explicit in SUMMARY.

## Actor input object example

```json
{
  "countries": [
    "france",
    "japan",
    "ukraine"
  ],
  "maxSectionCharacters": 12000,
  "maxResults": 20,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "maxRunSeconds": 240
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runReport` (type: `string`):

Readable summary of saved records, reported source coverage, limits and next steps. Available when this run saves its SUMMARY.

## `csvExport` (type: `string`):

Download saved dataset records as a CSV file for spreadsheets and other tools.

## `summary` (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 = {
    "countries": [
        "france",
        "japan",
        "ukraine"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/fcdo-travel-advice-monitor").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": [
        "france",
        "japan",
        "ukraine",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("maydit/fcdo-travel-advice-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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": [
    "france",
    "japan",
    "ukraine"
  ]
}' |
apify call maydit/fcdo-travel-advice-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/fcdo-travel-advice-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/U1Isjatjb2eigbULx/builds/ce7yeiTFLMa5C7IgE/openapi.json
