# NOAA Hail, Wind & Tornado Storm Reports (SPC) (`wishbone_data/spc-storm-reports`) Actor

Daily NOAA Storm Prediction Center local storm reports - hail size, wind gusts, tornadoes - with lat/lon, county and exact UTC time. Filter by date range, state, hail size, wind speed or radius around a point. Built for roofing, restoration, insurance and solar teams.

- **URL**: https://apify.com/wishbone\_data/spc-storm-reports.md
- **Developed by:** [Walter Washburn](https://apify.com/wishbone_data) (community)
- **Categories:** Lead generation, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Hail, Wind & Tornado Storm Reports Scraper (NOAA SPC)

Get **every NOAA Storm Prediction Center hail, damaging-wind and tornado report** for any date range since 2004 - with **hail size in inches, wind gust in mph, exact UTC time, latitude/longitude, county and state**. Filter by state, minimum hail size, minimum wind speed, or a **radius around any point**.

Built for **roofing contractors, storm-restoration companies, public adjusters, insurers, solar and fleet operators** who need to know where damaging weather actually hit - the same day or years back.

### What does this Actor do?

The SPC publishes one CSV per day and per hazard. This Actor:

- reads every daily file in your date range (hail, wind, tornado),
- converts hail size from hundredths to inches and computes the **real UTC timestamp** (an SPC "day" runs 12:00 UTC to 11:59 UTC the next day - reports after midnight UTC are dated correctly),
- splits the issuing NWS office code out of the comments,
- filters by state, size, speed and distance, and adds `distanceMiles` for radius searches,
- optionally includes today's preliminary reports.

A 60-day, two-state hail/wind/tornado pull takes well under a minute.

### Use cases

- **Roofing & restoration lead targeting** - hail of 1.00"+ within 30 miles of your branch last week.
- **Insurance & claims** - verify a date-of-loss claim against reported hail/wind near an address.
- **Solar, auto dealers, fleet and ag** - post-storm damage checks on your sites.
- **Territory planning** - count damaging hail days per county over several seasons.
- **Media & research** - daily severe-weather summaries.

### Input examples

Golf-ball hail or bigger in Texas and Oklahoma, May-June 2025:

```json
{
  "startDate": "2025-05-01",
  "endDate": "2025-06-30",
  "reportTypes": ["hail"],
  "states": ["TX", "OK"],
  "minHailInches": "1.75"
}
```

Everything within 40 miles of Denver over a season:

```json
{
  "startDate": "2025-04-01",
  "endDate": "2025-07-31",
  "reportTypes": ["hail", "wind"],
  "centerLat": "39.74",
  "centerLon": "-104.99",
  "radiusMiles": 40
}
```

Last 14 days, all types, nationwide (good for a daily/weekly schedule):

```json
{ "startDate": "14 days ago", "endDate": "yesterday", "includeToday": true }
```

### Output example

```json
{
  "eventType": "hail",
  "reportDate": "2025-06-29",
  "eventTimeUtc": "2025-06-30T00:53:00Z",
  "magnitude": 1.75,
  "magnitudeUnit": "in",
  "hailSizeInches": 1.75,
  "windMph": null,
  "tornadoRating": null,
  "location": "4 WNW Foyil",
  "county": "Rogers",
  "state": "OK",
  "lat": 36.46,
  "lon": -95.59,
  "office": "TSA",
  "comments": "Pic of golf ball hail next to a ruler relayed via social media.",
  "sourceUrl": "https://www.spc.noaa.gov/climo/reports/250629_rpts_hail.csv"
}
```

| Field | Meaning |
|---|---|
| `eventType` | hail, wind or tornado |
| `reportDate` | SPC convective day (12Z-12Z) |
| `eventTimeUtc` | Exact report time in UTC |
| `hailSizeInches` / `windMph` / `tornadoRating` | Magnitude by type (`magnitude` + `magnitudeUnit` in one column too) |
| `location` | Distance/direction from a place, e.g. "4 WNW Foyil" |
| `county`, `state`, `lat`, `lon` | Where |
| `distanceMiles` | Only on radius searches |
| `office` | NWS office that logged the report |
| `comments` | Spotter / NWS remarks |

### Pricing

Pay-per-event:

| Event | Price |
|---|---|
| Actor start | $0.005 per run |
| `storm-report` | **$2.00 per 1,000 storm reports** |

Example: a 14-day nationwide run (all three types) in late September 2026 returned 803 reports - about **$1.61**. Peak spring weeks can return several times more. State, size and radius filters cut that down, and you only pay for reports that pass your filters. Set a max cost per run to cap spend.

### FAQ

**Is this legal?** Yes. SPC storm reports are produced by NOAA/National Weather Service, a U.S. Government agency; the data is public domain and published for public use. The Actor downloads the published CSV files at a gentle rate and doesn't touch any login-protected system. It contains no personal data.

**Are these reports verified?** They are *preliminary local storm reports* from trained spotters, emergency managers, mPING and the public, quality-controlled by the SPC. Final, verified data goes into NOAA's Storm Events Database months later. For same-week targeting, SPC reports are the standard source.

**Why does a report dated June 29 have a June 30 timestamp?** SPC days run 12:00 UTC to 11:59 UTC. Evening storms in the US are after midnight UTC, so `eventTimeUtc` is the next calendar day. `reportDate` keeps the SPC day for matching SPC's own maps.

**Does it return addresses?** No - reports are point locations. Combine `lat`/`lon` + `radiusMiles` with your own customer or property list.

**How far back?** The SPC CSV archive starts in 2004.

# Actor input Schema

## `startDate` (type: `string`):

First SPC convective day (YYYY-MM-DD), or relative like '7 days ago'. Archive goes back to 2004.

## `endDate` (type: `string`):

Last convective day (YYYY-MM-DD), 'yesterday' or 'today'. Each SPC day runs 12:00 UTC to 11:59 UTC next day.

## `reportTypes` (type: `array`):

Which SPC report files to read.

## `states` (type: `array`):

Two-letter state codes, e.g. TX, OK, CO. Empty = all states.

## `minHailInches` (type: `string`):

e.g. 1.00 (quarter), 1.75 (golf ball), 2.75 (baseball). Roof damage usually starts around 1.00-1.25 in.

## `minWindMph` (type: `integer`):

Wind reports with unknown speed are dropped when this is set.

## `centerLat` (type: `string`):

Optional. With longitude and radius, keeps only reports within that many miles.

## `centerLon` (type: `string`):

Longitude of the radius-search center, e.g. -97.52.

## `radiusMiles` (type: `integer`):

Radius around the center point, in miles.

## `includeToday` (type: `boolean`):

Adds the rolling 'today' files (preliminary, updated through the day).

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

0 = no limit.

## Actor input object example

```json
{
  "startDate": "14 days ago",
  "endDate": "yesterday",
  "reportTypes": [
    "hail",
    "wind",
    "tornado"
  ],
  "minHailInches": "1.0",
  "includeToday": false,
  "maxItems": 0
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `results` (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 = {
    "startDate": "14 days ago",
    "endDate": "yesterday",
    "reportTypes": [
        "hail",
        "wind",
        "tornado"
    ],
    "minHailInches": "1.0"
};

// Run the Actor and wait for it to finish
const run = await client.actor("wishbone_data/spc-storm-reports").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 = {
    "startDate": "14 days ago",
    "endDate": "yesterday",
    "reportTypes": [
        "hail",
        "wind",
        "tornado",
    ],
    "minHailInches": "1.0",
}

# Run the Actor and wait for it to finish
run = client.actor("wishbone_data/spc-storm-reports").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 '{
  "startDate": "14 days ago",
  "endDate": "yesterday",
  "reportTypes": [
    "hail",
    "wind",
    "tornado"
  ],
  "minHailInches": "1.0"
}' |
apify call wishbone_data/spc-storm-reports --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wishbone_data/spc-storm-reports"
        }
    }
}
```

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/oGluZrSDD5drD1lZy/builds/LZ1ozw0LFc43EACeL/openapi.json
