# NOAA GHCN Station Reference — Global Directory (`nexgensignal/noaa-ghcn-station-records`) Actor

NOAA GHCN-Daily station directory (ghcnd-stations.txt) as clean, per-record station reference - ID, coordinates, elevation, state and GSN/HCN/CRN/WMO flags for ~132,500 weather stations. Public-domain, $0.05 per record.

- **URL**: https://apify.com/nexgensignal/noaa-ghcn-station-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 ghcn station 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?

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

## NOAA GHCN Station Reference — Global Directory

Turn NOAA's GHCN-Daily station directory into clean, per-record station reference data - one row per weather station with its ID, coordinates, elevation and network flags, ready to normalize and geolocate observation networks worldwide.

Each line of NOAA's published fixed-width station file becomes **one clean, flat record** with
coordinates and elevation coerced to real numbers, a stable `record_id` (the station ID), and provenance
stamped on every row: source, source file, the public-domain notice, attribution, a UTC retrieval
timestamp and an interpretation caveat.

### What one record represents

The source is NOAA NCEI's **GHCN-Daily station directory** — the file `ghcnd-stations.txt`, the master
reference list of the weather stations in the Global Historical Climatology Network. Each record is
**one station**: its GHCN identification code, latitude, longitude, elevation, U.S./Canada state (when
applicable), station name, the GSN and HCN/CRN network flags, and its WMO id when one is assigned.

The Actor parses the file by the exact column positions NOAA documents in the GHCN-Daily readme
(section IV, "FORMAT OF ghcnd-stations.txt"), quoted here verbatim:

```
Variable   Columns   Type
ID            1-11   Character
LATITUDE     13-20   Real
LONGITUDE    22-30   Real
ELEVATION    32-37   Real
STATE        39-40   Character
NAME         42-71   Character
GSN FLAG     73-75   Character
HCN/CRN FLAG 77-79   Character
WMO ID       81-85   Character
```

The first two characters of the station ID are the FIPS country code and the third is a network code,
so the ID itself locates a station geographically and by numbering system.

### Coverage and volume

The live directory holds **132,501** stations across the Global Historical Climatology Network - every country, from single-gauge sites to major airport stations - that is the record capacity of a full pull.

**Live count: 132,501 station rows - matches the Wave-3 index figure exactly.**

This is a directory (reference) product: one record per station, delivered in file order. Set **Maximum
records** to sample or to pull the whole directory.

### Licence and attribution

NOAA NCEI GHCN-Daily is a **U.S. Government work in the public domain** — free to use and redistribute
with attribution. The full notice travels on every record:

> NOAA NCEI GHCN-Daily. U.S. Government work, public domain (NWS/NCEI data-use); free to use and redistribute with attribution. Reproduced verbatim from the published fixed-width station file.

The required attribution — `NOAA National Centers for Environmental Information (NCEI), GHCN-Daily` — is present on every record.

### Interpretation caveat

A station directory (reference), not observations. Elevation of -999.9 in the source denotes missing; state is present only for U.S./Canada stations; GSN and HCN/CRN flags are present only for stations in those networks. Station names are place names, never persons.

Values are reproduced verbatim from the published file: the Actor never rescales or re-derives a number.

### Person-data policy

The GHCN station spec contains no observer or contact field — every column is a station identifier,
coordinate, elevation, state, station name, network flag or WMO id. Station names are place names, never
persons, and a per-record assertion enforces a person-field allow-list at write time.

### Data quality and freshness

Latitude, longitude and elevation are coerced to real numbers; a source elevation of -999.9 denotes
missing and is reproduced verbatim so you can filter it explicitly. State, GSN, HCN/CRN and WMO fields
are present only where the network assigns them, and arrive as `null` otherwise. Every run re-reads the
live file and re-stamps `observed_at`, so scheduling the Actor keeps a downstream station table current
as NOAA adds or revises stations.

### Provenance and compliance

Every run reads the exact host's `robots.txt` at runtime and refuses to proceed if the crawl policy
disallows the station-file path; the gate result (URL, status, byte length, SHA-256 of the policy) is
written to the run's `RUN_RECEIPT`. The Actor identifies itself with a transparent, non-impersonating
User-Agent and never bypasses a block or fetches through a mirror.

### Inputs

- **Maximum records** (`maxRecords`) — hard cap on station records delivered and billed. The full
  directory is about 132,500 stations.

### Output

Records land in the Actor's default dataset and export as JSON, CSV, Excel or via the Apify API. A
tabular **overview view** surfaces station id, name, state, coordinates, elevation and the network flags.

### Fields in detail

The record leads with `record_id` (the station ID) and `station_id`, then `latitude`, `longitude` and
`elevation` as numbers, `state`, `station_name`, the `gsn_flag` and `hcn_crn_flag` network markers, and
`wmo_id`. The provenance block — `source`, `source_dataset`, `licence`, `attribution`, `caveat`,
`observed_at` — closes every record, so a single row is self-describing and audit-ready. Because delivery
is in file order and keyed on the stable station ID, the dataset is safe to diff, deduplicate or upsert
into a warehouse, and a station keeps the same `record_id` across runs.

### Station ID structure

The GHCN station ID is itself a compact locator. Its first two characters are the FIPS country code (so
`US`, `CA`, `AS`, `FR` and so on group stations by country), the third character is a network code that
identifies the numbering system the station belongs to (for example `0` for an unspecified up-to-eight-
character id, `1` for a CoCoRaHS-based id, `W` for a WBAN-based id), and the remaining eight characters
carry the actual station number. That means you can filter or bucket the whole directory by country and
network directly off the `station_id` string, before any join, and the `wmo_id` gives you a second key
to line stations up against WMO-based feeds. The `state` field is populated only for stations in the
United States and Canada; elsewhere it is `null`, which is itself informative when you are partitioning a
global network by region.

### Scaling and limits

Set **Maximum records** low to sample the leading stations cheaply, or to about 132,500 to pull the whole
directory in one run. The Actor reads the published file once and delivers incrementally, so memory stays
flat regardless of how many stations you request, and you are billed only for what is delivered. Because
the directory changes slowly, a scheduled weekly or monthly run is usually enough to keep a downstream
station table current; each run re-stamps `observed_at` so you always know how old your snapshot is.

### Sibling Actors

This Actor is the **station directory** that observation feeds reference. It complements the fleet's observation cells - **`storm-event-records`** (NOAA storm events) and **`air-quality-monitor-records`** (EPA monitor readings): use this directory to describe and geolocate a station, and those cells for the measurements. Directory versus observations - distinct jobs. This Actor also shares its engineering — the runtime robots gate, push-then-charge
billing and verbatim-value discipline — with the fleet's other public-data records Actors.

### Sample output

![Sample output — NOAA GHCN Station Reference — Global Directory](https://api.apify.com/v2/key-value-stores/IXCaMKjxSmUTLHhmq/records/noaa-ghcn-station-records.png)

*Real rows from a live run of this actor (first 5 rows, selected columns).*

One full record from the same run, exactly as delivered:

```json
{
  "station_id": "ACW00011604",
  "latitude": 17.1167,
  "longitude": -61.7833,
  "elevation": 10.1,
  "state": null,
  "station_name": "ST JOHNS COOLIDGE FLD",
  "gsn_flag": null,
  "hcn_crn_flag": null,
  "wmo_id": null,
  "record_id": "ACW00011604",
  "source": "NOAA NCEI - GHCN-Daily",
  "source_dataset": "ghcnd-stations.txt",
  "licence": "NOAA NCEI GHCN-Daily. U.S. Government work, public domain (NWS/NCEI data-use); free to use and redistribute with attribution. Reproduced verbatim from the published fixed-width station file.",
  "attribution": "NOAA National Centers for Environmental Information (NCEI), GHCN-Daily",
  "caveat": "A station directory (reference), not observations. Elevation of -999.9 in the source denotes missing; state is present only for U.S./Canada stations; GSN and HCN/CRN flags are present only for stations in those networks. Station names are place names, never persons.",
  "observed_at": "2026-09-25T17:24:35Z"
}
```

### Pricing

This Actor uses Apify's pay-per-event model: a flat **$0.05 per record** actually delivered to the
dataset, and nothing else — no monthly rental, no per-run base fee, no compute charge. Deliver 40
records and you pay $2.00; deliver 10,000 and you pay $500.00. Billing is wired *after* delivery — each
record is pushed first and only then does the per-record event fire — so a mid-run failure can only
ever under-charge you, never over-charge. Use **Maximum records** to cap spend precisely.

### Typical uses

Normalize and geolocate observation networks; join station coordinates and elevation onto weather or climate observations; filter to GSN or HCN/CRN reference networks; build a station map or coverage analysis; or feed a weather-data-vendor or climate-analytics pipeline with a clean station reference.

### What this Actor does not do

It does not deliver observations or measurements — it is the **station directory** that those
observations reference; it does not forecast or model; and it does not alter any published value. It
gives you a faithful, public-domain, analysis-ready station reference — one row per station — with a
provenance trail you can audit on every run.

# Actor input Schema

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

Maximum station records delivered and billed. You are billed only for records delivered. The full station directory is ~132,500 rows.

## Actor input object example

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

# Actor output Schema

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

The delivered NOAA GHCN station 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-ghcn-station-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-ghcn-station-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-ghcn-station-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/noaa-ghcn-station-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/ezvdiMFi5c7MCE6ul/builds/8LVcGlbsdcy2OcgZn/openapi.json
