NOAA Buoy Data Scraper avatar

NOAA Buoy Data Scraper

Pricing

from $2.13 / 1,000 observation extracteds

Go to Apify Store
NOAA Buoy Data Scraper

NOAA Buoy Data Scraper

Export official NOAA NDBC buoy observations by station and time range, including wind, waves, pressure, temperatures, units, and provenance.

Pricing

from $2.13 / 1,000 observation extracteds

Rating

0.0

(0)

Developer

Automation Lab

Automation Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

22 minutes ago

Last modified

Categories

Share

Export official NOAA buoy data from the National Data Buoy Center (NDBC) into a clean, timestamped dataset. Choose buoy station IDs, retrieve NOAA's rolling recent observations or complete yearly historical files, and receive normalized wind, wave, pressure, air temperature, water temperature, location, units, and source-provenance fields.

The Actor uses NOAA's first-party public data files. It needs no NOAA API key, browser, login, or proxy.

What can NOAA Buoy Data Scraper do?

  • Retrieve recent standard-meteorological observations for up to 20 NDBC stations per run.
  • Download as many as five annual historical station files in one run.
  • Keep NOAA's full time resolution: 10-minute and other subhourly observations keep their exact minute.
  • Filter results with inclusive ISO 8601 start and end times (UTC).
  • Normalize NOAA's dynamic columns, older archive column names, and realtime and historical missing-value markers.
  • Sort observations newest first and cap output with maxItems.
  • Optionally return only the latest observation per station for recurring buoy comparisons.
  • Add observationAgeMinutes to every row and warn when a realtime station has not reported for more than 3 hours.
  • Write a RUN_SUMMARY record with per-station and per-file outcomes, so missing files, empty date windows, and truncation are easy to tell apart.
  • Attach active-station names, coordinates, owner, program, and source URLs.
  • Export through Apify as JSON, CSV, Excel, XML, RSS, or an API response.

Who is this NOAA buoy data Actor for?

Marine operations teams can monitor winds, waves, and pressure at relevant offshore stations. Coastal researchers and analysts can build bounded time-series datasets. Surf, fishing, and boating products can ingest official observations. Data engineers can schedule a Task and deliver fresh station readings to databases, webhooks, or BI tools.

This Actor returns measurements, not forecasts or safety advice. For daily land weather observations, use NOAA Historical Weather Observations.

What data is extracted?

GroupFields
IdentitystationId, stationName, stationType, owner, program
Timetimestamp, year, month, day, hour, minute, observationAgeMinutes
WindwindDirectionDegrees, windSpeedMetersPerSecond, windGustMetersPerSecond
WaveswaveHeightMeters, dominantWavePeriodSeconds, averageWavePeriodSeconds, meanWaveDirectionDegrees
WeatherseaLevelPressureHpa, airTemperatureCelsius, dewPointCelsius, visibilityNauticalMiles, pressureTendencyHpa
WaterwaterTemperatureCelsius, tideFeet
Locationlatitude, longitude
Provenancemode, units, sourceUrl, sourceAgency, retrievedAt

A measurement is null when NOAA marks it missing or the station does not publish that sensor field. Realtime files mark missing values with MM; historical files use field-specific runs of 9s (for example 99.0 wind speed or 999.0 water temperature). Both become null rather than fake readings or misleading zeroes.

observationAgeMinutes is the number of whole minutes between timestamp and the run's retrievedAt time. One retrieval clock is used for the whole run.

How to get NOAA buoy observations

  1. Open the Actor input page.
  2. Enter one or more NDBC station IDs, such as 41004.
  3. Choose Recent / realtime or Historical yearly files.
  4. For historical data, provide one to five years.
  5. Optionally add start/end timestamps and adjust the result limit.
  6. Click Start and download the default dataset in your preferred format.

Input parameters

InputTypeDefaultDescription
stationIdsstring array["41004"]1–20 alphanumeric NDBC station IDs
modestringrealtimerealtime rolling archive or historical annual files
yearsinteger array[2025]Required in historical mode; 1–5 years
startDatestring—Optional inclusive ISO 8601 lower bound (UTC)
endDatestring—Optional inclusive ISO 8601 upper bound (UTC)
maxItemsinteger100Total rows to save, from 1 to 10,000
latestOnlybooleanfalseSave only the newest observation per station

Dates are UTC. A date without a time, such as 2025-06-03, means 2025-06-03T00:00:00Z, so use 2025-06-03T23:59:59Z to include the whole day. A time without a zone is read as UTC. Fractional seconds and UTC offsets such as +02:00 are accepted. Other date formats, and impossible dates such as 2025-02-30 in any form, are rejected before the run starts charging.

Historical files only exist for station/year combinations published by NOAA. A missing file is logged, recorded in RUN_SUMMARY, and skipped so another requested station or year can still produce data.

Station IDs are case-insensitive and duplicates are fetched once. Output uses the uppercase NDBC ID, for example BURL1.

Input examples

Recent observations for one buoy:

{
"stationIds": ["41004"],
"mode": "realtime",
"maxItems": 25
}

A bounded historical analysis:

{
"stationIds": ["41001"],
"mode": "historical",
"years": [2025],
"startDate": "2025-06-01T00:00:00Z",
"endDate": "2025-06-03T23:59:59Z",
"maxItems": 500
}

For station 41001 this window holds 432 ten-minute observations, and all 432 are saved because maxItems is above that count. With a lower maxItems, only the newest observations up to that cap are saved, and RUN_SUMMARY reports truncatedByMaxItems: true.

The latest reading at each of several buoys, for a scheduled comparison:

{
"stationIds": ["41002", "41004", "46042"],
"mode": "realtime",
"latestOnly": true,
"maxItems": 3
}

Output example

A real recent run produces rows shaped like this:

{
"stationId": "41004",
"stationName": "EDISTO - 41 NM Southeast of Charleston, SC",
"latitude": 32.502,
"longitude": -79.099,
"timestamp": "2026-09-19T04:00:00.000Z",
"windDirectionDegrees": 240,
"windSpeedMetersPerSecond": 3,
"windGustMetersPerSecond": 4,
"waveHeightMeters": null,
"seaLevelPressureHpa": 1017.6,
"airTemperatureCelsius": 28.1,
"waterTemperatureCelsius": 28.9,
"mode": "realtime",
"sourceUrl": "https://www.ndbc.noaa.gov/data/realtime2/41004.txt",
"sourceAgency": "NOAA National Data Buoy Center"
}

Every row also contains a units object, making downstream interpretation explicit.

Run summary

Each run also saves a RUN_SUMMARY record in its default key-value store. It is free and is not a dataset row. It lists, for each station, whether metadata and files were found, how many rows matched the date window, how many malformed rows NOAA's file contained, how many observations were selected and how many were actually saved (and charged), and the newest source timestamp and its age. It also states whether maxItems cut off matching observations and repeats any warnings, such as a missing file, unavailable station metadata, or a stale realtime station.

How much does it cost to export NOAA buoy observations?

Pay-per-event pricing consists of a $0.00005 start fee and one observation event per saved row. The BRONZE price is $0.003552 per observation, with lower unit prices on higher subscription tiers.

Saved observationsBRONZE estimate
10.003602 USD
250.08885 USD
1000.35525 USD
1,0003.55205 USD

Estimates use the current BRONZE price and include the start event. Actual billing can differ by subscription tier and can be affected by refunds, fraud, disputes, taxes, corrections, or clawbacks. Missing files and filtered-out rows are not charged as observations.

Monitoring and automation workflows

Create an Apify Task with stable station IDs, schedule it hourly or daily, and send results through a webhook. Use timestamp plus stationId as a natural deduplication key in your destination.

For dashboards and alerts that only need the current reading at each buoy, turn on latestOnly. One row per station keeps the dataset small and the cost predictable. Check observationAgeMinutes, or the stale-station warning in RUN_SUMMARY, before treating a reading as current. Stale readings are kept and flagged, never silently dropped. For historical backfills, request a bounded year/date range, export it once, and keep recurring jobs in realtime mode.

Useful integrations include Google Sheets, Make, Zapier, webhooks, cloud storage, PostgreSQL, and any client that can call the Apify API.

Use the Actor through the API

Replace APIFY_TOKEN with your token.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~noaa-buoy-observations/run-sync-get-dataset-items?token=APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"stationIds":["41004"],"mode":"realtime","maxItems":25}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/noaa-buoy-observations').call({
stationIds: ['41004'], mode: 'realtime', maxItems: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
client = ApifyClient(token="APIFY_TOKEN")
run = client.actor("automation-lab/noaa-buoy-observations").call(run_input={
"stationIds": ["41004"], "mode": "realtime", "maxItems": 25
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Use with MCP and AI agents

Claude Code setup

Add this Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/noaa-buoy-observations"

Claude Desktop, Cursor, and VS Code setup

Use this MCP configuration in Claude Desktop, Cursor, or VS Code:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/noaa-buoy-observations"
}
}
}

Example prompts:

  • “Get the 20 newest NOAA observations for buoy 41004 and summarize wind and waves.”
  • “Export station 41001 observations from June 1–3, 2025 as a table.”
  • “Compare the latest water temperatures at buoys 41002, 41004, and 46042.”

Reliability and failure behavior

The Actor retries transient network failures, timeouts, and HTTP 408/429/5xx responses up to three times with bounded backoff. Other HTTP errors are not retried and fail the run with the NOAA status. Requests time out after 30 seconds. Invalid station identifiers, malformed or impossible dates, reversed date ranges, and unsupported modes fail the run with a clear error before any observation is charged. Missing station/year files are warnings rather than fabricated empty records. If NOAA's station metadata feed is unavailable, observations are still returned with null station name and location, and the run summary says so. Malformed rows in a NOAA file are skipped and counted instead of shifting values into the wrong columns.

History is processed one file at a time and only the newest maxItems candidates are kept in memory, so a narrow date window or small limit over several years stays light.

Error reporting

When a run fails, the Actor sends sanitized diagnostic input, the exception, and Actor/build/run IDs to our private GlitchTip error tracker so we can fix the problem. Secret fields and URL query strings are removed, and reports are kept for 30 days.

NOAA may change files, station availability, sensor packages, or update cadence. Source timestamps are authoritative; “realtime” means NOAA's rolling recent archive, not guaranteed instantaneous delivery.

Limits and tips

  • Use exact NDBC station IDs; this version does not search by place or nearest coordinate.
  • The Actor supports NDBC standard meteorological files, not every specialized NDBC sensor product.
  • Active-station metadata can be unavailable for retired historical stations; observation rows still retain their station ID and source URL.
  • maxItems applies across all requested stations and years after newest-first sorting, so one station can fill the limit. Use latestOnly for one row per station.
  • Older historical archives are often hourly; recent archives and the realtime file are usually every 10 minutes. The actual NOAA reporting interval is kept.
  • A maximum of 20 stations, five historical years, and 10,000 saved observations keeps runs bounded.
  • No proxy setting is needed because NOAA's public files are accessed directly.

Legality and responsible use

NOAA/NDBC data is official U.S. government source material, but users remain responsible for checking applicable NOAA notices, attribution requirements, laws, and downstream-use obligations. Preserve sourceUrl, sourceAgency, and observation timestamps when redistributing records. Do not use this Actor as the sole source for navigation, emergency, or life-safety decisions.

Troubleshooting

Why did my run return no rows? Open RUN_SUMMARY in the run's key-value store. It shows whether NOAA had a file for each station/year and how many rows fell inside your date window. Then remove or widen date filters.

Why is a measurement null? NOAA uses missing-value markers when a sensor is unavailable or did not report. Null is the accurate normalized representation.

Why is my historical run large? Annual files can contain many observations. Set dates and maxItems before increasing scope.

Why is station metadata null? NOAA's active-station feed may no longer list a retired station. Historical measurements and provenance can still be valid.

FAQ

Does this provide forecasts? No. It exports measured NDBC observations.

Can I retrieve several buoys at once? Yes, provide up to 20 station IDs.

How far back does history go? Coverage varies by station. Request years from 1970 through the current year, but only NOAA-published files return records.

Are output units consistent? Yes. The Actor maps standard fields to explicit names and includes a units object on every row.

Are duplicate rows charged? No. Records are deduplicated by station ID and observation minute before charging and saving. Filtered-out rows, missing files, and the run summary are never charged.

Why do I get more rows per day than before? Observations now keep their exact minute. A buoy reporting every 10 minutes returns six rows per hour instead of one row per hour with a rounded time.