Kalshi Weather Markets Scraper
Pricing
from $2.00 / 1,000 market rows
Kalshi Weather Markets Scraper
Kalshi temperature, rain, hurricane and tornado markets as clean, spreadsheet-ready rows. Parses the city, weather station, storm name, bracket bounds and settled outcome into their own columns. Filter by city, temperature, date, volume or implied probability. No API key, no proxies.
Pricing
from $2.00 / 1,000 market rows
Rating
0.0
(0)
Developer
George Semaan
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Kalshi Weather Markets Scraper: Temperature, Rain, Hurricanes & Tornadoes, 28 Cities + Weather Stations
$2.00 per 1,000 rows. No API key. No proxies. Runs in under two minutes.
Pulls every open weather market on Kalshi (daily high and low temperature, hourly temperature, heat streaks, rain, snow, hurricanes, tropical storms, tornadoes, earthquakes and climate markets) and returns them as flat, spreadsheet-ready rows with the city, weather station, storm name, bracket bounds and settled outcome already parsed into their own columns.
It also reads settled markets, including the observed temperature that decided them, and can walk Kalshi's deep archive back to August 2021.
What you get
A single flat row per market. No nested JSON to unpick, no cent-vs-dollar guessing, no reading rules text to find out which city a ticker belongs to.
| ticker | city | station | date | bracket | yes_bid | yes_ask | implied_prob | volume |
|---|---|---|---|---|---|---|---|---|
| KXHIGHNY-26AUG29-T79 | New York City | CLINYC | 2026-08-29 | <79 | 0.56 | 0.57 | 0.565 | 2242.64 |
| KXHIGHNY-26AUG29-B79.5 | New York City | CLINYC | 2026-08-29 | 79-80 | 0.36 | 0.37 | 0.365 | 715.79 |
| KXRAIN-26AUG28-CHI | Chicago | CLIORD | 2026-08-28 | >0 inches | 0.00 | 0.01 | 0.005 | 4188.00 |
Storm markets, which have no city at all, come back keyed on the storm instead:
| ticker | storm_name | storm_metric | category | wind threshold | basin | yes_ask |
|---|---|---|---|---|---|---|
| KXHURCAT-26DOLLY-T1 | Dolly | hurricane_category | 1 | 74 mph | Atlantic | 0.09 |
| KXHURCAT-26DOLLY-T2 | Dolly | hurricane_category | 2 | 96 mph | Atlantic | 0.02 |
And settled markets carry what actually happened:
| ticker | date | bracket | result | observed | settlement |
|---|---|---|---|---|---|
| KXHIGHNY-26AUG27-T87 | 2026-08-27 | >87 | no | 77 °F | $0.00 |
30-second quickstart
- Click Start. The defaults fetch three representative series, about 226 rows, in a few seconds: a temperature ladder, a multi-city rain event and a storm bloc.
- To widen it, clear Series tickers entirely for every weather series with open markets, about 1,280 rows in roughly six minutes. To narrow it instead, list the tickers you want. Series are discovered at runtime, so new ones appear without an update.
- To get results instead of prices, set What to fetch to
settled.
Coverage
Measured on a live full run:
- 109 series with open markets, out of 360 in Kalshi's catalogue; the other 251 are renamed duplicates and unlaunched tickers, filtered out automatically.
- 28 cities, 41 distinct weather stations, 57 named storms, 17 regions and ocean basins.
- 99.7% of rows resolve a city, a named storm or a region. The remainder are markets whose rules genuinely state no location.
Every city Kalshi lists is in the United States. These are the 28, and there are no others. The scraper reads whatever the exchange publishes, so if a city is missing it is missing from Kalshi, not filtered out here:
Atlanta, Austin, Boston, Chicago, Dallas, Dallas/Fort Worth, Denver, Hoover Dam, Houston, Houston Hobby Airport, Las Vegas, Los Angeles, Louisville, Miami, Minneapolis, New Orleans, New York City, Newark, Oklahoma City, Philadelphia, Phoenix, San Antonio, San Diego, San Francisco, San Jose, Seattle, Trenton, Washington DC.
Kalshi writes several of these two ways: Austin and Austin, TX,
Central Park, New York City and New York City. Both spellings are preserved
in city and unified in city_canonical, and the cities filter matches
either, so you never have to know which wording a given market used.
Outside the United States
There is international coverage, but it is not city-level. Those markets are
about a basin, a country or the whole planet, so they carry a region instead
of a city. Filter them with regions, not cities:
region | What it covers |
|---|---|
Atlantic, Eastern Pacific, Central Pacific | Hurricanes, named storms, season totals |
Worldwide | Global temperature records, CO2 concentration, earthquakes, volcanoes |
Japan | Earthquake markets |
European Union, India | Climate-policy markets |
Arctic | Sea ice extent |
Pacific | ENSO / El Niño (RONI) |
// Atlantic hurricane season markets{ "mode": "live", "regions": ["Atlantic"] }
Market types, by open-market count on a recent run: storms 347, low temperature 291, high temperature 288, rain 156, hourly temperature 63, heat streaks 50, global temperature 17, earthquakes 17, ENSO 16, sea ice 9, CO2 5, volcanoes 4, climate policy 4.
Input
Every field is optional.
| Field | Default | What it does |
|---|---|---|
mode | live | live for open markets and prices, settled for outcomes, both. |
seriesFilter | KXHIGHNY, KXRAIN, KXHURCAT | Which series to fetch. Clear it entirely to fetch every weather series that currently has open markets. |
includeStorms | true | Include hurricane, tropical storm and tornado markets. |
includeOrderbook | false | Add resting bid depth, a derived yes-ask and the spread. Batched, so it costs very few extra requests. |
includeRecentTrades | false | Add recent executed trades. Costs one request per market. |
historyDays | 7 | Settlement lookback window. |
includeHistoricalArchive | false | Also walk Kalshi's deep archive, back to 2021. |
incremental | false | Remember the newest settlement seen and fetch only newer ones next run. |
maxResults | 5000 | Safety cap on rows per run. |
requestsPerSecond | 2 | Politeness limit. |
Filters
Ask for the slice you want instead of downloading everything and grepping it. Filters run before rows are written, so a narrower request returns fewer rows and costs less.
| Field | What it does |
|---|---|
cities | Keep only these cities: ["Chicago", "New York City"]. Case- and punctuation-insensitive, and matches both the city as Kalshi wrote it and its canonical name, so archive rows written "Central Park, New York City" still match "New York City". |
regions | Keep only these regions, basins or countries: ["Atlantic"]. This is how you filter storm markets, which have no city. |
stations | Keep only these weather station codes: ["CLINYC", "CLIORD"]. |
stormNames | Keep only these named storms: ["Yolanda"]. |
metrics | Keep only certain market types (high_temp, rain, storm, …). |
minStrike / maxStrike | Strike window in the market's own unit: °F for temperature, inches for rain, category for hurricanes. A market is kept when any part of its range overlaps the window, so open-ended markets like "below 79" are not silently dropped. |
dateFrom / dateTo | Weather-date window, YYYY-MM-DD. This is the date the market is about, not its close date. |
minVolume | Drop markets that have traded less than this. The most effective single lever for cutting a run down to markets anyone is actually trading. |
minOpenInterest | Drop markets with fewer open contracts than this. |
minProbability / maxProbability | Implied-probability window, 0–1. 0.4–0.6 finds near coin-flips; maxProbability: 0.05 finds longshots. |
results | Settled modes only. Keep only yes, no or scalar outcomes. |
// Every Chicago rain market anyone is actually trading{ "mode": "live", "cities": ["Chicago"], "metrics": ["rain"], "minVolume": 100 }// Near coin-flips across every weather market{ "mode": "live", "minProbability": 0.4, "maxProbability": 0.6 }// New York highs between 70 °F and 80 °F this week{ "mode": "live", "cities": ["New York City"], "minStrike": 70, "maxStrike": 80 }
Scheduling recipe
Kalshi's public data is cached for 15 seconds, so polling faster than that returns identical bytes. A sensible schedule:
- Prices: hourly,
mode: live, with aseriesFiltercovering only the cities you trade. A three-series run is about 10 requests and 60 rows. - Results: once daily after settlement,
mode: settledwithincremental: true. The first run fetches your lookback window; every run after that fetches only what is new, and finishes in seconds.
Pipe the dataset straight into Google Sheets, S3 or a webhook using Apify's built-in integrations, no extra code.
What makes this different
Storm markets are covered. Hurricanes, tropical storms and tornadoes are the single largest bloc of open weather markets on Kalshi. They carry a storm name and an ocean basin rather than a city, so tools built around "city + temperature" return empty columns for all of them. This one parses the storm name, basin, category, wind threshold and season window.
Multi-city rain markets are decomposed. Kalshi packs 22 cities into a single rain event, and the city appears only on the individual market. Rows come back with the right city and station on each.
The observed temperature is recovered. Over half of Kalshi's archived settled
markets have an empty observed-value field. Because a daily temperature ladder has
exactly one winning bracket, the real reading can be bounded from it. The actor
fills observed_value_min and observed_value_max, and marks whether the value was
reported or derived. That lifts observed-value coverage on a five-year New York pull
from 45% to 90%.
Five years of history joins cleanly. Kalshi's rules wording changed over time
("Central Park, New York" in 2022, "New York City (CLINYC)" in 2026), and its tickers
were renamed (HIGHNY → KXHIGHNY, KXLOW → KXLOWT). city keeps the published
text; city_canonical gives one name you can group by across the whole archive.
Nothing is hardcoded. Series, cities and stations are all discovered at runtime. Kalshi has renamed tickers twice and moved its settlement source once; a scraper with a baked-in city list breaks on the next change.
Strike direction is read, not guessed. A -T79 ticker is a less-than market
and a -T86 is a greater-than one. The letter means nothing. Bounds come from the
payload, with explicit floor_inclusive / cap_inclusive flags.
Output fields
Identity: ticker, event_ticker, series_ticker, market_title,
event_title, series_title, category, schema_version
Location: city, city_canonical, station, station_kind, city_source,
region, region_kind
Storms: storm_name, storm_basin, storm_metric, storm_category,
storm_wind_threshold_mph, season_start, season_end
Classification: weather_metric, unit, metric_source, frequency, tags,
market_date, mutually_exclusive
Strike: strike_type, floor_strike, cap_strike, floor_inclusive,
cap_inclusive, bracket_label, yes_sub_title, no_sub_title
Prices: yes_bid, yes_ask, no_bid, no_ask, last_price,
previous_price, previous_yes_bid, previous_yes_ask, yes_bid_size,
yes_ask_size, implied_probability_yes
Size: volume, volume_24h, open_interest, liquidity, notional_value
Settlement: status, result, settlement_value, settlement_ts,
observed_value, observed_value_min, observed_value_max, observed_value_source
Times: open_time, close_time, expiration_time, expected_expiration_time,
can_close_early, created_time, updated_time, scraped_at
Optional: orderbook_yes_bids, orderbook_no_bids, orderbook_best_yes_bid,
orderbook_best_no_bid, orderbook_yes_ask, orderbook_yes_ask_size,
orderbook_spread, recent_trades
Raw: rules_primary, rules_secondary are passed through untouched, so you can
always check the parsing against the source.
Notes on accuracy
- Prices are dollars per contract, 0.0000 to 1.0000. A missing quote is
null, never0. - Volumes and sizes can be fractional. They are numbers, not strings.
resultcan beyes,noorscalar.scalarmeans a voided or partial settlement. Do not assume every settled market pays 0 or 1.- Settled markets can later be
disputedoramended.updated_timeis included so you can upsert rather than append. city_sourceandobserved_value_sourcetell you where each derived value came from, so you can filter to only what was read directly from the payload.- Order books are bid-only on both sides. The
orderbook_yes_askfield is derived as1 − best_no_bid, and it matches Kalshi's own quote on every market checked.
Schema stability & versioning
Every row carries schema_version. Fields will be added, never silently renamed or
removed within a major version. Kalshi replaced its integer-cent price fields with
decimal-string dollar fields in 2026 and broke most tools in this niche; this one
reads the current format and fails loudly rather than emitting zeros.
Compliance
This is an unofficial tool. It is not affiliated with, endorsed by, or connected to Kalshi in any way. "Kalshi" is used only to describe what the data is about.
It reads Kalshi's public, unauthenticated market-data endpoints at a deliberately conservative 2 requests per second with backoff and a circuit breaker. It does not log in, place orders, or access any account data.
You are responsible for your own use of the data, including compliance with Kalshi's terms. Nothing here is trading or investment advice.
Changelog
1.0: First release. Live and settled modes, deep archive, storm and region parsing, multi-city rain decomposition, observed-value recovery, order book depth, incremental runs.
Keywords
kalshi weather api, kalshi weather markets, kalshi temperature markets, KXHIGH data, KXHIGHNY, KXLOWT, KXLOW, KXRAIN, KXHURCAT, kalshi hurricane markets, kalshi tornado markets, kalshi rain markets, weather prediction market data, prediction market scraper, kalshi scraper, kalshi api, temperature futures data, weather trading data, kalshi settlement history, kalshi historical data, event contracts weather