# NOAA METAR Observations - Latest per Station, Per Record (`nexgensignal/noaa-metar-observation-records`) Actor

NOAA/NWS METAR latest observation per station (Canada excluded) as clean per-record data - raw text, station, time, coordinates, temp, wind, visibility, pressure and flight category. Hourly refresh. Public domain. $0.05 per record.

- **URL**: https://apify.com/nexgensignal/noaa-metar-observation-records.md
- **Developed by:** [NexGen Signal](https://apify.com/nexgensignal) (community)
- **Categories:** Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $33.50 / 1,000 metar observation records

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?

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

## How to integrate an Actor?

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

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

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

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

# README

## NOAA METAR Observations - Latest per Station, Per Record

The latest **METAR** aviation-weather observation for every reporting station worldwide (Canada excluded) as
one clean, flat record - raw METAR text, station, time, coordinates, temperature, wind, visibility, pressure
and flight category. Refreshed hourly.

### What one record represents

The source is the **NOAA/NWS Aviation Weather Center** hourly METAR cache (`aviationweather.gov`). Each record
is **one station's latest observation**: the raw METAR text, the ICAO station id, the observation time,
coordinates and elevation, temperature and dewpoint, wind direction/speed/gust, visibility, altimeter and
sea-level pressure, the flight category (VFR/MVFR/IFR/LIFR) and the METAR/SPECI type.

### Coverage and volume

The cache holds the latest observation for **about 4,530 non-Canada stations** (live at build time: 4,953 total
minus 423 Canadian). Because the cache refreshes hourly and stations report intermittently, the exact count
fluctuates from hour to hour.

**Sol's Wave-4 index put this door at 4,498 non-Canada stations (4,937 - 439 Canada); measured live at build
time it is about 4,530 (4,953 - 423) - the count moves with the hourly cache, and the live figures are what this
listing quotes.**

The Actor downloads the hourly cache, drops the Canadian stations, and delivers a record per remaining station.

### Licence and attribution

The data is a U.S. Government work in the public domain. The full notice travels on every record:

> NOAA/NWS Aviation Weather Center. U.S. Government work in the public domain (17 U.S.C. 105) - no copyright; provided 'as is' with no warranty.

### Person-data policy

METAR observations carry **no personal data** - they are machine and station weather reports. A per-record
assertion rejects any contact/person field as a matter of form. No natural-person data is processed.

### The Canada ban

Every station whose ICAO id starts with **C** (Canada) is **structurally dropped** - the row is never emitted.
This is baked into the Actor, not a buyer option, and a planted-Canada test confirms no `C`-prefixed station
reaches the output. The run receipt records how many rows were dropped by the filter.

### Interpretation caveat

One record per station's latest METAR observation from the Aviation Weather Center hourly cache: raw METAR text, station, time, coordinates, temperature, dewpoint, wind, visibility, altimeter, sea-level pressure, flight category and elevation. Every station whose ICAO id starts with C (Canada) is structurally dropped. The cache refreshes hourly.

Values are reproduced verbatim from the cache; the Actor never rewrites a field. Numeric fields (temperature,
wind, pressure, coordinates, elevation) are real numbers; visibility is kept as the source's verbatim string
(e.g. "6+") because it is not always numeric. Each record is the latest observation for its station at fetch
time - a live snapshot, not a history.

### Provenance and compliance

Every run reads the door host's `robots.txt` at runtime; the gate result (URL, status, byte length and, where a
policy is served, its SHA-256) is written to the run's `RUN_RECEIPT`. Where the host serves no robots.txt, the
gate records that fact (flagged) and proceeds on the licence, which expressly grants re-use. The endpoint is
keyless. The Actor never bypasses a block or fetches through a mirror.

### Data quality and freshness

Boolean columns are delivered as real booleans and numeric columns as real numbers. Delivery is keyed on a
stable id, so the dataset is safe to diff, deduplicate or upsert. Every run re-reads the live door, so the data
is as fresh as the source publishes, and each record's `observed_at` stamp dates the snapshot. The run's
`RUN_RECEIPT` records the source URL and how many records were delivered and charged, and confirms
`charge_equals_delivered`.

### Billing and delivery

Pricing is per record: you are billed only for records the Actor actually delivers, with the charge raised
after each record is pushed (push-then-charge), so a failed or empty run costs nothing. The **Maximum records**
cap bounds every run, so you control spend precisely - sample cheaply, then raise it. Because delivery is keyed
on a stable id, re-running and upserting keeps a downstream table current without re-paying for rows you already
hold; only new and changed records add cost, and every receipt reconciles delivered against charged.

### Schema, typing and joins

Every record is a flat object with a fixed, typed schema: strings stay strings, numbers are parsed to real
numbers, and booleans to real booleans, so the data loads into a warehouse or a dataframe without a cleaning
pass. The `record_id` is a stable composite key, which means the dataset is safe to diff between runs, to
deduplicate, and to upsert into a table you maintain over time. Because the identifiers the source uses are
preserved verbatim, the dataset joins cleanly onto other sources keyed on the same identifier, and a scheduled
run keeps the downstream copy current with no manual reconciliation - the new and changed rows simply upsert
over the old ones, and the `observed_at` stamp on every record tells you when each was last seen live.

### Inputs

- **Maximum records** (`maxRecords`) - hard cap on observation records delivered and billed.

### Output

Records land in the Actor's default dataset and export as JSON, CSV, Excel or via the Apify API. A tabular
overview surfaces station, observation time, temperature, wind, visibility, flight category and latitude.

### Fields in detail

The record leads with `raw_text`, `station_id`, `observation_time`, `latitude`, `longitude`, then the weather
values (`temp_c`, `dewpoint_c`, `wind_dir_degrees`, `wind_speed_kt`, `wind_gust_kt`, `visibility_statute_mi`,
`altim_in_hg`, `sea_level_pressure_mb`), the `flight_category`, `metar_type` and `elevation_m`. The provenance
block closes every record.

### Typical uses

Aviation-operations and weather teams use this cell as a live global METAR snapshot - the latest conditions and
flight category at every reporting station - refreshed hourly, ready to drop into a dispatch board or a weather
screen. Because the flight category and winds are first-class fields, a filter surfaces every IFR station in a
region at a glance. For a history rather than a snapshot, the fleet's NOAA ISD archive cell is the companion;
for a per-call lookup, the fleet's Weather MCP is the tool.

### A live snapshot, not an archive

This cell delivers the **latest** observation per station, refreshed from the hourly cache - a live picture of
current conditions worldwide, not a time series. That is the right shape for a dispatch board or an operations
screen, where what matters is the conditions right now. For history - the same stations over days, months or
years - the fleet's NOAA ISD archive cell is the companion; for a single-station lookup on demand, the fleet's
Weather MCP is the tool. The three cover the same domain at three grains: live snapshot, historical archive,
and per-call tool.

### Why the Canada ban

The cell is scoped to exclude Canadian stations (every ICAO id beginning with C), by design and baked into the
Actor. The exclusion is structural - Canadian rows are dropped before delivery and never billed - and a
planted-Canada test confirms none slips through; the run receipt reports how many rows the filter removed. The
remaining coverage is global, spanning the roughly 4,500 non-Canada stations reporting at fetch time.

### Reading the observation

`flight_category` (VFR/MVFR/IFR/LIFR) is the quick read on whether a station is flyable, derived by the source
from ceiling and visibility; `wind_dir_degrees`/`wind_speed_kt`/`wind_gust_kt` give the wind; and `altim_in_hg`
and `sea_level_pressure_mb` the pressure. The `raw_text` field carries the full coded METAR for anyone who
wants to parse it further. Because the numeric fields are real numbers, a filter on flight category or wind
speed surfaces the stations that matter to an operation at a glance, and the station id joins to any airport
reference keyed on ICAO.

### Sibling Actors

It sits beside the fleet's NOAA ISD hourly-observation archive (history vs live snapshot) and the fleet's Weather MCP server (per-call tool vs bulk snapshot). It shares its CSV engineering with the fleet's other records Actors.

# Actor input Schema

## `maxRecords` (type: `integer`):

Maximum records delivered and billed. You are billed only for records actually delivered. Raise it to pull the full set.

## Actor input object example

```json
{
  "maxRecords": 500
}
```

# Actor output Schema

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

The delivered NOAA METAR observation record.

# 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 = {
    "maxRecords": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgensignal/noaa-metar-observation-records").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 = { "maxRecords": 500 }

# Run the Actor and wait for it to finish
run = client.actor("nexgensignal/noaa-metar-observation-records").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 '{
  "maxRecords": 500
}' |
apify call nexgensignal/noaa-metar-observation-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/noaa-metar-observation-records"
        }
    }
}
```

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/o3cBm7MGnuiMflyCK/builds/h6BLM9QGtru16ROWa/openapi.json
