Historical weather and climate: 100+ years of station data, normals, extremes, and trends.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Returns observations with 1991–2020 baseline comparisons at daily, weekly, or monthly granularity for a location and period. <br><b>When to use:</b> Graph or tabulate recent anomalies at a location for a specific period — e.g. 'how did last month compare to normal?' <br><b>Date format:</b> YYYYMMDD for ymd; use groupby (day/week/month) to control granularity. For 'last week' use YYYYMMDD of 7 days ago. For 'last month' use YYYYMM of prior month. <br><b>Performance:</b> Computed on demand; moderate speed. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Use after /anomalies or /breaking. Identifies a city of interest; provides per-day/week detail for drill-down. Combine groupby=DAY/FULL_DAY with a recent date range for 'recent days with departure from normal' queries. <br><b>Augment:</b> Provides the per-period anomaly series for prose ('temperatures were above normal for 12 of the past 14 days'). Returns: loc, ts, vals, N, vals_ts, baseline.
End of period (YYYY[MMDD])
Start of period (YYYY[MMDD])
Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport
Unique Location Identifier
Latitude,Longitude ex: 40.78,-73.97
Period Type [ MONTH | YEAR | WEEK | DAY | FULL_DAY | FUTURE_DAY] (default: FULL_DAY)
Observed period (default: 1)
Tool list last changed Oct 23, 2026.
Returns observations with 1991–2020 baseline comparisons at daily, weekly, or monthly granularity for a location and period. <br><b>When to use:</b> Graph or tabulate recent anomalies at a location for a specific period — e.g. 'how did last month compare to normal?' <br><b>Date format:</b> YYYYMMDD for ymd; use groupby (day/week/month) to control granularity. For 'last week' use YYYYMMDD of 7 days ago. For 'last month' use YYYYMM of prior month. <br><b>Performance:</b> Computed on demand; moderate speed. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Use after /anomalies or /breaking. Identifies a city of interest; provides per-day/week detail for drill-down. Combine groupby=DAY/FULL_DAY with a recent date range for 'recent days with departure from normal' queries. <br><b>Augment:</b> Provides the per-period anomaly series for prose ('temperatures were above normal for 12 of the past 14 days'). Returns: loc, ts, vals, N, vals_ts, baseline.
| Argument | Type | Description |
|---|---|---|
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| ymd_end* | string | End of period (YYYY[MMDD]) |
| ymd_start* | string | Start of period (YYYY[MMDD]) |
| period_type | string | Period Type [ MONTH | YEAR | WEEK | DAY | FULL_DAY | FUTURE_DAY] (default: FULL_DAY) |
| observed_period | string | Observed period (default: 1) |
{
"type": "object",
"required": [
"ymd_start",
"ymd_end"
],
"properties": {
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"ymd_end": {
"type": "string",
"description": "End of period (YYYY[MMDD])"
},
"ymd_start": {
"type": "string",
"description": "Start of period (YYYY[MMDD])"
},
"period_type": {
"type": "string",
"description": "Period Type [ MONTH | YEAR | WEEK | DAY | FULL_DAY | FUTURE_DAY] (default: FULL_DAY)"
},
"observed_period": {
"type": "string",
"description": "Observed period (default: 1)"
}
}
}Returns precomputed anomalous observations for locations in a given time period and scope. <br><b>When to use:</b> Survey anomalous weather at regional or global scale quickly without specifying individual cities. <br><b>Date format:</b> YYYY[MM[DD]]: YYYY for annual anomalies (scope=year), YYYYMM for monthly (scope=month), YYYYMMDD for weekly or daily (scope=week/day). <br><b>Performance:</b> Fast — retrieves precomputed data. <br><b>Prerequisites:</b> None; global or country-filtered. Use /countries for country IDs. <br><b>Investigate:</b> Good early call to identify which locations experienced anomalies before drilling into specifics with /anom or /dailycomp. <br><b>Augment:</b> Use for a first-pass global scan to identify story-worthy anomalies before fetching per-location detail. Returns: anomalies, anomaly.locid, anomaly.lat, anomaly.long, anomaly.obs_start, anomaly.obs_end, anomaly.obs_dur, anomaly.base_start, anomaly.base_end, anomaly.base_dur, anomaly.obs_period, anomaly.base_period, anomaly.outliers, outlier.obs_metric, outlier.percentile, outlier.obs_N, outlier.obs_X, outlier.base_N, outlier.base_X, outlier.obs_val, outlier.base_val, outlier.base_mean, outlier.base_stddev, outlier.min, outlier.max, outlier.max_key, outlier.min_key, outlier.obs_min_key, outlier.obs_max_key.
| Argument | Type | Description |
|---|---|---|
| z | string | Minimum avg std-devs departure from mean (default: 0) |
| ymd* | string | Time Period YYYY[MMDD] |
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| locid | string | Unique Location Identifier |
Given a single week, month, or day, ranks locations whose weather best matches a set of criteria (most optional criteria met first; all MUST criteria satisfied by every result). Filter by lat/lon+radius or countries. <br><b>When to use:</b> Answer 'where has the best weather for week/month/day X?' <br><b>Date format:</b> scope=day + time=YYYYMMDD (forecast); scope=week + time=MMDD; scope=month + time=MM. Defaults: week of today+14, month today+1, day today+1. <br><b>Performance:</b> Filter by area/countries to keep fast. <br><b>Prerequisites:</b> None; supply lat/lon+radius_km or a country list. <br><b>Investigate:</b> Rank places for a given time window. scope=day uses forecasts. <br><b>Augment:</b> Find the best destinations for a target week/month. <br><b>Notes:</b> Every criterion metric name is literal and fully qualified: the 'avg:' prefix, then the metric base (observation metrics keep their 'obs.' segment), then the attribute — e.g. avg:max_t.p50, avg:obs.rain.sum, avg:obs.is_rain.count. Dropping 'avg:' or 'obs.' is an error; the criteria parameter below lists every valid name. scope=day queries forecasts; week/month query the 1996-2025 historical baseline. Returns: scope, time, baseline, results, locid, location, criteria_met, criteria_met_count, record.
| Argument | Type | Description |
|---|---|---|
| time | string | YYYYMMDD (day), MMDD (week), or MM (month) |
| scope | string | day | week | month (default: week) |
| ctryid | string | Comma-separated ISO country codes (mutually exclusive with latlon) |
| latlon | string | Latitude,Longitude for area search ex: 40.78,-73.97 |
Given a location, ranks the weeks or months whose historical climatology best matches a set of weather criteria (most optional criteria met first; all MUST criteria satisfied by every result). <br><b>When to use:</b> Answer 'when is the best time to visit X for weather like Y?' Choose when_type=week or month over the 1996-2025 baseline. <br><b>Date format:</b> when_type: week|month|day. Historical basis only for week/month. <br><b>Performance:</b> Sub-second per location. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Rank a location's calendar by weather suitability. For a specific upcoming day's forecast, use /api/anom with period_type=FUTURE_DAY. <br><b>Augment:</b> Find the typical best window for an activity at a place. <br><b>Notes:</b> Every criterion metric name is literal and fully qualified: the 'avg:' prefix, then the metric base (observation metrics keep their 'obs.' segment), then the attribute — e.g. avg:max_t.p50, avg:obs.rain.sum, avg:obs.is_rain.count. Dropping 'avg:' or 'obs.' is an error; the criteria parameter below lists every valid name. For daily forecasts use /api/anom (period_type=FUTURE_DAY). Weekly/monthly forecasts are planned. Returns: location, baseline, when_type, results, time, criteria_met, criteria_met_count, record.
| Argument | Type | Description |
|---|---|---|
| name | string | Location name, e.g. New York |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| baseline | string | Baseline year range YYYY-YYYY (default: 1996-2025) |
Returns anomalous weather conditions (breaking news) across the world or specified countries in the very recent past (observations) or immediate future (forecast). <br><b>When to use:</b> First call when looking for current or upcoming notable weather events globally or by country. <br><b>Date format:</b> No date params — always returns the most recent ~3 days of observations (breaking_type=obs) or next 7 days of forecast (breaking_type=forecast). <br><b>Performance:</b> Fast — retrieves precomputed anomaly snapshots. <br><b>Prerequisites:</b> Use /countries to get country IDs for filtering. <br><b>Investigate:</b> Start here for any 'what's happening right now?' or 'what's forecast this week?' query; follow up with /anom or /dailycomp for per-location detail. <br><b>Augment:</b> Primary source for identifying breaking weather news stories globally; use ctryid to narrow scope by country. Returns: anomalies, anomaly.locid, anomaly.name, anomaly.city, anomaly.country, anomaly.lat, anomaly.lon, anomaly.geohash, anomaly.elevation, anomaly.obs_start, anomaly.obs_end, anomaly.obs_dur, anomaly.pt, anomaly.anomalies, outlier.obsm, outlier.comps, comp.obsm_f, comp.oq, comp.bq, comp.scope, comp.val, comp.bval, comp.min, comp.max, comp.med, comp.mean, comp.std, comp.min_dt, comp.max_dt, comp.intensity, comp.intensity_f, comp.rp, comp.summary, comp.period, comp.base_N, comp.N, comp.ut, comp.start, comp.end.
| Argument | Type | Description |
|---|---|---|
| ctryid | string | Comma-separated country codes to filter (as returned by /api/countries). Leave empty for global results. |
| breaking_type | string | Type of anomaly source. Values: obs (recent observations, ~last 3 days), forecast (upcoming 0-7 days). (default: obs) |
| metric_category | string | Filter by metric category. Values: A (All), T (Temperature), P (Precipitation), H (Humidity/Dew Point), W (Wind). (default: A) |
Returns monthly distributions of selected metrics for locations compared against a baseline period. <br><b>When to use:</b> Compute normalized and absolute deviations from a baseline, inter-annual and intra-annual variations within months and seasons. Check base_N and obs_N to assess data completeness. <br><b>Date format:</b> obs_years as YYYY or YYYY-YYYY range; months as MM or MM-MM (e.g. '06', '06-08', 'All' for annual). <br><b>Performance:</b> Bulk query — can be slow for global or large-area queries. Filter with locids, lat_lon/radius_km, or countries. <br><b>Prerequisites:</b> Use /location to obtain locids first for point queries. <br><b>Investigate:</b> Use to compare a recent season or year against the long-term baseline across many locations simultaneously. Combine with /climatetrends for trend context. <br><b>Augment:</b> Identifies which locations had the most anomalous season compared to their historical distribution. <br><b>Notes:</b> Metric format: 'max_t' = distribution of daily Maximum Temperature over the period; 'max_t.means' = distribution of annual means of max_t (1 value per year); 'rain_sum' (accumulations) and 'obs.is_thunderstorm' (counts) follow the same pattern. Returns: results, comp.locid, comp.geohash, comp.lat, comp.lon, comp.elev, comp.area, comp.country, comp.src_type, comp.metric, comp.obs_years, comp.base_years, comp.month, comp.obs_N, comp.base_N, comp.obs, comp.base, comp.obs.{q} / comp.base.{q}.
| Argument | Type | Description |
|---|---|---|
| locids | string | Comma-separated location IDs (as returned by /api/location). Example: '037720_99999,432950_99999'. |
| months | string | Single month ('06') or hyphenated range ('MM-MM'). Seasons: '12-02' (Dec-Feb), '12-03' (Dec-Mar), '10-11' (Oct-Nov), '03-05' (Mar-May), '06-08' (Jun-Aug), '06-09' (Jun-Sep). Use 'All' for annual. Example: '06' or '06-09'. |
| lat_lon |
Returns monthly timeseries of selected climate trend metrics for one or more locations, suitable for long-term trend analysis. <br><b>When to use:</b> Retrieve long-term monthly timeseries for statistical trend analysis across any number of locations including globally. Use num_years and avg_N to filter sparse records. <br><b>Date format:</b> years as YYYY- range (e.g. '1975-' for 1975 to present); months as MM or MM-MM range (e.g. '06' for June, '06-08' for June–August, 'All' for annual). <br><b>Performance:</b> Bulk query — can be slow for global or many-location queries. Filter with locids, lat_lon/radius_km, or countries to improve speed. <br><b>Prerequisites:</b> Use /location to obtain locids first for point queries. <br><b>Investigate:</b> Use for global or regional trend analysis. Metric name format: 'agg_func:metric_id.attribute' (e.g. 'avg:max_t.p50'). Check num_years to confirm data completeness before citing a trend. <br><b>Augment:</b> Backs trend claims with long-term data across many locations (e.g. 'temperatures rising across Southeast Asia'). <br><b>Notes:</b> Example metrics: avg:max_t.p50, avg:obs.temp.mean, sum:obs.is_rain.count. See /api/metrics for full list. Returns: results, trend.locid, trend.geohash, trend.lat, trend.lon, trend.elev, trend.area, trend.country, trend.src_type, trend.metric, trend.years, trend.month, trend.num_years, trend.avg_N, trend.mvals, trend.mvals.xvals, trend.mvals.yvals_by_metric.
| Argument | Type | Description |
|---|---|---|
| avg_N | string | Minimum average number of days per period for years with data. (default: 0) |
| years | string | Year range string. Known values: '1975-' (data from 1975 onward). (default: 1975-) |
| locids | string | Comma-separated list of location IDs (as returned by /api/location). Example: '037720_99999,432950_99999'. Use locids for point queries. |
Compares a location's observed weather period against the corresponding periods in a historical baseline distribution. <br><b>When to use:</b> Quantify how extreme a specific period was across all metrics at once — e.g. how anomalous was March 2025 at New York vs the 1991–2020 baseline. <br><b>Date format:</b> YYYY[MM[DD]]: YYYYMMDD for a specific day or short window (period_type DAY/WEEK), YYYYMM for a month (period_type MONTH), YYYY for an annual comparison (period_type YEAR). <br><b>Performance:</b> Computed on demand; fast for short periods. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Best for 'how unusual was [period] at [location]?' — returns percentile and z-score across all metrics simultaneously. Set baseline_offset=1 for the standard 1991–2020 baseline. <br><b>Augment:</b> Provides the precise statistical framing ('the hottest March in 30 years') before describing the anomaly in prose. Returns: comparisons, comparison.locid, comparison.lat, comparison.long, comparison.obs_start, comparison.obs_end, comparison.obs_dur, comparison.base_start, comparison.base_end, comparison.base_dur, comparison.obs_period, comparison.base_period, comparison.outliers, outlier.obs_metric, outlier.percentile, outlier.obs_N, outlier.obs_X, outlier.base_N, outlier.base_X, outlier.obs_val, outlier.base_val, outlier.base_mean, outlier.base_stddev, outlier.min, outlier.max, outlier.max_key, outlier.min_key, outlier.obs_min_key, outlier.obs_max_key.
| Argument | Type | Description |
|---|---|---|
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
Returns countries with their canonical country IDs used in all other API calls. <br><b>When to use:</b> Resolve country names to canonical IDs, or obtain the full list of supported countries. This list rarely changes. <br><b>Performance:</b> Fast — static data; safe to cache across calls. <br><b>Prerequisites:</b> None. <br><b>Investigate:</b> Call once if country-level filtering is needed; cache the result for the session. <br><b>Augment:</b> Fetch country IDs before making country-filtered calls to /anomalies or /breaking. Returns: countries, country.ctryid, country.name, country.regions.
| Argument | Type | Description |
|---|---|---|
| ctryid | string | Country Id |
{
"type": "object",
"required": [],
"properties": {
"ctryid": {
"type": "string",
"description": "Country Id"
}
}
}Returns per-day observed values with percentiles and z-scores vs a sliding N-day window over a historical baseline. <br><b>When to use:</b> Graph heatwaves, cold spells, and other streaks by showing daily departures from normal. Also compare two separate periods or locations using z-scores or percentiles for normalized severity. <br><b>Date format:</b> YYYYMMDD for ymd_start and ymd_end. Keep ranges ≤30 days for fast response; up to 90 days is feasible. <br><b>Performance:</b> Computed on demand; slower for long date ranges. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Best for detailed day-by-day anomaly investigation once approximate dates and location are known. Use separate calls for two periods to compare heatwave severity via z-score. Do NOT use for ranking top-N events across years — call /events with criteria for that and post-process the response. <br><b>Augment:</b> Provides the daily series needed to describe the arc of a heatwave or cold snap in a news narrative. Returns: locid, lat, lon, dates, num_years, avg_coverage, metrics, metrics.{key}.values, metrics.{key}.pcts, metrics.{key}.sigmas, metrics.{key}.p1 … p99, metrics.{key}.bmin / bmax, metrics.{key}.mean, metrics.{key}.stddev, metrics.{key}.coverage.
| Argument | Type | Description |
|---|---|---|
| name | string | Location name, e.g. New York |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| window | string | Sliding window days (3-7) (default: 7) |
| ymd_end |
How often a compound daily weather condition happens, per location: for every location in an area, the average number of days per year that met all the criteria, with the count, the days that had data, and the percentage. <br><b>When to use:</b> Map where a condition is common or rare, e.g. 'where are summer days between 20 and 30 C most frequent' or 'where did heatwave nights occur in the last five summers'. <br><b>Date format:</b> Either ymd_start and ymd_end (YYYYMMDD, at most 31 days) or year_start, year_end with optional mm_dd_start and mm_dd_end for a season across years (at most 5 years). Defaults to the last 30 days. <br><b>Performance:</b> Full counts need a geo scope (ctryid, latlon, or a bbox of at most continent size) or a date range of at most 30 days. Anything wider is sampled automatically to about 200 locations (see sample), because an open-ended multi-year count takes over a minute; pass sample=0 to be refused instead. With a geo scope, year windows up to 5 years run fast. <br><b>Prerequisites:</b> None; without a geo scope, windows over 30 days are sampled. <br><b>Investigate:</b> Use min_count_pct to keep only locations where the condition is frequent, or min_count 0 with max_count to find where it is rare or never happens. <br><b>Augment:</b> Support statements about how common a condition is across a region with avg_count and count_pct. <br><b>Request format:</b> HTTP GET, query parameters; criteria is URL-encoded JSON. Example: /api/dailycountbyloc?token=TOKEN&ctryid=IN&year_start=2021&year_end=2025&mm_dd_start=0601&mm_dd_end=0831&criteria=[{"metric":"max_t","lb":35}] <br><b>Response format:</b> JSON. results is a list of objects, one per location, highest avg_count first: locid, lat, lon, city_name, country, avg_count, count, days_with_data, count_pct. sample is null unless the result was sampled (then auto is true when the server sampled on its own). <br><b>Notes:</b> avg_count is matched days divided by years in the window; count_pct divides by the days that actually had data, so station gaps do not read as absence. Returns: criteria_desc, time, total_days_per_year, num_years, total_days_found, count, truncated, results, locid, lat, lon, city_name, country, avg_count, days_with_data, count_pct, sample, note, error.
| Argument | Type | Description |
|---|
For one location, the number of days per year that met all the criteria within a month-day window, for every year with data, plus a trend line (days per decade) with R squared and p-value. <br><b>When to use:</b> Answer 'is this condition becoming more frequent here?', e.g. hot summer days or frost nights per year over decades. <br><b>Date format:</b> The window is mm_dd_start and mm_dd_end (MMDD), or the month-days of ymd_start and ymd_end; years are not a filter, every year with data is returned. A window crossing the year end (1201 to 0228) belongs to the year it starts in. Defaults to the month-days of the last 30 days. <br><b>Performance:</b> Fast: filtered to one location in the index. <br><b>Prerequisites:</b> locid from /api/location (ICAO and WMO ids also resolve). <br><b>Investigate:</b> Compare the trend across nearby locations, or across absolute and percentile criteria for the same condition. <br><b>Augment:</b> Back 'more frequent than it used to be' claims with slope_per_decade and its p_value. <br><b>Request format:</b> HTTP GET, query parameters; criteria is URL-encoded JSON. Example: /api/dailycountbyyear?token=TOKEN&locid=725030_14732&mm_dd_start=1201&mm_dd_end=0228&criteria=[{"metric":"min_t","ub":-10}] <br><b>Response format:</b> JSON. years, counts, days_with_data and in_trend are parallel lists of equal length: index i describes the season starting in years[i]. trend is an object (slope_per_decade, r_squared, p_value, n) or null with under 3 usable years. <br><b>Notes:</b> Years with under 80% of the window covered are listed (in_trend false) but excluded from the trend. Returns: locid, location, criteria_desc, mm_dd_start, mm_dd_end, total_days_per_year, years, counts, days_with_data, in_trend, trend, note, error.
| Argument | Type | Description |
|---|---|---|
| locid* | string | Location id from /api/location, e.g. 724940_23234 |
| ymd_end | string | Alternative to mm_dd_end: a day whose MMDD ends the window |
How good Weathersight's own forecast was at one location, at one or more lead times: a daily series of the observed value, the forecast made lead days earlier, and RMSE, MSE, ACC and ETS over a trailing window ending on each day. <br><b>When to use:</b> Answer 'how reliable has the 3-day forecast been here lately?' or 'how fast does skill decay from 1 to 7 days ahead?'. This scores the forecast Weathersight serves (after model choice and bias correction); fcastevalbylocation scores the raw vendor models. <br><b>Date format:</b> start_date and end_date are YYYYMMDD, at most 31 days apart (forecast retention). Defaults to the 31 days ending yesterday. <br><b>Performance:</b> Fast: two small lookups for one location, whatever the number of lead_times. <br><b>Prerequisites:</b> locid from /api/location (ICAO and WMO ids also resolve). <br><b>Investigate:</b> Ask for lead_times=1,3,7 at once to see how skill decays. <br><b>Augment:</b> Quote recent forecast error at the article's location. <br><b>Request format:</b> HTTP GET, query parameters. Example: /api/dailyfcasteval?token=TOKEN&locid=725030_14732&metric=max_t&lead_times=1,3,7&start_date=20261001&end_date=20261020&time_window=5 <br><b>Response format:</b> JSON. lead_times is the ascending list of leads served (the FIRST axis of every per-lead series); xvals is the list of dates (the SECOND axis). yvals.obs is ONE list aligned with xvals (observations do not depend on lead). yvals.forecast, yvals.rmse, yvals.mse, yvals.acc and yvals.ets are each a list of lists: yvals.rmse[i][j] is the RMSE for lead_times[i] over the window ending on xvals[j]. Every inner list has one entry per xvals date, null where there is no value. <br><b>Notes:</b> ETS is reported for rain, snow and hourly rain only, and rain has no ACC (it carries no z-score). Scores need at least 3 days with both a forecast and an observation in the window. Returns: location, metric, lead_times, time_window, xvals, yvals, note, error.
| Argument | Type | Description |
|---|---|---|
| locid* | string | Location id from /api/location, e.g. 724940_23234 |
One day's weather across an area: every location matching the criteria on that date, with one or more metrics' values, anomalies (z) and percentiles. Observed days, or Weathersight's forecast for the next 7 days. The result is columnar: columns names each position, and every entry of rows is a list aligned with columns (null where absent). <br><b>When to use:</b> Map a single day, e.g. 'where was it over 40 C yesterday' or 'where is tomorrow forecast to be unusually humid'. <br><b>Date format:</b> date is YYYYMMDD. Observations exist up to yesterday; forecasts from tomorrow to 7 days ahead, and are kept for 31 days. <br><b>Performance:</b> Fast: at most one row per location. <br><b>Prerequisites:</b> None. <br><b>Investigate:</b> Pair with dailycountbyloc to show whether today's extremes are common there. <br><b>Augment:</b> Report the hottest or wettest places on the article's date. <br><b>Request format:</b> HTTP GET, query parameters. Example: /api/dailyweather?token=TOKEN&date=20261019&metric=max_t,min_t&ctryid=IN&sample=200 <br><b>Response format:</b> JSON, columnar. columns names each position once; rows is a list of lists, one per location, each aligned with columns, null where absent. columns are locid, city_name, country, lat, lon, final, then per requested metric m: m, m.z (absent for rain and snow) and m.ptile. units maps each metric to its unit. Rows are sorted by the first metric, highest first. <br><b>Notes:</b> For src=fcast, lead is days from the forecast's issue to the date. It defaults to date minus today plus 1, clamped to 1 to 7: the newest forecast from yesterday's run (today plus 7 exists only once today's run has landed). Rows with final false are yesterday's preliminary values, before the official daily record merged. Returns: date, src, lead, metrics, units, criteria_desc, count, truncated, columns, rows, sample, note, error.
| Argument | Type | Description |
|---|---|---|
| src | string | obs (observed) or fcast (Weathersight's forecast) (default: obs) |
| bbox |
Returns cumulative degree-day indicators (heating/cooling/growing) for a location and period using ERA5 reanalysis data. <br><b>When to use:</b> Estimate energy demand anomalies or agricultural stress in a recent or upcoming period. <br><b>Date format:</b> YYYYMMDD for ymd_start and ymd_end. Maximum interval is 14 days per call. <br><b>Performance:</b> Computed on demand using ERA5; moderate speed. Keep intervals to ≤14 days. <br><b>Prerequisites:</b> Requires lat/lon directly — no locid needed. <br><b>Investigate:</b> Use when the query involves power grid strain or energy demand. For forecast context, use future ymd dates. <br><b>Augment:</b> Adds quantitative energy-demand context to heatwave or cold snap stories. Returns: meta, indicators.
| Argument | Type | Description |
|---|---|---|
| unit | string | Degree days as measured in F|C (default: C) |
| latlon* | string | Latitude,Longitude ex: 40.78,-73.97 |
| ymd_end | string | End of period (YYYYMMDD) |
| ymd_start | string | Start of period (YYYYMMDD) |
| indicators | string | Comma separated list of indicator names. ['hdd'|'cdd'|'wbcdd'|'gdd] (default: hdd,cdd,wbcdd) |
| base_temp_C | string | Base temperature in °C for all indicators (default: 18.3) |
Finds days matching one or more compound weather conditions (e.g. hot + humid, rainy + windy) for a location. Returns up to 5000 most-recent matching events plus the total count. <br><b>When to use:</b> Count occurrences of compound weather events across years, study extreme or unusual day combinations, or identify streaks of such events. <br><b>Date format:</b> year_start/year_end as YYYY; month_day_start/month_day_end as MMDD for seasonal filtering within each year. <br><b>Performance:</b> Computed on demand; returns up to 5000 most-recent matches. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Use when the query involves compound conditions — 'how many days had both extreme heat and thunderstorms?' Combine numeric and condition metrics with AND/OR logic. <br><b>Augment:</b> Provides event frequency counts for framing rarity in a story ('only 3 such days in the past 20 years'). <br><b>Notes:</b> Numeric metrics: cloudiness, dewp, dpd, gust, hail_size, hi, insolation, max_dewp, max_dpd, max_hi, max_t, max_wbgt, max_wbulb, max_wind, min_dewp, min_t, min_wchill, rain, rain_12hr, rain_1hr, rain_3hr, rain_6hr, snow, snow_12hr, snow_1hr, snow_3hr, snow_6hr, snow_depth, temp, visibility, wbgt, wbulb, wchill, wind, wind_dir. Condition metrics: is_drizzle, is_dust, is_duststorm, is_fog, is_frozen_rain, is_funnel_cloud, is_hail, is_haze, is_heavy_rain, is_heavy_snow, is_ice_pellets, is_mist, is_rain, is_smoke, is_snow, is_squall, is_thunderstorm. Do not specify lower or upper bound when dealing with absolutes unless it is required. Sensible defaults are populated automatically and if the values provided fall out of those, the request is deemed invalid. Returns: locid, name, total_events, events, datestamp, max_t, max_t_complete, min_t, min_t_complete, rain, rain_complete, snow, temp, dewp, wind, max_wind, gust, conditions, criteria_met.
| Argument | Type | Description |
|---|---|---|
| name | string | Location name, e.g. New York |
| locid | string |
Returns extreme value analysis (return periods) for a specified location and metric. <br><b>When to use:</b> Quantify the statistical rarity of a record or near-record value. Typically called after other APIs establish that an observation is anomalous. <br><b>Performance:</b> Computed on demand; moderate speed. <br><b>Prerequisites:</b> Use /location to obtain a locid first. Prefer level='area' over 'city' for better recall and longer period of record. <br><b>Investigate:</b> Use after /recentextremes or /anom establishes a high value; provides the return-period framing ('a once-in-50-year event'). <br><b>Augment:</b> Provides the statistical rarity framing needed for record-event stories. Try both src_types 'Obs' and 'ERA5' for non-US locations to account for discontinuous station records. Returns: locid, period, months_covered, window_size, N, coverage_pct, results, result.metric, result.value, result.return_period.
| Argument | Type | Description |
|---|---|---|
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| level | string | Aggregation level: city (single station) | area (nearby stations pooled). Use 'area' to improve period of record. (default: area) |
| locid | string | Unique Location Identifier |
| month | string | Two-digit month filter (e.g. '06' for June). Leave empty for all months. |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
Scores how well each forecast model actually performed at each of many locations, by comparing what the models predicted against what was then observed. Returns one score matrix per location, models by evaluation metrics, for a single weather metric at a single lead time, plus the winning model per location. <br><b>When to use:</b> Answer 'which forecast model is most accurate here?' at scale — to map the best model by region, to check whether a specific model is worth using over the default blend, or to compare physical and AI models across the world. <br><b>Date format:</b> ymd_start and ymd_end are YYYYMMDD and inclusive. Inclusive day range as YYYYMMDD. Defaults to the 14 days ending yesterday; today is never included because it has not been verified yet. At most 180 days, which is also how much history the index retains. <br><b>Performance:</b> Filter by ctryid, latlon+radius_km or a small sample_pct to keep it fast; a global 5 percent sample over 14 days is a few hundred locations. <br><b>Prerequisites:</b> None. Supply locid, name, latlon+radius_km, ctryid, or nothing at all with a sample_pct for an unbiased global sample. <br><b>Investigate:</b> Use this to find where a model is strong or weak. Ask for one metric and one lead_time at a time; compare models by reading across each row of evals, and use winners for the answer at a glance. <br><b>Augment:</b> Back a claim about forecast reliability with the measured error of the named model at that place over the recent past. <br><b>Notes:</b> Forecasts come from Open-Meteo. Lead time is the number of days ahead the forecast was issued, so lead_time 1 is yesterday's forecast for today; only the indexed lead times are available. The WN2 model is an ensemble mean, which is smoother than the deterministic models and so tends to score slightly better on mae and rmse and slightly worse on extremes. A score is null, never zero, when its sample was too small to measure: fewer than 5 verified days for mae, rmse, mse, bias and ets, or fewer than 10 for acc. Returns: metric, unit, lead_time, ymd_start, ymd_end, days, models, eval_metrics, sample_pct, sample_pct_effective, seed, buckets, count, scanned, truncated, note, error, results, locid, location, evals, n, n_days, error_basis, winners.
| Argument | Type | Description |
|---|
Scores how well each forecast model performed at ONE location, across several forecast lead times and across a sliding time window. Shows both how fast accuracy decays as the forecast reaches further ahead, and how accuracy at a given lead time has varied over recent weeks. <br><b>When to use:</b> Answer 'how far ahead can I trust the forecast here?' or 'has the forecast been unusually poor here lately?' Use fcastevalbygroup instead to compare many locations at one lead time. <br><b>Date format:</b> ymd_start and ymd_end are YYYYMMDD and inclusive. Inclusive day range as YYYYMMDD. Defaults to the 14 days ending yesterday; today is never included because it has not been verified yet. At most 180 days, which is also how much history the index retains. <br><b>Performance:</b> Fast: one location. The cost grows with the number of lead times and the length of the range. <br><b>Prerequisites:</b> A location: locid from /api/location, or name, or latlon. <br><b>Investigate:</b> Ask for several lead_times at once (e.g. 1,3,5,7) to get the skill-decay curve in one call. Set window to get a moving average and see the trend over time rather than one number. <br><b>Augment:</b> Quantify how reliable a forecast for this place actually is at the lead time being written about. <br><b>Notes:</b> Forecasts come from Open-Meteo. Lead time is the number of days ahead the forecast was issued; only the indexed lead times are available. A score is null, never zero, when its sample was too small to measure: fewer than 5 verified days for mae, rmse, mse, bias and ets, or fewer than 10 for acc. Returns: locid, location, metric, unit, ymd_start, ymd_end, days, window, num_windows, windows, lead_times, models, eval_metrics, scanned, count, truncated, error, evals, n, n_days, error_basis.
| Argument | Type | Description |
|---|---|---|
| name | string | Place name, e.g. 'San Francisco'. Ignored if locid is set |
| locid | string | Location id from /api/location, e.g. 725030_14732 |
Returns meta information for a location given a name, locid, or lat/lon. <br><b>When to use:</b> Obtain the canonical locid needed by all location-specific API calls. Typically the first call in any workflow. <br><b>Performance:</b> Fast — precomputed lookup. <br><b>Prerequisites:</b> None — this is the entry point. <br><b>Investigate:</b> Call first whenever the user names a city or region; cache the locid for all subsequent calls in the session. Use 'City, State Country' format (e.g. 'Austin TX USA'). <br><b>Augment:</b> Resolve city names from the article to locids early; reuse them throughout augmentation to avoid repeated name lookups. Returns: name, locid, friendly, lat, long, country, icao, elevation, timezone, wmo.
| Argument | Type | Description |
|---|---|---|
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
{
"type": "object",
"required": [],
"properties": {
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
}
}
}Returns the catalogue of all supported weather metric identifiers with units and categories. <br><b>When to use:</b> Resolve metric IDs to human-friendly names, units, and categories. Call once and cache per session. <br><b>Performance:</b> Fast — static data; safe to cache for the lifetime of a session. <br><b>Prerequisites:</b> None. <br><b>Investigate:</b> Call once at session start; use metric.id as a lookup key throughout the conversation. <br><b>Augment:</b> Translate metric IDs into readable labels for article text and chart axes. Returns: metrics, metric.id, metric.name, metric.cat, metric.type, metric.dist.
No arguments.
{
"type": "object",
"required": [],
"properties": {}
}Returns recent weather records (all-time or period-of-record extremes) for the world or specified countries. <br><b>When to use:</b> Find which locations have broken or nearly broken records in a recent date window. Set history_years ≥ 15 to ensure a meaningful period of record. <br><b>Date format:</b> YYYYMMDD for ymd_start and ymd_end. Keep windows ≤ 3 months per call for reasonable performance. <br><b>Performance:</b> Computed on demand; slower for large date ranges. Start with scope='monthly' or 'yearly'; fall back to 'weekly' for near-records. <br><b>Prerequisites:</b> Use /countries for country IDs; use /location for locids. <br><b>Investigate:</b> Use after /breaking identifies a record-breaking event to get precise extreme-value context. For US locations use period_type='DAY'; for non-US use 'FULL_DAY'. Hourly-derived metrics (wet bulb, wind gusts) for non-US require period_type='DAY'. <br><b>Augment:</b> Provides the 'record' framing for a story — 'hottest day ever recorded at this station.' Note: FULL_DAY and DAY expose different metric sets. Returns: results, extreme.locid, extreme.name, extreme.country_code, extreme.lat, extreme.lon, extreme.elev, extreme.period_type, extreme.metric, extreme.ymd, extreme.anomaly_type, extreme.scope, extreme.value, extreme.history_years.
| Argument | Type | Description |
|---|---|---|
| scope | string | Record scope. Values: month (monthly records), week (weekly records), year (annual records). (default: month) |
| ctryid | string | Comma-separated country codes to filter (as returned by /api/countries). |
| metrics | string | Applicable metrics. For period_type DAY: ('temp.max','temp.min', 'temp.mean', 'rain.mean', 'snow.mean', 'dewp.mean', 'wbulb.max', 'heatindex.max', 'wbgt.max', 'dpd.max','gust.max','wind.max','rainh.max')<br>For period_type FULL_DAY/FUTURE_DAY: ('max_t.mean','min_t.mean','temp.mean','rain.mean','snow.mean','dewp.mean','max_wind'.mean) (default: max_t.mean) |
Seasonal (monthly) forecast anomalies for the next six months, with the local climatology they are measured against. Each result gives, per metric: the ERA5 baseline mean (means), its interannual standard deviation (std), the predicted anomaly (anom, in degrees C / mm / km/h) and how unusual that is, both as standard deviations (norm) and as a percentile rank among the last 30 years (perc). <br><b>When to use:</b> Answer 'will next month be hotter/wetter than normal here?' or 'where is the coming season predicted to be most unusual?' <br><b>Date format:</b> ym_start and ym_end are YYYYMM, inclusive. For a single month set both to the same value. Defaults to next month through next month + 5. <br><b>Performance:</b> Filter by locid, ctryid or latlon+radius_km to keep fast; a whole-world month slice is about 4000 rows and fits in one page. <br><b>Prerequisites:</b> None; supply locid, name, latlon+radius_km, ctryid, or nothing at all for a global query. <br><b>Investigate:</b> Rank places by how abnormal the coming months look. Use sort=perc:obs.rain.sum for rainfall and sort=norm:max_t.mean for heat. <br><b>Augment:</b> Back claims about the coming season with the predicted anomaly and how it compares with the local 30-year normal. <br><b>Notes:</b> Monthly resolution only — for daily forecasts use typicalweather. The forecast is ECMWF SEAS5; its anomalies are relative to SEAS5's own 1991-2020 model climatology, so means + anom approximates rather than equals the predicted absolute. Returns: ym_start, ym_end, baseline, metrics, count, truncated, note, error, next_cursor, results, locid, location, ym, run_ymd, basis_type, means, std, anom, norm, perc, criteria_met, criteria_met_count.
| Argument | Type | Description |
|---|---|---|
| name | string | Place name, e.g. 'San Francisco'. Ignored if locid is set |
| sort | string | One of: 'criteria' (most optional criteria met first), 'locid' (id order, resumable with cursor), or an attribute name to rank by how far from normal it is: 'norm:METRIC' or 'perc:METRIC', e.g. norm:obs.rain.sum. Those are the same names used in criteria, and they order most-abnormal-first in either direction — use criteria to pick a direction (e.g. lb 0 for hotter than normal only). Defaults to criteria when criteria are given, otherwise locid. |
Returns aggregated metric values as a yearly or monthly timeseries for a location. <br><b>When to use:</b> Detect long-term trends and compute statistical significance (r-squared, p-value). Best suited for multi-decade spans. <br><b>Date format:</b> mm_dd_start/mm_dd_end as MMDD (day-of-year window, not a calendar year); year_start/year_end as YYYY. Note: Use mm_dd_start/mm_dd_end as MM when months are specified and MMDD when week-level granularity is needed. When day-level info is needed use /events or /dailycomp. <br><b>Performance:</b> Computed on demand; slower for large date ranges or many metrics. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Use for trend analysis ('Is max temperature at location X increasing over decades?'). Combine with r-squared post-processing for significance. <br><b>Augment:</b> Provides decadal trend context alongside current anomalies ('temperatures have risen 1.5°C over 40 years'). Returns: locid, lat, lon, xvals, yvals.
| Argument | Type | Description |
|---|---|---|
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| groupby | string | Aggregating key: Year | Month | Week | Hour (default: Year) |
| metrics* | string | Comma separated list of tuple describing <i>aggregation function</i>:<i>metric_id</i>.<i>attribute</i> <br> ex: sum:obs.is_rain.count, avg:max_t.p99<br>agg_func = {sum,avg,min,max}. See /api/metrics for metric and attribtutes |
Returns statistical distributions of weather attributes (temperature, precipitation, wind, etc.) for a location and time period. <br><b>When to use:</b> Establish the climatological baseline — what is 'normal' for this location and period. Use before discussing anomalies. <br><b>Date format:</b> YYYY[MM[DD]]: YYYYMMDD for a specific week, YYYYMM for a month, YYYY for a seasonal or annual overview. Note: YYYYMMDD does not give info about daily obs. If a date is specified it corresponds to the week. Use /events for daily history. <br><b>Performance:</b> Computed on demand; moderate speed. Avoid date spans wider than one year. <br><b>Prerequisites:</b> Use /location to obtain a locid first. <br><b>Investigate:</b> Good for grounding anomaly claims — e.g. 'Is 35°C in July unusual for Madrid?' Check distributions before asserting extremeness. <br><b>Augment:</b> Use to provide climatological context before describing observed anomalies in an article. Returns: duration, observations, conditions, probs, pcps, means, >>.
| Argument | Type | Description |
|---|---|---|
| name | string | Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport |
| locid | string | Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| ymd_end* | string | End of period (YYYY[MMDD]) |
| hour_end | string | Hour End (00 to 24) (default: 24) |
| scope | string | Scope Type [week | month | year] |
| ctryid | string | Country IDs (comma sep) returned by /api/countries |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| metrics | string | One of metrics returned by /api/metrics. Overrides 'CAT' |
| category | string | Metrics Category[Not Available] as defined by /api/metrics |
| period_type | string | Period Type [MONTH | WEEK | YEAR | DAY | FULL_DAY | FUTURE_DAY] (default: DAY) |
| anomaly_type | string | Anomaly Type [HIGH | LOW] |
{
"type": "object",
"required": [
"ymd"
],
"properties": {
"z": {
"type": "string",
"description": "Minimum avg std-devs departure from mean (default: 0)"
},
"ymd": {
"type": "string",
"description": "Time Period YYYY[MMDD]"
},
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"scope": {
"type": "string",
"description": "Scope Type [week | month | year]"
},
"ctryid": {
"type": "string",
"description": "Country IDs (comma sep) returned by /api/countries"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"metrics": {
"type": "string",
"description": "One of metrics returned by /api/metrics. Overrides 'CAT'"
},
"category": {
"type": "string",
"description": "Metrics Category[Not Available] as defined by /api/metrics"
},
"period_type": {
"type": "string",
"description": "Period Type [MONTH | WEEK | YEAR | DAY | FULL_DAY | FUTURE_DAY] (default: DAY)"
},
"anomaly_type": {
"type": "string",
"description": "Anomaly Type [HIGH | LOW]"
}
}
}| baseline |
| string |
| Baseline year range YYYY-YYYY (default: 1996-2025) |
| criteria* | string | JSON array of criteria, passed as a string. Example: [{"metric":"avg:max_t.p50","lb":18,"ub":28,"must_have":true},{"metric":"avg:obs.rain.sum","ub":40,"must_have":true},{"metric":"avg:obs.is_rain.count","ub":6,"must_have":false}] Each element has: metric (required, one of the exact names listed below), lb and ub (optional numeric lower/upper bounds, unscaled natural units; set at least one), and must_have (true = hard filter every result must satisfy, false = optional, only used to rank results). At least one criterion with must_have=true is required. Metric names are literal and case-sensitive. Each is the prefix 'avg:' + the metric base + '.' + the attribute — for example avg:obs.rain.sum and avg:max_t.p50. Never drop the 'avg:' prefix and never drop the 'obs.' segment: 'obs.rain.sum', 'rain.sum' and 'avg:rain.sum' are all rejected. 'avg' means the mean across the baseline years for that week/month bucket. lb/ub are unscaled natural units (°C, mm, km/h, oktas, days). Percentile metrics — p1 = low tail, p50 = median, p99 = high tail: avg:max_t.p1, avg:max_t.p50, avg:max_t.p99, avg:min_t.p1, avg:min_t.p50, avg:min_t.p99, avg:obs.dewp.p1, avg:obs.dewp.p50, avg:obs.dewp.p99, avg:obs.dewph.p1, avg:obs.dewph.p50, avg:obs.dewph.p99, avg:obs.wbulb.p1, avg:obs.wbulb.p50, avg:obs.wbulb.p99, avg:obs.wbgt.p1, avg:obs.wbgt.p50, avg:obs.wbgt.p99, avg:obs.temp.p1, avg:obs.temp.p50, avg:obs.temp.p99, avg:obs.heatindex.p1, avg:obs.heatindex.p50, avg:obs.heatindex.p99 (°C); avg:obs.wind.p1, avg:obs.wind.p50, avg:obs.wind.p99 (km/h); avg:obs.cloudcover.p1, avg:obs.cloudcover.p50, avg:obs.cloudcover.p99 (oktas). Tail-percentile metrics: avg:obs.gust.p99 (km/h); avg:obs.rain.p95, avg:obs.rain.p99, avg:obs.snow.p95, avg:obs.snow.p99 (mm). Accumulation over the bucket: avg:obs.rain.sum, avg:obs.snow.sum (mm). Day-counts within the bucket: avg:obs.is_snow.count, avg:obs.is_rain.count, avg:obs.is_hail.count, avg:obs.is_thunderstorm.count, avg:obs.is_fog.count, avg:obs.is_smoke.count (days). Use exactly one of the names above as the criterion 'metric'; anything else returns an error listing the valid names. |
| radius_km | string | Radius km for area search (default: 100) |
| max_results | string | Max results (default: 100) |
{
"type": "object",
"required": [
"criteria"
],
"properties": {
"time": {
"type": "string",
"description": "YYYYMMDD (day), MMDD (week), or MM (month)"
},
"scope": {
"type": "string",
"description": "day | week | month (default: week)"
},
"ctryid": {
"type": "string",
"description": "Comma-separated ISO country codes (mutually exclusive with latlon)"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude for area search ex: 40.78,-73.97"
},
"baseline": {
"type": "string",
"description": "Baseline year range YYYY-YYYY (default: 1996-2025)"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria, passed as a string. Example: [{\"metric\":\"avg:max_t.p50\",\"lb\":18,\"ub\":28,\"must_have\":true},{\"metric\":\"avg:obs.rain.sum\",\"ub\":40,\"must_have\":true},{\"metric\":\"avg:obs.is_rain.count\",\"ub\":6,\"must_have\":false}] Each element has: metric (required, one of the exact names listed below), lb and ub (optional numeric lower/upper bounds, unscaled natural units; set at least one), and must_have (true = hard filter every result must satisfy, false = optional, only used to rank results). At least one criterion with must_have=true is required. Metric names are literal and case-sensitive. Each is the prefix 'avg:' + the metric base + '.' + the attribute — for example avg:obs.rain.sum and avg:max_t.p50. Never drop the 'avg:' prefix and never drop the 'obs.' segment: 'obs.rain.sum', 'rain.sum' and 'avg:rain.sum' are all rejected. 'avg' means the mean across the baseline years for that week/month bucket. lb/ub are unscaled natural units (°C, mm, km/h, oktas, days). Percentile metrics — p1 = low tail, p50 = median, p99 = high tail: avg:max_t.p1, avg:max_t.p50, avg:max_t.p99, avg:min_t.p1, avg:min_t.p50, avg:min_t.p99, avg:obs.dewp.p1, avg:obs.dewp.p50, avg:obs.dewp.p99, avg:obs.dewph.p1, avg:obs.dewph.p50, avg:obs.dewph.p99, avg:obs.wbulb.p1, avg:obs.wbulb.p50, avg:obs.wbulb.p99, avg:obs.wbgt.p1, avg:obs.wbgt.p50, avg:obs.wbgt.p99, avg:obs.temp.p1, avg:obs.temp.p50, avg:obs.temp.p99, avg:obs.heatindex.p1, avg:obs.heatindex.p50, avg:obs.heatindex.p99 (°C); avg:obs.wind.p1, avg:obs.wind.p50, avg:obs.wind.p99 (km/h); avg:obs.cloudcover.p1, avg:obs.cloudcover.p50, avg:obs.cloudcover.p99 (oktas). Tail-percentile metrics: avg:obs.gust.p99 (km/h); avg:obs.rain.p95, avg:obs.rain.p99, avg:obs.snow.p95, avg:obs.snow.p99 (mm). Accumulation over the bucket: avg:obs.rain.sum, avg:obs.snow.sum (mm). Day-counts within the bucket: avg:obs.is_snow.count, avg:obs.is_rain.count, avg:obs.is_hail.count, avg:obs.is_thunderstorm.count, avg:obs.is_fog.count, avg:obs.is_smoke.count (days). Use exactly one of the names above as the criterion 'metric'; anything else returns an error listing the valid names."
},
"radius_km": {
"type": "string",
"description": "Radius km for area search (default: 100)"
},
"max_results": {
"type": "string",
"description": "Max results (default: 100)"
}
}
}| criteria* |
| string |
| JSON array of criteria, passed as a string. Example: [{"metric":"avg:max_t.p50","lb":18,"ub":28,"must_have":true},{"metric":"avg:obs.rain.sum","ub":40,"must_have":true},{"metric":"avg:obs.is_rain.count","ub":6,"must_have":false}] Each element has: metric (required, one of the exact names listed below), lb and ub (optional numeric lower/upper bounds, unscaled natural units; set at least one), and must_have (true = hard filter every result must satisfy, false = optional, only used to rank results). At least one criterion with must_have=true is required. Metric names are literal and case-sensitive. Each is the prefix 'avg:' + the metric base + '.' + the attribute — for example avg:obs.rain.sum and avg:max_t.p50. Never drop the 'avg:' prefix and never drop the 'obs.' segment: 'obs.rain.sum', 'rain.sum' and 'avg:rain.sum' are all rejected. 'avg' means the mean across the baseline years for that week/month bucket. lb/ub are unscaled natural units (°C, mm, km/h, oktas, days). Percentile metrics — p1 = low tail, p50 = median, p99 = high tail: avg:max_t.p1, avg:max_t.p50, avg:max_t.p99, avg:min_t.p1, avg:min_t.p50, avg:min_t.p99, avg:obs.dewp.p1, avg:obs.dewp.p50, avg:obs.dewp.p99, avg:obs.dewph.p1, avg:obs.dewph.p50, avg:obs.dewph.p99, avg:obs.wbulb.p1, avg:obs.wbulb.p50, avg:obs.wbulb.p99, avg:obs.wbgt.p1, avg:obs.wbgt.p50, avg:obs.wbgt.p99, avg:obs.temp.p1, avg:obs.temp.p50, avg:obs.temp.p99, avg:obs.heatindex.p1, avg:obs.heatindex.p50, avg:obs.heatindex.p99 (°C); avg:obs.wind.p1, avg:obs.wind.p50, avg:obs.wind.p99 (km/h); avg:obs.cloudcover.p1, avg:obs.cloudcover.p50, avg:obs.cloudcover.p99 (oktas). Tail-percentile metrics: avg:obs.gust.p99 (km/h); avg:obs.rain.p95, avg:obs.rain.p99, avg:obs.snow.p95, avg:obs.snow.p99 (mm). Accumulation over the bucket: avg:obs.rain.sum, avg:obs.snow.sum (mm). Day-counts within the bucket: avg:obs.is_snow.count, avg:obs.is_rain.count, avg:obs.is_hail.count, avg:obs.is_thunderstorm.count, avg:obs.is_fog.count, avg:obs.is_smoke.count (days). Use exactly one of the names above as the criterion 'metric'; anything else returns an error listing the valid names. |
| when_type | string | week | month | day (default: week) |
| when_basis | string | historical | forecast (default: historical) |
| max_results | string | Max results (default: 25) |
{
"type": "object",
"required": [
"criteria"
],
"properties": {
"name": {
"type": "string",
"description": "Location name, e.g. New York"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"baseline": {
"type": "string",
"description": "Baseline year range YYYY-YYYY (default: 1996-2025)"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria, passed as a string. Example: [{\"metric\":\"avg:max_t.p50\",\"lb\":18,\"ub\":28,\"must_have\":true},{\"metric\":\"avg:obs.rain.sum\",\"ub\":40,\"must_have\":true},{\"metric\":\"avg:obs.is_rain.count\",\"ub\":6,\"must_have\":false}] Each element has: metric (required, one of the exact names listed below), lb and ub (optional numeric lower/upper bounds, unscaled natural units; set at least one), and must_have (true = hard filter every result must satisfy, false = optional, only used to rank results). At least one criterion with must_have=true is required. Metric names are literal and case-sensitive. Each is the prefix 'avg:' + the metric base + '.' + the attribute — for example avg:obs.rain.sum and avg:max_t.p50. Never drop the 'avg:' prefix and never drop the 'obs.' segment: 'obs.rain.sum', 'rain.sum' and 'avg:rain.sum' are all rejected. 'avg' means the mean across the baseline years for that week/month bucket. lb/ub are unscaled natural units (°C, mm, km/h, oktas, days). Percentile metrics — p1 = low tail, p50 = median, p99 = high tail: avg:max_t.p1, avg:max_t.p50, avg:max_t.p99, avg:min_t.p1, avg:min_t.p50, avg:min_t.p99, avg:obs.dewp.p1, avg:obs.dewp.p50, avg:obs.dewp.p99, avg:obs.dewph.p1, avg:obs.dewph.p50, avg:obs.dewph.p99, avg:obs.wbulb.p1, avg:obs.wbulb.p50, avg:obs.wbulb.p99, avg:obs.wbgt.p1, avg:obs.wbgt.p50, avg:obs.wbgt.p99, avg:obs.temp.p1, avg:obs.temp.p50, avg:obs.temp.p99, avg:obs.heatindex.p1, avg:obs.heatindex.p50, avg:obs.heatindex.p99 (°C); avg:obs.wind.p1, avg:obs.wind.p50, avg:obs.wind.p99 (km/h); avg:obs.cloudcover.p1, avg:obs.cloudcover.p50, avg:obs.cloudcover.p99 (oktas). Tail-percentile metrics: avg:obs.gust.p99 (km/h); avg:obs.rain.p95, avg:obs.rain.p99, avg:obs.snow.p95, avg:obs.snow.p99 (mm). Accumulation over the bucket: avg:obs.rain.sum, avg:obs.snow.sum (mm). Day-counts within the bucket: avg:obs.is_snow.count, avg:obs.is_rain.count, avg:obs.is_hail.count, avg:obs.is_thunderstorm.count, avg:obs.is_fog.count, avg:obs.is_smoke.count (days). Use exactly one of the names above as the criterion 'metric'; anything else returns an error listing the valid names."
},
"when_type": {
"type": "string",
"description": "week | month | day (default: week)"
},
"when_basis": {
"type": "string",
"description": "historical | forecast (default: historical)"
},
"max_results": {
"type": "string",
"description": "Max results (default: 25)"
}
}
}{
"type": "object",
"required": [],
"properties": {
"ctryid": {
"type": "string",
"description": "Comma-separated country codes to filter (as returned by /api/countries). Leave empty for global results."
},
"breaking_type": {
"type": "string",
"description": "Type of anomaly source. Values: obs (recent observations, ~last 3 days), forecast (upcoming 0-7 days). (default: obs)"
},
"metric_category": {
"type": "string",
"description": "Filter by metric category. Values: A (All), T (Temperature), P (Precipitation), H (Humidity/Dew Point), W (Wind). (default: A)"
}
}
}| string |
| Latitude,Longitude of area centre (e.g. '51.5,-0.1'). Used with radius_km for area search. Ignored when locids is set. |
| metrics* | string | Metric to compare. Available: max_t, max_t.means, max_wind, max_wind.means, min_t, min_t.means, obs.dewp, obs.dewp.means, obs.dpd, obs.dpd.means, obs.gust, obs.heatindex, obs.heatindex.means, obs.is_dust, obs.is_fog, obs.is_frozen_rain, obs.is_hail, obs.is_haze, obs.is_ice_pellets, obs.is_rain, obs.is_smoke, obs.is_snow, obs.is_squall, obs.is_thunderstorm, obs.rain, obs.rainh, obs.snow, obs.snowh, obs.temp, obs.temp.means, obs.wbulb, obs.wbulb.means, obs.wind, obs.wind.means, rain_sum, snow_sum |
| src_type | string | Data source: Obs (station observations) | ERA5 (reanalysis). (default: Obs) |
| countries | string | Comma-separated ISO country codes to filter (e.g. 'GB,FR'). |
| obs_years | string | Observation year or range (e.g. '2024' or '2020-2024'). Values can range from 2024 to current year, or a single hyphenated range e.g. 1981-2010. |
| radius_km | string | Search radius in km around lat_lon. Default 100. (default: 100) |
| base_years | string | Baseline period. Available: 1991-2020. (default: 1991-2020) |
{
"type": "object",
"required": [
"metrics"
],
"properties": {
"locids": {
"type": "string",
"description": "Comma-separated location IDs (as returned by /api/location). Example: '037720_99999,432950_99999'."
},
"months": {
"type": "string",
"description": "Single month ('06') or hyphenated range ('MM-MM'). Seasons: '12-02' (Dec-Feb), '12-03' (Dec-Mar), '10-11' (Oct-Nov), '03-05' (Mar-May), '06-08' (Jun-Aug), '06-09' (Jun-Sep). Use 'All' for annual. Example: '06' or '06-09'."
},
"lat_lon": {
"type": "string",
"description": "Latitude,Longitude of area centre (e.g. '51.5,-0.1'). Used with radius_km for area search. Ignored when locids is set."
},
"metrics": {
"type": "string",
"description": "Metric to compare. Available: max_t, max_t.means, max_wind, max_wind.means, min_t, min_t.means, obs.dewp, obs.dewp.means, obs.dpd, obs.dpd.means, obs.gust, obs.heatindex, obs.heatindex.means, obs.is_dust, obs.is_fog, obs.is_frozen_rain, obs.is_hail, obs.is_haze, obs.is_ice_pellets, obs.is_rain, obs.is_smoke, obs.is_snow, obs.is_squall, obs.is_thunderstorm, obs.rain, obs.rainh, obs.snow, obs.snowh, obs.temp, obs.temp.means, obs.wbulb, obs.wbulb.means, obs.wind, obs.wind.means, rain_sum, snow_sum"
},
"src_type": {
"type": "string",
"description": "Data source: Obs (station observations) | ERA5 (reanalysis). (default: Obs)"
},
"countries": {
"type": "string",
"description": "Comma-separated ISO country codes to filter (e.g. 'GB,FR')."
},
"obs_years": {
"type": "string",
"description": "Observation year or range (e.g. '2024' or '2020-2024'). Values can range from 2024 to current year, or a single hyphenated range e.g. 1981-2010."
},
"radius_km": {
"type": "string",
"description": "Search radius in km around lat_lon. Default 100. (default: 100)"
},
"base_years": {
"type": "string",
"description": "Baseline period. Available: 1991-2020. (default: 1991-2020)"
}
}
}| months | string | Single month ('06') or hyphenated range ('03-05' for March-May, '06-08' for June-August) or 'All' for annual trends. Example: '06' or '03-05'. |
| lat_lon | string | Latitude,Longitude of area centre (e.g. '51.5,-0.1'). Used with radius_km for area search. Ignored when locids is set. |
| metrics* | string | Comma-separated metric(s) in format agg_func:metric_id.attribute. Example: avg:max_t.p50. Available: avg:max_t.mean, avg:max_t.p10, avg:max_t.p5, avg:max_t.p90, avg:max_t.p95, avg:max_wind.p95, avg:min_t.mean, avg:min_t.p10, avg:min_t.p5, avg:min_t.p90, avg:min_t.p95, avg:obs.dewp.mean, avg:obs.dewp.p5, avg:obs.dewp.p95, avg:obs.dpd.mean, avg:obs.dpd.p95, avg:obs.rain.p95, avg:obs.rainh.p95, avg:obs.snow.p95, avg:obs.temp.mean, avg:obs.temp.p5, avg:obs.temp.p50, avg:obs.temp.p95, avg:obs.wbulb.mean, avg:obs.wbulb.p95, avg:obs.wind.mean, avg:obs.wind.p5, avg:obs.wind.p50, avg:obs.wind.p95, sum:obs.is_fog.count, sum:obs.is_hail.count, sum:obs.is_rain.count, sum:obs.is_smoke.count, sum:obs.is_snow.count, sum:obs.is_thunderstorm.count, sum:obs.rain.sum, sum:obs.snow.sum |
| src_type | string | Data source: Obs (station observations) | ERA5 (reanalysis). ERA5 provides global coverage including ocean areas. (default: Obs) |
| countries | string | Comma-separated ISO country codes to filter results (e.g. 'GB,FR'). |
| num_years | string | Minimum number of years with non-null data. Use to filter sparse records. (default: 0) |
| radius_km | string | Search radius in km around lat_lon. Default 100. (default: 100) |
{
"type": "object",
"required": [
"metrics"
],
"properties": {
"avg_N": {
"type": "string",
"description": "Minimum average number of days per period for years with data. (default: 0)"
},
"years": {
"type": "string",
"description": "Year range string. Known values: '1975-' (data from 1975 onward). (default: 1975-)"
},
"locids": {
"type": "string",
"description": "Comma-separated list of location IDs (as returned by /api/location). Example: '037720_99999,432950_99999'. Use locids for point queries."
},
"months": {
"type": "string",
"description": "Single month ('06') or hyphenated range ('03-05' for March-May, '06-08' for June-August) or 'All' for annual trends. Example: '06' or '03-05'."
},
"lat_lon": {
"type": "string",
"description": "Latitude,Longitude of area centre (e.g. '51.5,-0.1'). Used with radius_km for area search. Ignored when locids is set."
},
"metrics": {
"type": "string",
"description": "Comma-separated metric(s) in format agg_func:metric_id.attribute. Example: avg:max_t.p50. Available: avg:max_t.mean, avg:max_t.p10, avg:max_t.p5, avg:max_t.p90, avg:max_t.p95, avg:max_wind.p95, avg:min_t.mean, avg:min_t.p10, avg:min_t.p5, avg:min_t.p90, avg:min_t.p95, avg:obs.dewp.mean, avg:obs.dewp.p5, avg:obs.dewp.p95, avg:obs.dpd.mean, avg:obs.dpd.p95, avg:obs.rain.p95, avg:obs.rainh.p95, avg:obs.snow.p95, avg:obs.temp.mean, avg:obs.temp.p5, avg:obs.temp.p50, avg:obs.temp.p95, avg:obs.wbulb.mean, avg:obs.wbulb.p95, avg:obs.wind.mean, avg:obs.wind.p5, avg:obs.wind.p50, avg:obs.wind.p95, sum:obs.is_fog.count, sum:obs.is_hail.count, sum:obs.is_rain.count, sum:obs.is_smoke.count, sum:obs.is_snow.count, sum:obs.is_thunderstorm.count, sum:obs.rain.sum, sum:obs.snow.sum"
},
"src_type": {
"type": "string",
"description": "Data source: Obs (station observations) | ERA5 (reanalysis). ERA5 provides global coverage including ocean areas. (default: Obs)"
},
"countries": {
"type": "string",
"description": "Comma-separated ISO country codes to filter results (e.g. 'GB,FR')."
},
"num_years": {
"type": "string",
"description": "Minimum number of years with non-null data. Use to filter sparse records. (default: 0)"
},
"radius_km": {
"type": "string",
"description": "Search radius in km around lat_lon. Default 100. (default: 100)"
}
}
}| ymd_end* |
| string |
| End of period (YYYY[MMDD]) |
| ymd_start* | string | Start of period (YYYY[MMDD]) |
| period_type | string | Period Type [ MONTH | YEAR | WEEK | DAY | FULL_DAY | FUTURE_DAY] (default: DAY) |
| baseline_offset | string | Baseline offset in years (default: 1) |
| baseline_period | string | Baseline period in years (default: 30) |
| observed_period | string | Observed period (default: 1) |
{
"type": "object",
"required": [
"ymd_start",
"ymd_end"
],
"properties": {
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"ymd_end": {
"type": "string",
"description": "End of period (YYYY[MMDD])"
},
"ymd_start": {
"type": "string",
"description": "Start of period (YYYY[MMDD])"
},
"period_type": {
"type": "string",
"description": "Period Type [ MONTH | YEAR | WEEK | DAY | FULL_DAY | FUTURE_DAY] (default: DAY)"
},
"baseline_offset": {
"type": "string",
"description": "Baseline offset in years (default: 1)"
},
"baseline_period": {
"type": "string",
"description": "Baseline period in years (default: 30)"
},
"observed_period": {
"type": "string",
"description": "Observed period (default: 1)"
}
}
}| string |
| Observation end date (YYYYMMDD) |
| category | string | Category: Temp | Prcp | Wind | Humidity (default: Temp) |
| ymd_start* | string | Observation start date (YYYYMMDD), max 5-year span |
| baseline_year_end | string | Baseline year end YYYY (default: 2020) |
| baseline_year_start | string | Baseline year start YYYY (default: 1991) |
{
"type": "object",
"required": [
"ymd_start",
"ymd_end"
],
"properties": {
"name": {
"type": "string",
"description": "Location name, e.g. New York"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"window": {
"type": "string",
"description": "Sliding window days (3-7) (default: 7)"
},
"ymd_end": {
"type": "string",
"description": "Observation end date (YYYYMMDD)"
},
"category": {
"type": "string",
"description": "Category: Temp | Prcp | Wind | Humidity (default: Temp)"
},
"ymd_start": {
"type": "string",
"description": "Observation start date (YYYYMMDD), max 5-year span"
},
"baseline_year_end": {
"type": "string",
"description": "Baseline year end YYYY (default: 2020)"
},
"baseline_year_start": {
"type": "string",
"description": "Baseline year start YYYY (default: 1991)"
}
}
}| bbox | string | Box as 'lat1,lon1,lat2,lon2': two opposite corners, lon1 the western edge and lon2 the eastern (lon1 greater than lon2 crosses the antimeridian). Approximate, like latlon. Give at most one of ctryid, latlon, bbox; none means global |
| limit | string | Most locations to return, 1 to 10000, highest avg_count first (default: 2000) |
| ctryid | string | Comma-separated ISO country codes, e.g. US,MX |
| latlon | string | Centre of an area as 'lat,lon', e.g. 12.97,77.59. Approximate: the area searched is the circle's bounding box rounded out to geohash cells |
| sample | string | Show about this many locations (1 to 2000) for a map view: whole geohash3 cells (about 150 km) are kept or dropped by a fixed hash, so the same cells appear on every request and zooming in only adds points. The share kept is sample divided by the locations in the area, so a wider area keeps a smaller share. Omit for every location. A sampled request may use any time window, even without a geo scope. dailycountbyloc only: a request too wide to count in full (no geo scope and more than 30 days) is sampled to 200 automatically; pass sample=0 to get an error instead |
| ymd_end | string | Last day YYYYMMDD of the date range, inclusive |
| criteria | string | JSON array of criteria, all of which must hold, e.g. [{"metric":"max_t","lb":35},{"metric":"obs.dewp.ptile","lb":95}]. Each element: metric (exact name), lb and/or ub (inclusive bounds). At most 8 criteria. Absolute values use the metric name, in natural units: max_t (°C), min_t (°C), obs.temp (°C), obs.dewp (°C), obs.wind (km/h), obs.gust (km/h), max_wind (km/h), obs.rain (mm), obs.snow (mm), obs.wbulb (°C), obs.wbgt (°C), obs.heatindex (°C), obs.rainh (mm). Append .z for the anomaly in standard deviations (-10 to 10) or .ptile for the percentile (0 to 100) within that week's climatology. Both forms: max_t, min_t, obs.temp, obs.dewp, obs.wind, obs.gust, max_wind, obs.wbulb, obs.wbgt, obs.heatindex. Percentile only: obs.rain, obs.snow, obs.rainh. Condition flags take lb 1 (happened) or ub 0 (did not): obs.is_rain, obs.is_snow, obs.is_thunderstorm, obs.is_fog, obs.is_hail. Percentiles and z-scores read more extreme than their names suggest: the weekly climatology averages each year's week, which narrows its spread, so for example ptile of 90 or more selects well over 10 percent of days. Use 99 or z of 3 for rare days. For obs.wbulb, obs.wbgt, obs.heatindex, obs.rainh, .ptile and .z rank the day's worst hour among all hours of that week, not the day among days, so a typical day's peak already ranks high. Days before a location has 5 baseline years carry no .z or .ptile. Defaults to max_t between 20 and 30 C when omitted. |
| year_end | string | Last year of the window, YYYY, inclusive |
| max_count | string | Highest avg_count to return, inclusive |
| min_count | string | Lowest avg_count (days per year) to return, inclusive |
| mm_dd_end | string | Window end MMDD (or MM), inclusive |
| radius_km | string | Radius in km for latlon, up to 2000 (default: 100) |
| ymd_start | string | First day YYYYMMDD of a date range of at most 31 days. Use either ymd_start/ymd_end or year_start/year_end/mm_dd_start/mm_dd_end |
| year_start | string | First year of a years x month-day window, YYYY |
| mm_dd_start | string | Window start MMDD (or MM). When later than mm_dd_end the window crosses the year end, e.g. 1201 to 0228, and each season belongs to the year it starts in |
| max_count_pct | string | Highest count_pct (0-100) to return, inclusive |
| min_count_pct | string | Lowest count_pct (0-100) to return, inclusive |
{
"type": "object",
"required": [],
"properties": {
"bbox": {
"type": "string",
"description": "Box as 'lat1,lon1,lat2,lon2': two opposite corners, lon1 the western edge and lon2 the eastern (lon1 greater than lon2 crosses the antimeridian). Approximate, like latlon. Give at most one of ctryid, latlon, bbox; none means global"
},
"limit": {
"type": "string",
"description": "Most locations to return, 1 to 10000, highest avg_count first (default: 2000)"
},
"ctryid": {
"type": "string",
"description": "Comma-separated ISO country codes, e.g. US,MX"
},
"latlon": {
"type": "string",
"description": "Centre of an area as 'lat,lon', e.g. 12.97,77.59. Approximate: the area searched is the circle's bounding box rounded out to geohash cells"
},
"sample": {
"type": "string",
"description": "Show about this many locations (1 to 2000) for a map view: whole geohash3 cells (about 150 km) are kept or dropped by a fixed hash, so the same cells appear on every request and zooming in only adds points. The share kept is sample divided by the locations in the area, so a wider area keeps a smaller share. Omit for every location. A sampled request may use any time window, even without a geo scope. dailycountbyloc only: a request too wide to count in full (no geo scope and more than 30 days) is sampled to 200 automatically; pass sample=0 to get an error instead"
},
"ymd_end": {
"type": "string",
"description": "Last day YYYYMMDD of the date range, inclusive"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria, all of which must hold, e.g. [{\"metric\":\"max_t\",\"lb\":35},{\"metric\":\"obs.dewp.ptile\",\"lb\":95}]. Each element: metric (exact name), lb and/or ub (inclusive bounds). At most 8 criteria. Absolute values use the metric name, in natural units: max_t (°C), min_t (°C), obs.temp (°C), obs.dewp (°C), obs.wind (km/h), obs.gust (km/h), max_wind (km/h), obs.rain (mm), obs.snow (mm), obs.wbulb (°C), obs.wbgt (°C), obs.heatindex (°C), obs.rainh (mm). Append .z for the anomaly in standard deviations (-10 to 10) or .ptile for the percentile (0 to 100) within that week's climatology. Both forms: max_t, min_t, obs.temp, obs.dewp, obs.wind, obs.gust, max_wind, obs.wbulb, obs.wbgt, obs.heatindex. Percentile only: obs.rain, obs.snow, obs.rainh. Condition flags take lb 1 (happened) or ub 0 (did not): obs.is_rain, obs.is_snow, obs.is_thunderstorm, obs.is_fog, obs.is_hail. Percentiles and z-scores read more extreme than their names suggest: the weekly climatology averages each year's week, which narrows its spread, so for example ptile of 90 or more selects well over 10 percent of days. Use 99 or z of 3 for rare days. For obs.wbulb, obs.wbgt, obs.heatindex, obs.rainh, .ptile and .z rank the day's worst hour among all hours of that week, not the day among days, so a typical day's peak already ranks high. Days before a location has 5 baseline years carry no .z or .ptile. Defaults to max_t between 20 and 30 C when omitted."
},
"year_end": {
"type": "string",
"description": "Last year of the window, YYYY, inclusive"
},
"max_count": {
"type": "string",
"description": "Highest avg_count to return, inclusive"
},
"min_count": {
"type": "string",
"description": "Lowest avg_count (days per year) to return, inclusive"
},
"mm_dd_end": {
"type": "string",
"description": "Window end MMDD (or MM), inclusive"
},
"radius_km": {
"type": "string",
"description": "Radius in km for latlon, up to 2000 (default: 100)"
},
"ymd_start": {
"type": "string",
"description": "First day YYYYMMDD of a date range of at most 31 days. Use either ymd_start/ymd_end or year_start/year_end/mm_dd_start/mm_dd_end"
},
"year_start": {
"type": "string",
"description": "First year of a years x month-day window, YYYY"
},
"mm_dd_start": {
"type": "string",
"description": "Window start MMDD (or MM). When later than mm_dd_end the window crosses the year end, e.g. 1201 to 0228, and each season belongs to the year it starts in"
},
"max_count_pct": {
"type": "string",
"description": "Highest count_pct (0-100) to return, inclusive"
},
"min_count_pct": {
"type": "string",
"description": "Lowest count_pct (0-100) to return, inclusive"
}
}
}| criteria | string | JSON array of criteria, all of which must hold, e.g. [{"metric":"max_t","lb":35},{"metric":"obs.dewp.ptile","lb":95}]. Each element: metric (exact name), lb and/or ub (inclusive bounds). At most 8 criteria. Absolute values use the metric name, in natural units: max_t (°C), min_t (°C), obs.temp (°C), obs.dewp (°C), obs.wind (km/h), obs.gust (km/h), max_wind (km/h), obs.rain (mm), obs.snow (mm), obs.wbulb (°C), obs.wbgt (°C), obs.heatindex (°C), obs.rainh (mm). Append .z for the anomaly in standard deviations (-10 to 10) or .ptile for the percentile (0 to 100) within that week's climatology. Both forms: max_t, min_t, obs.temp, obs.dewp, obs.wind, obs.gust, max_wind, obs.wbulb, obs.wbgt, obs.heatindex. Percentile only: obs.rain, obs.snow, obs.rainh. Condition flags take lb 1 (happened) or ub 0 (did not): obs.is_rain, obs.is_snow, obs.is_thunderstorm, obs.is_fog, obs.is_hail. Percentiles and z-scores read more extreme than their names suggest: the weekly climatology averages each year's week, which narrows its spread, so for example ptile of 90 or more selects well over 10 percent of days. Use 99 or z of 3 for rare days. For obs.wbulb, obs.wbgt, obs.heatindex, obs.rainh, .ptile and .z rank the day's worst hour among all hours of that week, not the day among days, so a typical day's peak already ranks high. Days before a location has 5 baseline years carry no .z or .ptile. Defaults to max_t between 20 and 30 C when omitted. |
| mm_dd_end | string | Window end MMDD (or MM), inclusive |
| ymd_start | string | Alternative to mm_dd_start: a day whose MMDD starts the window |
| mm_dd_start | string | Window start MMDD (or MM) |
{
"type": "object",
"required": [
"locid"
],
"properties": {
"locid": {
"type": "string",
"description": "Location id from /api/location, e.g. 724940_23234"
},
"ymd_end": {
"type": "string",
"description": "Alternative to mm_dd_end: a day whose MMDD ends the window"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria, all of which must hold, e.g. [{\"metric\":\"max_t\",\"lb\":35},{\"metric\":\"obs.dewp.ptile\",\"lb\":95}]. Each element: metric (exact name), lb and/or ub (inclusive bounds). At most 8 criteria. Absolute values use the metric name, in natural units: max_t (°C), min_t (°C), obs.temp (°C), obs.dewp (°C), obs.wind (km/h), obs.gust (km/h), max_wind (km/h), obs.rain (mm), obs.snow (mm), obs.wbulb (°C), obs.wbgt (°C), obs.heatindex (°C), obs.rainh (mm). Append .z for the anomaly in standard deviations (-10 to 10) or .ptile for the percentile (0 to 100) within that week's climatology. Both forms: max_t, min_t, obs.temp, obs.dewp, obs.wind, obs.gust, max_wind, obs.wbulb, obs.wbgt, obs.heatindex. Percentile only: obs.rain, obs.snow, obs.rainh. Condition flags take lb 1 (happened) or ub 0 (did not): obs.is_rain, obs.is_snow, obs.is_thunderstorm, obs.is_fog, obs.is_hail. Percentiles and z-scores read more extreme than their names suggest: the weekly climatology averages each year's week, which narrows its spread, so for example ptile of 90 or more selects well over 10 percent of days. Use 99 or z of 3 for rare days. For obs.wbulb, obs.wbgt, obs.heatindex, obs.rainh, .ptile and .z rank the day's worst hour among all hours of that week, not the day among days, so a typical day's peak already ranks high. Days before a location has 5 baseline years carry no .z or .ptile. Defaults to max_t between 20 and 30 C when omitted."
},
"mm_dd_end": {
"type": "string",
"description": "Window end MMDD (or MM), inclusive"
},
"ymd_start": {
"type": "string",
"description": "Alternative to mm_dd_start: a day whose MMDD starts the window"
},
"mm_dd_start": {
"type": "string",
"description": "Window start MMDD (or MM)"
}
}
}| metric | string | Metric to score: max_t, max_wind, min_t, obs.dewp, obs.gust, obs.heatindex, obs.rain, obs.rainh, obs.snow, obs.temp, obs.wbgt, obs.wbulb, obs.wind (default: max_t) |
| end_date | string | Last day YYYYMMDD, inclusive; defaults to yesterday |
| lead_times | string | Comma-separated forecast leads in days, each 1 to 7, e.g. 1,3,7. De-duplicated and returned in ascending order as the first axis of the per-lead series (default: 1) |
| start_date | string | First day YYYYMMDD |
| time_window | string | Trailing window in days (1 to 31) each day's scores are computed over (default: 5) |
{
"type": "object",
"required": [
"locid"
],
"properties": {
"locid": {
"type": "string",
"description": "Location id from /api/location, e.g. 724940_23234"
},
"metric": {
"type": "string",
"description": "Metric to score: max_t, max_wind, min_t, obs.dewp, obs.gust, obs.heatindex, obs.rain, obs.rainh, obs.snow, obs.temp, obs.wbgt, obs.wbulb, obs.wind (default: max_t)"
},
"end_date": {
"type": "string",
"description": "Last day YYYYMMDD, inclusive; defaults to yesterday"
},
"lead_times": {
"type": "string",
"description": "Comma-separated forecast leads in days, each 1 to 7, e.g. 1,3,7. De-duplicated and returned in ascending order as the first axis of the per-lead series (default: 1)"
},
"start_date": {
"type": "string",
"description": "First day YYYYMMDD"
},
"time_window": {
"type": "string",
"description": "Trailing window in days (1 to 31) each day's scores are computed over (default: 5)"
}
}
}| string |
| Box as 'lat1,lon1,lat2,lon2': two opposite corners, lon1 the western edge and lon2 the eastern (lon1 greater than lon2 crosses the antimeridian). Approximate, like latlon. Give at most one of ctryid, latlon, bbox; none means global |
| date* | string | Day YYYYMMDD |
| lead | string | fcast only: forecast lead in days, 1 to 7 (days from the forecast's issue to date). Defaults to date minus today plus 1, clamped to 1 to 7: the newest forecast from yesterday's run |
| limit | string | Most rows to return, 1 to 5000, highest value first (default: 2000) |
| ctryid | string | Comma-separated ISO country codes, e.g. US,MX |
| latlon | string | Centre of an area as 'lat,lon', e.g. 12.97,77.59. Approximate: the area searched is the circle's bounding box rounded out to geohash cells |
| metric | string | Comma-separated metrics to report, up to 8, e.g. max_t,min_t. Rows are sorted by the first, highest first; a location appears when at least one is present. Valid: max_t, max_wind, min_t, obs.dewp, obs.gust, obs.heatindex, obs.rain, obs.rainh, obs.snow, obs.temp, obs.wbgt, obs.wbulb, obs.wind (default: max_t) |
| sample | string | Show about this many locations (1 to 2000) for a map view: whole geohash3 cells (about 150 km) are kept or dropped by a fixed hash, so the same cells appear on every request and zooming in only adds points. The share kept is sample divided by the locations in the area, so a wider area keeps a smaller share. Omit for every location. A sampled request may use any time window, even without a geo scope. dailycountbyloc only: a request too wide to count in full (no geo scope and more than 30 days) is sampled to 200 automatically; pass sample=0 to get an error instead |
| criteria | string | JSON array of criteria, all of which must hold, e.g. [{"metric":"max_t","lb":35},{"metric":"obs.dewp.ptile","lb":95}]. Each element: metric (exact name), lb and/or ub (inclusive bounds). At most 8 criteria. Absolute values use the metric name, in natural units: max_t (°C), min_t (°C), obs.temp (°C), obs.dewp (°C), obs.wind (km/h), obs.gust (km/h), max_wind (km/h), obs.rain (mm), obs.snow (mm), obs.wbulb (°C), obs.wbgt (°C), obs.heatindex (°C), obs.rainh (mm). Append .z for the anomaly in standard deviations (-10 to 10) or .ptile for the percentile (0 to 100) within that week's climatology. Both forms: max_t, min_t, obs.temp, obs.dewp, obs.wind, obs.gust, max_wind, obs.wbulb, obs.wbgt, obs.heatindex. Percentile only: obs.rain, obs.snow, obs.rainh. Condition flags take lb 1 (happened) or ub 0 (did not): obs.is_rain, obs.is_snow, obs.is_thunderstorm, obs.is_fog, obs.is_hail. Percentiles and z-scores read more extreme than their names suggest: the weekly climatology averages each year's week, which narrows its spread, so for example ptile of 90 or more selects well over 10 percent of days. Use 99 or z of 3 for rare days. For obs.wbulb, obs.wbgt, obs.heatindex, obs.rainh, .ptile and .z rank the day's worst hour among all hours of that week, not the day among days, so a typical day's peak already ranks high. Days before a location has 5 baseline years carry no .z or .ptile. Optional here: omit it to list every location with the metric. |
| radius_km | string | Radius in km for latlon, up to 2000 (default: 100) |
{
"type": "object",
"required": [
"date"
],
"properties": {
"src": {
"type": "string",
"description": "obs (observed) or fcast (Weathersight's forecast) (default: obs)"
},
"bbox": {
"type": "string",
"description": "Box as 'lat1,lon1,lat2,lon2': two opposite corners, lon1 the western edge and lon2 the eastern (lon1 greater than lon2 crosses the antimeridian). Approximate, like latlon. Give at most one of ctryid, latlon, bbox; none means global"
},
"date": {
"type": "string",
"description": "Day YYYYMMDD"
},
"lead": {
"type": "string",
"description": "fcast only: forecast lead in days, 1 to 7 (days from the forecast's issue to date). Defaults to date minus today plus 1, clamped to 1 to 7: the newest forecast from yesterday's run"
},
"limit": {
"type": "string",
"description": "Most rows to return, 1 to 5000, highest value first (default: 2000)"
},
"ctryid": {
"type": "string",
"description": "Comma-separated ISO country codes, e.g. US,MX"
},
"latlon": {
"type": "string",
"description": "Centre of an area as 'lat,lon', e.g. 12.97,77.59. Approximate: the area searched is the circle's bounding box rounded out to geohash cells"
},
"metric": {
"type": "string",
"description": "Comma-separated metrics to report, up to 8, e.g. max_t,min_t. Rows are sorted by the first, highest first; a location appears when at least one is present. Valid: max_t, max_wind, min_t, obs.dewp, obs.gust, obs.heatindex, obs.rain, obs.rainh, obs.snow, obs.temp, obs.wbgt, obs.wbulb, obs.wind (default: max_t)"
},
"sample": {
"type": "string",
"description": "Show about this many locations (1 to 2000) for a map view: whole geohash3 cells (about 150 km) are kept or dropped by a fixed hash, so the same cells appear on every request and zooming in only adds points. The share kept is sample divided by the locations in the area, so a wider area keeps a smaller share. Omit for every location. A sampled request may use any time window, even without a geo scope. dailycountbyloc only: a request too wide to count in full (no geo scope and more than 30 days) is sampled to 200 automatically; pass sample=0 to get an error instead"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria, all of which must hold, e.g. [{\"metric\":\"max_t\",\"lb\":35},{\"metric\":\"obs.dewp.ptile\",\"lb\":95}]. Each element: metric (exact name), lb and/or ub (inclusive bounds). At most 8 criteria. Absolute values use the metric name, in natural units: max_t (°C), min_t (°C), obs.temp (°C), obs.dewp (°C), obs.wind (km/h), obs.gust (km/h), max_wind (km/h), obs.rain (mm), obs.snow (mm), obs.wbulb (°C), obs.wbgt (°C), obs.heatindex (°C), obs.rainh (mm). Append .z for the anomaly in standard deviations (-10 to 10) or .ptile for the percentile (0 to 100) within that week's climatology. Both forms: max_t, min_t, obs.temp, obs.dewp, obs.wind, obs.gust, max_wind, obs.wbulb, obs.wbgt, obs.heatindex. Percentile only: obs.rain, obs.snow, obs.rainh. Condition flags take lb 1 (happened) or ub 0 (did not): obs.is_rain, obs.is_snow, obs.is_thunderstorm, obs.is_fog, obs.is_hail. Percentiles and z-scores read more extreme than their names suggest: the weekly climatology averages each year's week, which narrows its spread, so for example ptile of 90 or more selects well over 10 percent of days. Use 99 or z of 3 for rare days. For obs.wbulb, obs.wbgt, obs.heatindex, obs.rainh, .ptile and .z rank the day's worst hour among all hours of that week, not the day among days, so a typical day's peak already ranks high. Days before a location has 5 baseline years carry no .z or .ptile. Optional here: omit it to list every location with the metric."
},
"radius_km": {
"type": "string",
"description": "Radius in km for latlon, up to 2000 (default: 100)"
}
}
}| is_forecast |
| string |
| Forecast requested? (0|1) (default: 1) |
{
"type": "object",
"required": [
"latlon"
],
"properties": {
"unit": {
"type": "string",
"description": "Degree days as measured in F|C (default: C)"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"ymd_end": {
"type": "string",
"description": "End of period (YYYYMMDD)"
},
"ymd_start": {
"type": "string",
"description": "Start of period (YYYYMMDD)"
},
"indicators": {
"type": "string",
"description": "Comma separated list of indicator names. ['hdd'|'cdd'|'wbcdd'|'gdd] (default: hdd,cdd,wbcdd)"
},
"base_temp_C": {
"type": "string",
"description": "Base temperature in °C for all indicators (default: 18.3)"
},
"is_forecast": {
"type": "string",
"description": "Forecast requested? (0|1) (default: 1)"
}
}
}| Unique Location Identifier |
| latlon | string | Latitude,Longitude ex: 40.78,-73.97 |
| baseline | string | Baseline period used to resolve sigma/percentile bounds, format YYYY_YYYY (default: 1991_2020) |
| criteria* | string | JSON array of criteria objects. Each criterion is either a numeric criterion {"metric":"<name>","bound_type":"A|S|P","lower_bound":<val>,"upper_bound":<val>,"must_have":true|false} where bound_type A=absolute (default bounds per metric), S=sigma (-4 to 4), P=percentile (0-100); or a condition criterion {"metric":"<is_* name>","state":"1|0","must_have":true|false}. Defaults: numeric metrics use their natural absolute range; S defaults to [-4,4]; P defaults to [0,100]. At least one must_have=true criterion required. |
| year_end | string | Year end (YYYY, inclusive) (default: 2026) |
| year_start | string | Year start (YYYY) (default: 2024) |
| month_day_end | string | Month-day end filter MMDD e.g. 0831 (Aug 31). Omit for full year. |
| month_day_start | string | Month-day start filter MMDD e.g. 0601 (June 1). Omit for full year. |
{
"type": "object",
"required": [
"criteria"
],
"properties": {
"name": {
"type": "string",
"description": "Location name, e.g. New York"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"baseline": {
"type": "string",
"description": "Baseline period used to resolve sigma/percentile bounds, format YYYY_YYYY (default: 1991_2020)"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria objects. Each criterion is either a numeric criterion {\"metric\":\"<name>\",\"bound_type\":\"A|S|P\",\"lower_bound\":<val>,\"upper_bound\":<val>,\"must_have\":true|false} where bound_type A=absolute (default bounds per metric), S=sigma (-4 to 4), P=percentile (0-100); or a condition criterion {\"metric\":\"<is_* name>\",\"state\":\"1|0\",\"must_have\":true|false}. Defaults: numeric metrics use their natural absolute range; S defaults to [-4,4]; P defaults to [0,100]. At least one must_have=true criterion required."
},
"year_end": {
"type": "string",
"description": "Year end (YYYY, inclusive) (default: 2026)"
},
"year_start": {
"type": "string",
"description": "Year start (YYYY) (default: 2024)"
},
"month_day_end": {
"type": "string",
"description": "Month-day end filter MMDD e.g. 0831 (Aug 31). Omit for full year."
},
"month_day_start": {
"type": "string",
"description": "Month-day start filter MMDD e.g. 0601 (June 1). Omit for full year."
}
}
}| season |
| string |
| Season filter as 'MM-MM' (e.g. '06-08' for Jun-Aug, '12-02' for Dec-Feb). Overridden by 'month' if both are set. |
| src_type | string | Data source: Obs (station observations) | ERA5 (reanalysis). ERA5 recommended for precipitation outside US. (default: Obs) |
| model_type | string | Statistical model: '' (empirical/default) | MLE (maximum likelihood estimate). |
| window_size | string | Rolling window in days. Temperature metrics (MAX_TEMP, MIN_TEMP, AVG_TEMP, DEWPH, WBULB, DPD): 1, 2, 3. Precipitation metrics (PRCP, SNOW, RAINH, SNOWH): 1, 2, 3, 4, 7. (default: 1) |
| exceedance_type | string | Exceedance direction: High (probability of exceeding value) | Low (probability of being below value). (default: High) |
| metric_category | string | Metric category. Values: AVG_TEMP, DEWPH, DPD, MAX_TEMP, MIN_TEMP, PRCP, RAINH, SNOW, SNOWH, WBULB, WIND. Example: MAX_TEMP for maximum temperature extremes. (default: MAX_TEMP) |
{
"type": "object",
"required": [],
"properties": {
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"level": {
"type": "string",
"description": "Aggregation level: city (single station) | area (nearby stations pooled). Use 'area' to improve period of record. (default: area)"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"month": {
"type": "string",
"description": "Two-digit month filter (e.g. '06' for June). Leave empty for all months."
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"season": {
"type": "string",
"description": "Season filter as 'MM-MM' (e.g. '06-08' for Jun-Aug, '12-02' for Dec-Feb). Overridden by 'month' if both are set."
},
"src_type": {
"type": "string",
"description": "Data source: Obs (station observations) | ERA5 (reanalysis). ERA5 recommended for precipitation outside US. (default: Obs)"
},
"model_type": {
"type": "string",
"description": "Statistical model: '' (empirical/default) | MLE (maximum likelihood estimate)."
},
"window_size": {
"type": "string",
"description": "Rolling window in days. Temperature metrics (MAX_TEMP, MIN_TEMP, AVG_TEMP, DEWPH, WBULB, DPD): 1, 2, 3. Precipitation metrics (PRCP, SNOW, RAINH, SNOWH): 1, 2, 3, 4, 7. (default: 1)"
},
"exceedance_type": {
"type": "string",
"description": "Exceedance direction: High (probability of exceeding value) | Low (probability of being below value). (default: High)"
},
"metric_category": {
"type": "string",
"description": "Metric category. Values: AVG_TEMP, DEWPH, DPD, MAX_TEMP, MIN_TEMP, PRCP, RAINH, SNOW, SNOWH, WBULB, WIND. Example: MAX_TEMP for maximum temperature extremes. (default: MAX_TEMP)"
}
}
}| seed | string | Any string. The sample of locations is drawn deterministically from it, so the same seed always returns the same locations. Every response reports the seed it used, including when one was not supplied, so any result can be reproduced exactly by sending that seed back. |
| limit | string | Maximum locations returned, 1 to 4000 (default: 500) |
| ctryid | string | Comma-separated ISO country codes from /api/countries, e.g. US,CA. Omit for a global query. This endpoint compares many locations and has no single-location argument; for one place use fcastevalbylocation |
| metric | string | Metric names are literal and case-sensitive. Never drop the 'obs.' segment and never drop the '.mean' suffix. The eight metrics are: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean (C); obs.rain.mean, obs.snow.mean (mm); obs.wind.mean, obs.gust.mean (km/hr). They are daily quantities: max_t.mean and min_t.mean are the day's high and low, obs.temp.mean the day's mean temperature, obs.dewp.mean the day's mean dew point, obs.rain.mean and obs.snow.mean the day's total precipitation and snowfall, obs.wind.mean the day's mean wind speed and obs.gust.mean the day's maximum gust. Exactly one metric per request. Full list: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean, obs.rain.mean, obs.snow.mean, obs.wind.mean, obs.gust.mean (default: obs.temp.mean) |
| models | string | Forecast models, given as comma-separated keys: auto (Open-Meteo's own per-location blend — what a caller gets by default), IFS (ECMWF IFS 0.25 degree, physical NWP), GFS (NCEP GFS), AIFS (ECMWF AIFS, machine-learned, deterministic), WN2 (Google WeatherNext 2, ensemble mean). Defaults to all of them. |
| ymd_end | string | Last day evaluated, YYYYMMDD, inclusive |
| lead_time | string | Forecast lead time in days. A lead time is how many days ahead the forecast was issued, so lead time 1 is yesterday's forecast for today and lead time 10 is a forecast made ten days before the day it describes. Only these lead times are indexed: 1, 2, 3, 5, 7, 10. Asking for any other lead time is an error, not an empty result. One value only here; use fcastevalbylocation to compare lead times. (default: 1) |
| threshold | string | Precipitation threshold in mm per day for the 'ets' eval metric, ignored otherwise. A day counts as a wet-day event when the total is at or above this. Useful rungs are 0.2, 1.0, 5.0, 10.0, 25.0. (default: 1.0) |
| ymd_start | string | Inclusive day range as YYYYMMDD. Defaults to the 14 days ending yesterday; today is never included because it has not been verified yet. At most 180 days, which is also how much history the index retains. |
| sample_pct | string | Percent of the world's locations to sample, from 0.1 to 100. Sampling is by stable hash bucket, so every location has an equal chance of being selected and the sample is unbiased by geography. The granularity is one bucket, which is 2.5 percent, and a request is rounded up to whole buckets; the response reports the sample_pct_effective actually served and the buckets drawn. Defaults to 5 percent for a global query, and to 100 when ctryid is given, because sampling exists to bound a world-sized scan and naming countries is already a restriction. |
| eval_metrics | string | Evaluation metrics, comma-separated, any of: 'mae' mean absolute error in the metric's own unit, lower is better; 'rmse' root mean squared error, same unit, lower is better, more sensitive to large misses than mae; 'mse' the same squared, lower is better; 'bias' mean signed error, positive means the model forecasts too high, zero is best; 'acc' anomaly correlation coefficient from -1 to 1, higher is better, which measures whether the model got the departure from the local seasonal normal right rather than just the absolute value, so a model that always forecasts the local average scores near zero however small its mae; 'ets' equitable threat score from -1/3 to 1, higher is better, the standard precipitation score, which is only valid for the accumulation metrics obs.rain.mean and obs.snow.mean and uses the threshold argument. Defaults to mae,rmse,acc. IMPORTANT for obs.rain.mean and obs.snow.mean: mae, rmse, mse and bias are measured on WET DAYS ONLY, meaning days where the observed total was at or above the threshold, because a daily rain total is zero on most days and an all-days average mostly measures days both sides correctly called dry. So for rain, mae answers 'when it actually rained, how far off was the amount' and n counts wet days, not days. ets still scores every day, wet and dry, because the dry days are what make it meaningful. For every other metric all scores use every day. A cell whose sample was too small is returned as null, never as zero. (default: mae,rmse,acc) |
{
"type": "object",
"required": [],
"properties": {
"seed": {
"type": "string",
"description": "Any string. The sample of locations is drawn deterministically from it, so the same seed always returns the same locations. Every response reports the seed it used, including when one was not supplied, so any result can be reproduced exactly by sending that seed back."
},
"limit": {
"type": "string",
"description": "Maximum locations returned, 1 to 4000 (default: 500)"
},
"ctryid": {
"type": "string",
"description": "Comma-separated ISO country codes from /api/countries, e.g. US,CA. Omit for a global query. This endpoint compares many locations and has no single-location argument; for one place use fcastevalbylocation"
},
"metric": {
"type": "string",
"description": "Metric names are literal and case-sensitive. Never drop the 'obs.' segment and never drop the '.mean' suffix. The eight metrics are: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean (C); obs.rain.mean, obs.snow.mean (mm); obs.wind.mean, obs.gust.mean (km/hr). They are daily quantities: max_t.mean and min_t.mean are the day's high and low, obs.temp.mean the day's mean temperature, obs.dewp.mean the day's mean dew point, obs.rain.mean and obs.snow.mean the day's total precipitation and snowfall, obs.wind.mean the day's mean wind speed and obs.gust.mean the day's maximum gust. Exactly one metric per request. Full list: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean, obs.rain.mean, obs.snow.mean, obs.wind.mean, obs.gust.mean (default: obs.temp.mean)"
},
"models": {
"type": "string",
"description": "Forecast models, given as comma-separated keys: auto (Open-Meteo's own per-location blend — what a caller gets by default), IFS (ECMWF IFS 0.25 degree, physical NWP), GFS (NCEP GFS), AIFS (ECMWF AIFS, machine-learned, deterministic), WN2 (Google WeatherNext 2, ensemble mean). Defaults to all of them."
},
"ymd_end": {
"type": "string",
"description": "Last day evaluated, YYYYMMDD, inclusive"
},
"lead_time": {
"type": "string",
"description": "Forecast lead time in days. A lead time is how many days ahead the forecast was issued, so lead time 1 is yesterday's forecast for today and lead time 10 is a forecast made ten days before the day it describes. Only these lead times are indexed: 1, 2, 3, 5, 7, 10. Asking for any other lead time is an error, not an empty result. One value only here; use fcastevalbylocation to compare lead times. (default: 1)"
},
"threshold": {
"type": "string",
"description": "Precipitation threshold in mm per day for the 'ets' eval metric, ignored otherwise. A day counts as a wet-day event when the total is at or above this. Useful rungs are 0.2, 1.0, 5.0, 10.0, 25.0. (default: 1.0)"
},
"ymd_start": {
"type": "string",
"description": "Inclusive day range as YYYYMMDD. Defaults to the 14 days ending yesterday; today is never included because it has not been verified yet. At most 180 days, which is also how much history the index retains."
},
"sample_pct": {
"type": "string",
"description": "Percent of the world's locations to sample, from 0.1 to 100. Sampling is by stable hash bucket, so every location has an equal chance of being selected and the sample is unbiased by geography. The granularity is one bucket, which is 2.5 percent, and a request is rounded up to whole buckets; the response reports the sample_pct_effective actually served and the buckets drawn. Defaults to 5 percent for a global query, and to 100 when ctryid is given, because sampling exists to bound a world-sized scan and naming countries is already a restriction."
},
"eval_metrics": {
"type": "string",
"description": "Evaluation metrics, comma-separated, any of: 'mae' mean absolute error in the metric's own unit, lower is better; 'rmse' root mean squared error, same unit, lower is better, more sensitive to large misses than mae; 'mse' the same squared, lower is better; 'bias' mean signed error, positive means the model forecasts too high, zero is best; 'acc' anomaly correlation coefficient from -1 to 1, higher is better, which measures whether the model got the departure from the local seasonal normal right rather than just the absolute value, so a model that always forecasts the local average scores near zero however small its mae; 'ets' equitable threat score from -1/3 to 1, higher is better, the standard precipitation score, which is only valid for the accumulation metrics obs.rain.mean and obs.snow.mean and uses the threshold argument. Defaults to mae,rmse,acc. IMPORTANT for obs.rain.mean and obs.snow.mean: mae, rmse, mse and bias are measured on WET DAYS ONLY, meaning days where the observed total was at or above the threshold, because a daily rain total is zero on most days and an all-days average mostly measures days both sides correctly called dry. So for rain, mae answers 'when it actually rained, how far off was the amount' and n counts wet days, not days. ets still scores every day, wet and dry, because the dry days are what make it meaningful. For every other metric all scores use every day. A cell whose sample was too small is returned as null, never as zero. (default: mae,rmse,acc)"
}
}
}| latlon | string | 'lat,lon' ex: 37.62,-122.4. Used if locid and name are absent |
| metric | string | Metric names are literal and case-sensitive. Never drop the 'obs.' segment and never drop the '.mean' suffix. The eight metrics are: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean (C); obs.rain.mean, obs.snow.mean (mm); obs.wind.mean, obs.gust.mean (km/hr). They are daily quantities: max_t.mean and min_t.mean are the day's high and low, obs.temp.mean the day's mean temperature, obs.dewp.mean the day's mean dew point, obs.rain.mean and obs.snow.mean the day's total precipitation and snowfall, obs.wind.mean the day's mean wind speed and obs.gust.mean the day's maximum gust. Exactly one metric per request. Full list: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean, obs.rain.mean, obs.snow.mean, obs.wind.mean, obs.gust.mean (default: obs.temp.mean) |
| models | string | Forecast models, given as comma-separated keys: auto (Open-Meteo's own per-location blend — what a caller gets by default), IFS (ECMWF IFS 0.25 degree, physical NWP), GFS (NCEP GFS), AIFS (ECMWF AIFS, machine-learned, deterministic), WN2 (Google WeatherNext 2, ensemble mean). Defaults to all of them. |
| window | string | Sliding window in days for the moving average. A 14 day range with a 7 day window yields 8 windows. Defaults to the whole range, which yields exactly one window |
| ymd_end | string | Last day evaluated, YYYYMMDD, inclusive |
| threshold | string | Precipitation threshold in mm per day for the 'ets' eval metric, ignored otherwise. A day counts as a wet-day event when the total is at or above this. Useful rungs are 0.2, 1.0, 5.0, 10.0, 25.0. (default: 1.0) |
| ymd_start | string | Inclusive day range as YYYYMMDD. Defaults to the 14 days ending yesterday; today is never included because it has not been verified yet. At most 180 days, which is also how much history the index retains. |
| lead_times | string | Comma-separated forecast lead times in days. A lead time is how many days ahead the forecast was issued, so lead time 1 is yesterday's forecast for today and lead time 10 is a forecast made ten days before the day it describes. Only these lead times are indexed: 1, 2, 3, 5, 7, 10. Asking for any other lead time is an error, not an empty result. They become the outermost axis of the evals structure, in ascending order. (default: 1) |
| eval_metrics | string | Evaluation metrics, comma-separated, any of: 'mae' mean absolute error in the metric's own unit, lower is better; 'rmse' root mean squared error, same unit, lower is better, more sensitive to large misses than mae; 'mse' the same squared, lower is better; 'bias' mean signed error, positive means the model forecasts too high, zero is best; 'acc' anomaly correlation coefficient from -1 to 1, higher is better, which measures whether the model got the departure from the local seasonal normal right rather than just the absolute value, so a model that always forecasts the local average scores near zero however small its mae; 'ets' equitable threat score from -1/3 to 1, higher is better, the standard precipitation score, which is only valid for the accumulation metrics obs.rain.mean and obs.snow.mean and uses the threshold argument. Defaults to mae,rmse,acc. IMPORTANT for obs.rain.mean and obs.snow.mean: mae, rmse, mse and bias are measured on WET DAYS ONLY, meaning days where the observed total was at or above the threshold, because a daily rain total is zero on most days and an all-days average mostly measures days both sides correctly called dry. So for rain, mae answers 'when it actually rained, how far off was the amount' and n counts wet days, not days. ets still scores every day, wet and dry, because the dry days are what make it meaningful. For every other metric all scores use every day. A cell whose sample was too small is returned as null, never as zero. (default: mae,rmse,acc) |
{
"type": "object",
"required": [],
"properties": {
"name": {
"type": "string",
"description": "Place name, e.g. 'San Francisco'. Ignored if locid is set"
},
"locid": {
"type": "string",
"description": "Location id from /api/location, e.g. 725030_14732"
},
"latlon": {
"type": "string",
"description": "'lat,lon' ex: 37.62,-122.4. Used if locid and name are absent"
},
"metric": {
"type": "string",
"description": "Metric names are literal and case-sensitive. Never drop the 'obs.' segment and never drop the '.mean' suffix. The eight metrics are: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean (C); obs.rain.mean, obs.snow.mean (mm); obs.wind.mean, obs.gust.mean (km/hr). They are daily quantities: max_t.mean and min_t.mean are the day's high and low, obs.temp.mean the day's mean temperature, obs.dewp.mean the day's mean dew point, obs.rain.mean and obs.snow.mean the day's total precipitation and snowfall, obs.wind.mean the day's mean wind speed and obs.gust.mean the day's maximum gust. Exactly one metric per request. Full list: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean, obs.rain.mean, obs.snow.mean, obs.wind.mean, obs.gust.mean (default: obs.temp.mean)"
},
"models": {
"type": "string",
"description": "Forecast models, given as comma-separated keys: auto (Open-Meteo's own per-location blend — what a caller gets by default), IFS (ECMWF IFS 0.25 degree, physical NWP), GFS (NCEP GFS), AIFS (ECMWF AIFS, machine-learned, deterministic), WN2 (Google WeatherNext 2, ensemble mean). Defaults to all of them."
},
"window": {
"type": "string",
"description": "Sliding window in days for the moving average. A 14 day range with a 7 day window yields 8 windows. Defaults to the whole range, which yields exactly one window"
},
"ymd_end": {
"type": "string",
"description": "Last day evaluated, YYYYMMDD, inclusive"
},
"threshold": {
"type": "string",
"description": "Precipitation threshold in mm per day for the 'ets' eval metric, ignored otherwise. A day counts as a wet-day event when the total is at or above this. Useful rungs are 0.2, 1.0, 5.0, 10.0, 25.0. (default: 1.0)"
},
"ymd_start": {
"type": "string",
"description": "Inclusive day range as YYYYMMDD. Defaults to the 14 days ending yesterday; today is never included because it has not been verified yet. At most 180 days, which is also how much history the index retains."
},
"lead_times": {
"type": "string",
"description": "Comma-separated forecast lead times in days. A lead time is how many days ahead the forecast was issued, so lead time 1 is yesterday's forecast for today and lead time 10 is a forecast made ten days before the day it describes. Only these lead times are indexed: 1, 2, 3, 5, 7, 10. Asking for any other lead time is an error, not an empty result. They become the outermost axis of the evals structure, in ascending order. (default: 1)"
},
"eval_metrics": {
"type": "string",
"description": "Evaluation metrics, comma-separated, any of: 'mae' mean absolute error in the metric's own unit, lower is better; 'rmse' root mean squared error, same unit, lower is better, more sensitive to large misses than mae; 'mse' the same squared, lower is better; 'bias' mean signed error, positive means the model forecasts too high, zero is best; 'acc' anomaly correlation coefficient from -1 to 1, higher is better, which measures whether the model got the departure from the local seasonal normal right rather than just the absolute value, so a model that always forecasts the local average scores near zero however small its mae; 'ets' equitable threat score from -1/3 to 1, higher is better, the standard precipitation score, which is only valid for the accumulation metrics obs.rain.mean and obs.snow.mean and uses the threshold argument. Defaults to mae,rmse,acc. IMPORTANT for obs.rain.mean and obs.snow.mean: mae, rmse, mse and bias are measured on WET DAYS ONLY, meaning days where the observed total was at or above the threshold, because a daily rain total is zero on most days and an all-days average mostly measures days both sides correctly called dry. So for rain, mae answers 'when it actually rained, how far off was the amount' and n counts wet days, not days. ets still scores every day, wet and dry, because the dry days are what make it meaningful. For every other metric all scores use every day. A cell whose sample was too small is returned as null, never as zero. (default: mae,rmse,acc)"
}
}
}| ymd_end | string | End date YYYYMMDD. Defaults to today. |
| ymd_start | string | Start date YYYYMMDD. Defaults to 15 days ago. |
| period_type | string | Period type. Values: DAY (US daily obs), FULL_DAY (non-US daily obs), FUTURE_DAY (forecast). (default: FULL_DAY) |
| history_years | string | Minimum years of history required to qualify as a record. Use >= 15 for meaningful records. (default: 5) |
{
"type": "object",
"required": [],
"properties": {
"scope": {
"type": "string",
"description": "Record scope. Values: month (monthly records), week (weekly records), year (annual records). (default: month)"
},
"ctryid": {
"type": "string",
"description": "Comma-separated country codes to filter (as returned by /api/countries)."
},
"metrics": {
"type": "string",
"description": "Applicable metrics. For period_type DAY: ('temp.max','temp.min', 'temp.mean', 'rain.mean', 'snow.mean', 'dewp.mean', 'wbulb.max', 'heatindex.max', 'wbgt.max', 'dpd.max','gust.max','wind.max','rainh.max')<br>For period_type FULL_DAY/FUTURE_DAY: ('max_t.mean','min_t.mean','temp.mean','rain.mean','snow.mean','dewp.mean','max_wind'.mean) (default: max_t.mean)"
},
"ymd_end": {
"type": "string",
"description": "End date YYYYMMDD. Defaults to today."
},
"ymd_start": {
"type": "string",
"description": "Start date YYYYMMDD. Defaults to 15 days ago."
},
"period_type": {
"type": "string",
"description": "Period type. Values: DAY (US daily obs), FULL_DAY (non-US daily obs), FUTURE_DAY (forecast). (default: FULL_DAY)"
},
"history_years": {
"type": "string",
"description": "Minimum years of history required to qualify as a record. Use >= 15 for meaningful records. (default: 5)"
}
}
}| limit | string | Results per page, 1 to 4000. 4000 covers every location in one page (default: 100) |
| locid | string | Location id from /api/location, e.g. 724940_23234 |
| ctryid | string | Comma-separated ISO country codes (mutually exclusive with latlon) |
| cursor | string | next_cursor from a previous response. Only valid with sort=locid; sending it with a ranked sort is an error |
| fields | string | 'full' for everything, 'compact' for locid/lat/lon/ym plus anom, norm and perc of the requested metrics only (default: full) |
| latlon | string | Centre of an area search as 'lat,lon' ex: 37.62,-122.4 |
| offset | string | Offset into a ranked result (any sort except locid). offset plus limit must be at most 4000. Use cursor, not offset, with sort=locid (default: 0) |
| ym_end | string | Last target month as YYYYMM, inclusive. Must be at least ym_start. Defaults to ym_start plus 5 months. |
| metrics | string | Comma-separated metrics to return: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean, obs.wind.mean, obs.rain.sum, obs.snow.sum. The metric named by sort is always returned as well, whether or not it is listed here. Defaults to all seven. |
| baseline | string | Baseline year range YYYY-YYYY (default: 1996-2025) |
| criteria | string | JSON array of criteria, passed as a string. Optional for this API: omit it to get every location for the requested months. Example: [{"metric":"norm:max_t.mean","lb":1.5,"must_have":true},{"metric":"perc:obs.rain.sum","ub":15,"must_have":true}] Each element has: metric (required, one of the exact names listed below), lb and ub (optional numeric lower/upper bounds), and must_have (true = hard filter every result must satisfy, false = optional, only used to rank). Metric names are literal and case-sensitive: a prefix plus the metric base plus '.' plus the attribute, e.g. norm:max_t.mean, perc:obs.rain.sum. Never drop the prefix and never drop the 'obs.' segment. The seven metrics are: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean (C); obs.wind.mean (km/h); obs.rain.sum, obs.snow.sum (mm). Filterable prefixes: 'norm:' = anomaly divided by that place's interannual standard deviation (|1| unusual, |2| strongly unusual, |3|+ rare); 'perc:' = percentile rank of the prediction among the last 30 years, 0 to 100 (90 = hotter/wetter than 90% of them, 50 = typical); 'anom:' = the absolute anomaly in natural units, which is not comparable between places. Prefer 'perc:' for obs.rain.sum and obs.snow.sum, whose year-to-year distributions are skewed, and note 'norm:' is absent where interannual variability is near zero. The 'avg:' and 'std:' attributes are returned for display but cannot be filtered on. Full list: anom:max_t.mean, anom:min_t.mean, anom:obs.temp.mean, anom:obs.dewp.mean, anom:obs.wind.mean, anom:obs.rain.sum, anom:obs.snow.sum, norm:max_t.mean, norm:min_t.mean, norm:obs.temp.mean, norm:obs.dewp.mean, norm:obs.wind.mean, norm:obs.rain.sum, norm:obs.snow.sum, perc:max_t.mean, perc:min_t.mean, perc:obs.temp.mean, perc:obs.dewp.mean, perc:obs.wind.mean, perc:obs.rain.sum, perc:obs.snow.sum |
| src_type | string | Forecast model to read: SEAS5 (ECMWF seasonal). SEAS5 is currently the only value, so this can be omitted. (default: SEAS5) |
| ym_start | string | First target month as YYYYMM, e.g. 202611. For a single month set ym_start and ym_end to the same value. Defaults to next month. |
| radius_km | string | Radius km for latlon, 1 to 2000 (default: 100) |
{
"type": "object",
"required": [],
"properties": {
"name": {
"type": "string",
"description": "Place name, e.g. 'San Francisco'. Ignored if locid is set"
},
"sort": {
"type": "string",
"description": "One of: 'criteria' (most optional criteria met first), 'locid' (id order, resumable with cursor), or an attribute name to rank by how far from normal it is: 'norm:METRIC' or 'perc:METRIC', e.g. norm:obs.rain.sum. Those are the same names used in criteria, and they order most-abnormal-first in either direction — use criteria to pick a direction (e.g. lb 0 for hotter than normal only). Defaults to criteria when criteria are given, otherwise locid."
},
"limit": {
"type": "string",
"description": "Results per page, 1 to 4000. 4000 covers every location in one page (default: 100)"
},
"locid": {
"type": "string",
"description": "Location id from /api/location, e.g. 724940_23234"
},
"ctryid": {
"type": "string",
"description": "Comma-separated ISO country codes (mutually exclusive with latlon)"
},
"cursor": {
"type": "string",
"description": "next_cursor from a previous response. Only valid with sort=locid; sending it with a ranked sort is an error"
},
"fields": {
"type": "string",
"description": "'full' for everything, 'compact' for locid/lat/lon/ym plus anom, norm and perc of the requested metrics only (default: full)"
},
"latlon": {
"type": "string",
"description": "Centre of an area search as 'lat,lon' ex: 37.62,-122.4"
},
"offset": {
"type": "string",
"description": "Offset into a ranked result (any sort except locid). offset plus limit must be at most 4000. Use cursor, not offset, with sort=locid (default: 0)"
},
"ym_end": {
"type": "string",
"description": "Last target month as YYYYMM, inclusive. Must be at least ym_start. Defaults to ym_start plus 5 months."
},
"metrics": {
"type": "string",
"description": "Comma-separated metrics to return: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean, obs.wind.mean, obs.rain.sum, obs.snow.sum. The metric named by sort is always returned as well, whether or not it is listed here. Defaults to all seven."
},
"baseline": {
"type": "string",
"description": "Baseline year range YYYY-YYYY (default: 1996-2025)"
},
"criteria": {
"type": "string",
"description": "JSON array of criteria, passed as a string. Optional for this API: omit it to get every location for the requested months. Example: [{\"metric\":\"norm:max_t.mean\",\"lb\":1.5,\"must_have\":true},{\"metric\":\"perc:obs.rain.sum\",\"ub\":15,\"must_have\":true}] Each element has: metric (required, one of the exact names listed below), lb and ub (optional numeric lower/upper bounds), and must_have (true = hard filter every result must satisfy, false = optional, only used to rank). Metric names are literal and case-sensitive: a prefix plus the metric base plus '.' plus the attribute, e.g. norm:max_t.mean, perc:obs.rain.sum. Never drop the prefix and never drop the 'obs.' segment. The seven metrics are: max_t.mean, min_t.mean, obs.temp.mean, obs.dewp.mean (C); obs.wind.mean (km/h); obs.rain.sum, obs.snow.sum (mm). Filterable prefixes: 'norm:' = anomaly divided by that place's interannual standard deviation (|1| unusual, |2| strongly unusual, |3|+ rare); 'perc:' = percentile rank of the prediction among the last 30 years, 0 to 100 (90 = hotter/wetter than 90% of them, 50 = typical); 'anom:' = the absolute anomaly in natural units, which is not comparable between places. Prefer 'perc:' for obs.rain.sum and obs.snow.sum, whose year-to-year distributions are skewed, and note 'norm:' is absent where interannual variability is near zero. The 'avg:' and 'std:' attributes are returned for display but cannot be filtered on. Full list: anom:max_t.mean, anom:min_t.mean, anom:obs.temp.mean, anom:obs.dewp.mean, anom:obs.wind.mean, anom:obs.rain.sum, anom:obs.snow.sum, norm:max_t.mean, norm:min_t.mean, norm:obs.temp.mean, norm:obs.dewp.mean, norm:obs.wind.mean, norm:obs.rain.sum, norm:obs.snow.sum, perc:max_t.mean, perc:min_t.mean, perc:obs.temp.mean, perc:obs.dewp.mean, perc:obs.wind.mean, perc:obs.rain.sum, perc:obs.snow.sum"
},
"src_type": {
"type": "string",
"description": "Forecast model to read: SEAS5 (ECMWF seasonal). SEAS5 is currently the only value, so this can be omitted. (default: SEAS5)"
},
"ym_start": {
"type": "string",
"description": "First target month as YYYYMM, e.g. 202611. For a single month set ym_start and ym_end to the same value. Defaults to next month."
},
"radius_km": {
"type": "string",
"description": "Radius km for latlon, 1 to 2000 (default: 100)"
}
}
}| hour_end | string | Hour End (00 to 24) (default: 24) |
| src_type | string | Data source type: Obs (station observations) | ERA5 (reanalysis gridded data) (default: Obs) |
| year_end | string | Year end YYYY (default: 2025) |
| hour_start | string | Hour Start (00 to 24) (default: 24) |
| year_start | string | Year start start YYYY (default: 1975) |
| month_day_end | string | Month day start MM[DD] |
| month_day_start | string | Month day start MM[DD] |
{
"type": "object",
"required": [
"metrics"
],
"properties": {
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"groupby": {
"type": "string",
"description": "Aggregating key: Year | Month | Week | Hour (default: Year)"
},
"metrics": {
"type": "string",
"description": "Comma separated list of tuple describing <i>aggregation function</i>:<i>metric_id</i>.<i>attribute</i> <br> ex: sum:obs.is_rain.count, avg:max_t.p99<br>agg_func = {sum,avg,min,max}. See /api/metrics for metric and attribtutes"
},
"hour_end": {
"type": "string",
"description": "Hour End (00 to 24) (default: 24)"
},
"src_type": {
"type": "string",
"description": "Data source type: Obs (station observations) | ERA5 (reanalysis gridded data) (default: Obs)"
},
"year_end": {
"type": "string",
"description": "Year end YYYY (default: 2025)"
},
"hour_start": {
"type": "string",
"description": "Hour Start (00 to 24) (default: 24)"
},
"year_start": {
"type": "string",
"description": "Year start start YYYY (default: 1975)"
},
"month_day_end": {
"type": "string",
"description": "Month day start MM[DD]"
},
"month_day_start": {
"type": "string",
"description": "Month day start MM[DD]"
}
}
}| lookback |
| string |
| Years looked back[1] (1 to 40) (default: 30) |
| ymd_start* | string | Start of period (YYYY[MMDD]) |
| hour_start | string | Hour Start (00 to 24) (default: 24) |
{
"type": "object",
"required": [
"ymd_start",
"ymd_end"
],
"properties": {
"name": {
"type": "string",
"description": "Common name of metro or metro area. for ex: New York, Beijing, Mumbai Airport"
},
"locid": {
"type": "string",
"description": "Unique Location Identifier"
},
"latlon": {
"type": "string",
"description": "Latitude,Longitude ex: 40.78,-73.97"
},
"ymd_end": {
"type": "string",
"description": "End of period (YYYY[MMDD])"
},
"hour_end": {
"type": "string",
"description": "Hour End (00 to 24) (default: 24)"
},
"lookback": {
"type": "string",
"description": "Years looked back[1] (1 to 40) (default: 30)"
},
"ymd_start": {
"type": "string",
"description": "Start of period (YYYY[MMDD])"
},
"hour_start": {
"type": "string",
"description": "Hour Start (00 to 24) (default: 24)"
}
}
}