Use case
Reading Kalshi's Weather Markets by City, Station and Bracket
Kalshi's temperature contracts never name the city in the question. Here is how to get city, settlement station and bracket bounds as columns you can join to a forecast.
A Kalshi daily-temperature market asks: “Will the maximum temperature be 86-87° on Sep 7, 2026?”
That question is missing the two things you need to trade it. It does not say which city, and it does not say which weather station settles the contract. Both exist — they are written into the market’s resolution rules as prose — but neither is in the title, the subtitle, or any field called something helpful. So the natural thing to do with a temperature market, which is to line its bracket up against a forecast, needs a parsing step before you can even begin.
This is what that step looks like as columns.
The job
You want a table where each row is one temperature bracket, carrying the city, the settlement station, the numeric bounds of the bracket, and the market’s own implied probability. Then you can join it to whatever forecast you already trust and see where the market disagrees with you.
The input
Kalshi honours a series ticker server-side, which matters here: naming the series you care about
turns a 17-second walk across the whole exchange into a single request of roughly half a second.
The daily-high series are named by city — KXHIGHNY, KXHIGHCHI, KXHIGHMIA, KXHIGHAUS — and
there are lows and rain series alongside them.
{
"venue": "kalshi",
"series": ["KXHIGHNY", "KXHIGHCHI", "KXHIGHMIA"],
"maxResults": 200
}
Do not add a keyword or a category on top of a series. The filters are AND-ed, so a series plus an unrelated keyword is a correct query with an empty answer.
If you would rather sweep by category than name series, use categories: ["Climate and Weather"]
with no series set. That reads the whole exchange and filters afterwards — slower, but it finds
series you did not know existed. On 7 September 2026 Kalshi’s climate and weather category held
104 events across 597 markets, and its series index listed 123 temperature and rain series by city,
from KXHIGHTEGLL (London) to KXLOWTMMMX (Mexico City).
What comes back
{
"venue": "kalshi",
"market_id": "KXHIGHMIA-26SEP07-B86.5",
"series": "KXHIGHMIA",
"question": "Will the maximum temperature be 86-87° on Sep 7, 2026?",
"subtitle": "86° to 87°",
"category": "Climate and Weather",
"yes_price": 0.03,
"implied_probability": 0.02,
"volume": 6136.62,
"open_interest": 4570.47,
"close_time": "2026-09-08T05:00:00Z",
"weather_city": "Miami",
"weather_station": "CLIMIA",
"bracket_low": 86.0,
"bracket_high": 87.0,
"bracket_type": "between"
}
Four fields there are the whole point of this article, and none of them is in the question text:
weather_city— Miami. Read out of the resolution rules, which say the temperature is recorded “at Miami (CLIMIA)”.weather_station— CLIMIA. This is the one that matters for settlement. A forecast for “Miami” is not the same thing as the reading at the specific station Kalshi settles against, and the difference is exactly where a bracket is won or lost.bracket_low/bracket_high— 86 and 87, as numbers. Kalshi states these structurally, so you are not parsing “86-87°” out of a string and hoping the dash is always the same character.bracket_type—between,greaterorless. The end brackets of a day’s ladder are open-ended: agreatermarket has abracket_lowand no high, and alessmarket the reverse.
The station codes follow the city: New York settles on CLINYC, Chicago on CLIMDW, Austin on
CLIAUS. They are CLI-prefixed climate-report identifiers rather than the airport codes you
might expect, which is its own small reason to take the value from the data rather than assume it.
Reading a day’s ladder
One city’s daily high is not one market — it is a ladder of brackets covering the plausible range,
and they are mutually exclusive. Sorting a day’s rows by bracket_low gives you the market’s whole
probability distribution for that city’s high temperature, which is a more useful object than any
single price. Where your forecast sits inside that distribution is the trade.
Two practical notes. implied_probability is null rather than zero on a bracket that has never
traded and has no resting orders — 0 would assert the market calls that temperature impossible,
which is a stronger claim than silence, and it matters here because a ladder’s outer brackets are
frequently untraded. And close_time is when trading stops, not when the temperature is measured;
the Miami row above closes at 05:00 UTC on 8 September for a 7 September high.
Running it daily
Daily-high markets are created fresh each day, so this is a scheduled run rather than a one-off.
Set the series you follow, run it each morning, and key on market_id — Kalshi’s tickers embed the
date (KXHIGHMIA-26SEP07-B86.5), so they are stable within a day and never collide across days.
At $0.0015 per market, a run covering three cities’ full ladders is a few cents. A run that matches nothing costs nothing.
Where this does not help
If you follow one city and want today’s number, open Kalshi’s own site — it is free, and it is faster than any of this. The parsing above earns its place when you are following many cities, or keeping history, or joining market-implied probabilities to your own forecast data in bulk.
And this actor reads only what Kalshi publishes. It does not forecast weather, it does not tell you which side of a bracket to take, and it has no opinion about either.
Related
The full how-to guide covers the rest of the input, including reading Polymarket alongside Kalshi so the same question’s price on both venues lands in one table.
The actor itself — Kalshi & Polymarket Prediction Market Odds Scraper — lists its live health, its nightly canary record and its current price.
For a different kind of forecast entirely, the Google Ads Transparency Center & Competitor Ad Scraper reads what advertisers are betting on with their budgets rather than what traders are betting on with theirs.
Last updated 2026-09-07