# Airport Database API - IATA, ICAO, Flight Distance, METAR (`martin10291/airports-flight-distance`) Actor

Airport database and flight distance API in one actor. No API key, no login, no proxy: open data (OurAirports, aviationweather.gov). Look up airports by IATA or ICAO code, name or country, find airports near a point, get distance and flight time, plus live METAR/TAF.

- **URL**: https://apify.com/martin10291/airports-flight-distance.md
- **Developed by:** [Martin Petrov](https://apify.com/martin10291) (community)
- **Categories:** Travel, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 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.
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

## Airport Database API - IATA, ICAO, Flight Distance & METAR Weather

One actor for everything about airports: **look up any airport by IATA or ICAO code**, **search by name, country or type**, **find airports near a latitude/longitude**, get the **great-circle distance, bearing and estimated flight duration between airports** (`JFK-LHR`), and read the **latest METAR and TAF weather** for any station.

Built on open data (OurAirports, public domain) and the official NOAA Aviation Weather Center API. **No API key, no login, no scraping of websites.** Results come back in seconds, as clean JSON, CSV or Excel.

### Who needs it

- **Travel apps and flight comparison sites**: autocomplete airports, show distance and flight time on a route page, fill city and country from a code.
- **AI travel agents and chatbots**: call it from an agent (MCP) to answer "how far is Varna from London?" or "what is the weather at JFK?".
- **Logistics, aviation and charter teams**: runway length, surfaces, elevation, nearest airports to a site, bearing between two points.
- **Data teams**: a clean, regularly updated airport table with IATA, ICAO, coordinates, time zone and runways, ready for joins.

### Five modes

| Mode | What it does |
|---|---|
| `distance` | Routes like `JFK-LHR`: kilometers, miles, nautical miles, initial bearing, **estimated** flight time, time zone difference. |
| `lookup` | Airport details by IATA or ICAO code. |
| `search` | Find airports by text, country (`US`, `BG`) and type (`large_airport`, `medium_airport`...). |
| `nearby` | Airports around a point, sorted by distance (airports with scheduled service by default). |
| `weather` | Latest METAR (raw and decoded) and optional TAF forecast. |

### How to use it (step by step)

1. Click **Try for free**.
2. Pick **What to do**. The default (`distance` with three sample routes) works immediately.
3. Fill the matching field: **Routes** for distance, **Airport codes** for lookup and weather, **Search text / Country / Types** for search, **Latitude / Longitude / Radius** for nearby.
4. Click **Start** and download JSON, CSV or Excel, or call it by API.

### API example (copy and paste)

Replace `YOUR_APIFY_TOKEN` with your token from Apify Console, Settings, Integrations.

```bash
curl -s -X POST "https://api.apify.com/v2/acts/martin10291~airports-flight-distance/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"distance","routes":["JFK-LHR","SOF-VAR","LAX-NRT"]}'
```

Weather for three airports:

```bash
curl -s -X POST "https://api.apify.com/v2/acts/martin10291~airports-flight-distance/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"weather","codes":["KJFK","EGLL","LBWN"],"includeTaf":true}'
```

### Use it from AI agents (MCP)

Add this actor as a tool through the Apify MCP server (`https://mcp.apify.com`), for example in Claude Desktop, Cursor or any MCP client:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=martin10291/airports-flight-distance",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}
```

Then ask your agent: "Distance and flight time from Sofia to Varna?" or "Current METAR at Heathrow?".

### Input

| Field | Type | Description |
|---|---|---|
| `mode` | string | `distance`, `lookup`, `search`, `nearby` or `weather`. |
| `routes` | array | Distance mode: pairs like `JFK-LHR` (IATA or ICAO). |
| `codes` | array | Lookup and weather mode: IATA or ICAO codes. |
| `query` | string | Search mode: text in name, city, code or keywords. |
| `country` | string | Search mode: two-letter ISO country code. |
| `types` | array | Search and nearby: airport types to keep. |
| `latitude`, `longitude` | number | Nearby mode: center point. |
| `radiusKm` | integer | Nearby mode: radius in km. |
| `scheduledServiceOnly` | boolean | Nearby mode: only airports with scheduled flights (default on). |
| `includeTaf` | boolean | Weather mode: also return the TAF forecast. |
| `onlyNew` | boolean | Monitoring: only new or changed results. |
| `monitorId` | string | Separate memory per watch list. |
| `maxItems` | integer | Hard limit on results saved (and paid for). |

### Output examples

#### distance

```json
{
  "route": "JFK-LHR",
  "from": {"iata": "JFK", "icao": "KJFK", "name": "John F. Kennedy International Airport", "city": "New York", "countryCode": "US", "latitude": 40.639447, "longitude": -73.779317},
  "to": {"iata": "LHR", "icao": "EGLL", "name": "London Heathrow Airport", "city": "London", "countryCode": "GB", "latitude": 51.470748, "longitude": -0.459909},
  "greatCircleKm": 5539.8,
  "miles": 3442.3,
  "nauticalMiles": 2991.3,
  "initialBearingDeg": 51.4,
  "initialBearingCompass": "NE",
  "estimatedFlightMinutes": 430,
  "estimatedFlightTime": "7h 10m",
  "estimateAssumptions": "Estimate only: block time = distance / 830 km/h + 30 min taxi/climb/descent overhead. Not a schedule.",
  "fromTimezone": "America/New_York",
  "toTimezone": "Europe/London",
  "timezoneDifferenceHours": 5.0
}
```

#### lookup / search / nearby

```json
{
  "iata": "JFK", "icao": "KJFK", "name": "John F. Kennedy International Airport", "type": "large_airport",
  "city": "New York", "region": "New York", "countryCode": "US", "country": "United States", "continent": "NA",
  "latitude": 40.639447, "longitude": -73.779317, "elevationFt": 13,
  "timezone": "America/New_York", "utcOffsetHours": -5.0, "scheduledService": true,
  "runways": {"count": 4, "longestFt": 14511, "longestM": 4423, "surfaces": ["ASP", "PEM"]},
  "wikipedia": "https://en.wikipedia.org/wiki/John_F._Kennedy_International_Airport",
  "homeLink": "https://www.jfkairport.com/"
}
```

Nearby mode adds `distanceKm` and `bearingDeg` to every airport.

#### weather

```json
{
  "icao": "EGLL",
  "observedAt": "2026-11-01T21:50:00Z",
  "rawMetar": "METAR EGLL 012150Z AUTO 35004KT 310V030 9999 SCT027 09/06 Q1035",
  "windDirectionDeg": 350, "windSpeedKt": 4, "windGustKt": null,
  "visibilitySm": "6+", "temperatureC": 9, "dewpointC": 6,
  "altimeterHpa": 1035, "altimeterInHg": 30.56,
  "flightCategory": "VFR",
  "clouds": [{"cover": "SCT", "base": 2700}],
  "rawTaf": "TAF AMD EGLL 011733Z 0118/0224 ..."
}
```

### Monitoring and alerts

Turn on **Only new or changed results** and set a **Monitor ID**. In `weather` mode only METARs that changed since the last run are returned (and paid for), so a schedule every 30 minutes behaves like a weather alert feed. In the other modes only airports or routes not seen before for that Monitor ID are returned. Connect Slack, email, Google Sheets, Zapier, Make or a webhook in Apify Console.

### Pricing

Pay per result: **$1.00 per 1,000 results** (one result = one airport, one route or one weather report). The sample input costs a fraction of a cent. Use **Max results** to cap spending.

### Data sources and attribution

- Airports, runways, countries and regions: [OurAirports](https://ourairports.com/data/), public domain. Downloaded at run time and cached for 7 days.
- Weather: [NOAA Aviation Weather Center Data API](https://aviationweather.gov/data/api/), official US government data, no key. Requests are kept modest and sent with an honest User-Agent.
- Time zones are derived from airport coordinates with the open-source `timezonefinder` library.

### FAQ

**Is the flight duration exact?** No. It is an estimate: distance divided by a typical cruise speed of 830 km/h plus 30 minutes for taxi, climb and descent. Real flights vary with winds, routing, aircraft and airline schedules.

**Does it track live flights or give timetables and prices?** No. It does not provide live flight positions, schedules, delays or fares. It covers airport data, distances and weather.

**Which codes work?** 3-letter IATA codes (JFK) and 4-character ICAO codes (EGLL). For weather, any ICAO station code works, even if it is not in the airport table.

**How fresh is the airport data?** OurAirports is community maintained and updated frequently. The actor refreshes its cached copy every 7 days.

**Why is a code not found?** Many small airfields have no IATA code. Try the ICAO code, or use `search` mode. Missing codes are listed in the run summary and are not charged.

**What is in the run summary?** The `RUN_SUMMARY` record in the default key-value store lists counts, codes not found and `lastError`.

# Actor input Schema

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

distance = great-circle distance, bearing and estimated flight time for routes like JFK-LHR. lookup = full airport details by IATA/ICAO code. search = find airports by text, country or type. nearby = airports around a latitude/longitude. weather = latest METAR (and optional TAF) for airports.

## `routes` (type: `array`):

Airport pairs as IATA or ICAO codes, for example JFK-LHR, SOF-VAR, LAX-NRT. Accepted separators: dash, 'to', '>' or space.

## `codes` (type: `array`):

IATA (3 letters, e.g. JFK) or ICAO (4 characters, e.g. EGLL) codes. For weather mode, ICAO codes of any station also work.

## `query` (type: `string`):

Text to find in airport name, city, code or keywords, for example 'heathrow', 'varna' or 'international'. Can be combined with country and type filters.

## `country` (type: `string`):

Two-letter ISO country code, for example US, GB, BG, DE. Empty = all countries.

## `types` (type: `array`):

Filter by type: large_airport, medium_airport, small_airport, heliport, seaplane_base, balloonport, closed. Empty = all open airport types in search mode, and large/medium/small airports in nearby mode.

## `latitude` (type: `number`):

Latitude of the center point in decimal degrees, for example 43.2321 (Varna).

## `longitude` (type: `number`):

Longitude of the center point in decimal degrees, for example 27.8251 (Varna).

## `radiusKm` (type: `integer`):

Search radius around the point in kilometers.

## `scheduledServiceOnly` (type: `boolean`):

Keep only airports that have scheduled passenger flights. Turn off to also see small airfields.

## `includeTaf` (type: `boolean`):

Also return the latest TAF (terminal aerodrome forecast) for each station, raw text.

## `onlyNew` (type: `boolean`):

For monitoring: weather mode returns only METARs that changed since the last run, other modes return only airports or routes not seen before for this Monitor ID. Each result is paid for once.

## `monitorId` (type: `string`):

Separate memory for different watch lists (used with only-new mode).

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

Hard limit on results saved (and paid for).

## Actor input object example

```json
{
  "mode": "distance",
  "routes": [
    "JFK-LHR",
    "SOF-VAR",
    "LAX-NRT"
  ],
  "codes": [
    "JFK",
    "LHR",
    "SOF"
  ],
  "latitude": 43.2321,
  "longitude": 27.8251,
  "radiusKm": 150,
  "scheduledServiceOnly": true,
  "includeTaf": false,
  "onlyNew": false,
  "monitorId": "default",
  "maxItems": 100
}
```

# Actor output Schema

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

Airports, flight distances and live METAR/TAF weather, one row per result.

# 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 = {
    "mode": "distance",
    "routes": [
        "JFK-LHR",
        "SOF-VAR",
        "LAX-NRT"
    ],
    "codes": [
        "JFK",
        "LHR",
        "SOF"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("martin10291/airports-flight-distance").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 = {
    "mode": "distance",
    "routes": [
        "JFK-LHR",
        "SOF-VAR",
        "LAX-NRT",
    ],
    "codes": [
        "JFK",
        "LHR",
        "SOF",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("martin10291/airports-flight-distance").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 '{
  "mode": "distance",
  "routes": [
    "JFK-LHR",
    "SOF-VAR",
    "LAX-NRT"
  ],
  "codes": [
    "JFK",
    "LHR",
    "SOF"
  ]
}' |
apify call martin10291/airports-flight-distance --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,martin10291/airports-flight-distance"
        }
    }
}
```

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/4aSFgEHfRV1hAq49Z/builds/Gtg86e5rNaS8fXraG/openapi.json
