WeatherCore Docs Get API key
API reference · v1

Build with the WeatherCore API.

A small, predictable JSON API: current conditions, a 16-day daily and hourly forecast, historical daily weather and derived alerts. Every endpoint is a GET that takes a latitude and longitude.

Base URL
https://weathercore-api.weathercore.workers.dev
Format
JSON over HTTPS, UTF-8

Authentication

Create a key in your dashboard and send it as a bearer token on every request.

Header
Authorization: Bearer wc_live_xxxxxxxxxxxxxxxxxxxxxxxx
  • Keys start with wc_live_. We store only a hash, so a lost key can't be recovered; revoke it and create a new one.
  • Keep keys on your server. The API allows browser calls from any origin, but a key in front-end code is visible to every visitor.
  • A missing, wrong or revoked key returns 401 unauthenticated.

Quickstart

Fetch a 7-day forecast for New York City.

curl -G "https://weathercore-api.weathercore.workers.dev/v1/forecast/daily" \
  -H "Authorization: Bearer $WEATHERCORE_KEY" \
  --data-urlencode "lat=40.7128" \
  --data-urlencode "lon=-74.006" \
  --data-urlencode "days=7"
const res = await fetch(
  "https://weathercore-api.weathercore.workers.dev/v1/forecast/daily?lat=40.7128&lon=-74.006&days=7",
  { headers: { Authorization: `Bearer ${process.env.WEATHERCORE_KEY}` } }
);
if (!res.ok) throw new Error((await res.json()).error.message);
const { forecast } = await res.json();
console.log(forecast[0].high, forecast[0].description);
import os, requests

r = requests.get(
    "https://weathercore-api.weathercore.workers.dev/v1/forecast/daily",
    params={"lat": 40.7128, "lon": -74.006, "days": 7},
    headers={"Authorization": f"Bearer {os.environ['WEATHERCORE_KEY']}"},
    timeout=10,
)
r.raise_for_status()
print(r.json()["forecast"][0])

Conventions

  • Units. Metric by default (°C, km/h, mm). Pass units=imperial for °F, mph and inches. The units object in each response tells you what you got.
  • Coordinates. Rounded to two decimals (about 1 km). The response echoes the grid point actually used in lat and lon.
  • Time. Dates and times in forecasts are local to the location, whose IANA name is in timezone. /v1/current also returns observedAt as a UTC ISO timestamp.
  • Nulls. A value the model doesn't provide is null, never omitted.
GET

/v1/current

Observed-style conditions for a coordinate right now, including the real UTC instant of the observation.

ParameterTypeRequiredDescription
latnumberrequiredLatitude, -90 to 90.
lonnumberrequiredLongitude, -180 to 180.
unitsstringoptionalmetric (default) or imperial.
200 OK · application/json
{
  "lat": 40.71,
  "lon": -74.01,
  "timezone": "America/New_York",
  "observedAt": "2026-10-15T18:00:00.000Z",
  "observedAtLocal": "2026-10-15T14:00",
  "temp": 16.8,
  "feelsLike": 15.2,
  "humidity": 58,
  "precipAmount": 0,
  "cloudCover": 88,
  "pressure": 1016.4,
  "windSpeed": 14.1,
  "windDirection": 250,
  "windGusts": 27.4,
  "isDay": true,
  "code": 3,
  "condition": "overcast",
  "description": "Overcast",
  "units": {
    "temperature": "°C",
    "wind": "km/h",
    "precipitation": "mm"
  }
}

pressure is mean sea-level pressure in hPa, windDirection is degrees (0–360, direction the wind comes from), cloudCover and humidity are percentages.

GET

/v1/forecast/daily

Up to 16 days of daily highs, lows, precipitation, wind, UV and sun times.

ParameterTypeRequiredDescription
latnumberrequiredLatitude, -90 to 90.
lonnumberrequiredLongitude, -180 to 180.
unitsstringoptionalmetric (default) or imperial.
daysintegeroptional1–16. Default 16. Out-of-range values are clamped.
200 OK · application/json
{
  "lat": 40.71,
  "lon": -74.01,
  "timezone": "America/New_York",
  "elevation": 10,
  "days": 2,
  "units": {
    "temperature": "°C",
    "wind": "km/h",
    "precipitation": "mm"
  },
  "forecast": [
    {
      "date": "2026-10-15",
      "code": 3,
      "condition": "overcast",
      "description": "Overcast",
      "high": 17.4,
      "low": 11.2,
      "precipChance": 20,
      "precipAmount": 0,
      "windMax": 18.5,
      "gustMax": 34.2,
      "uvIndexMax": 3.6,
      "sunrise": "2026-10-15T07:06",
      "sunset": "2026-10-15T18:00"
    },
    {
      "date": "2026-10-16",
      "code": 61,
      "condition": "rain",
      "description": "Slight rain",
      "high": 15.1,
      "low": 10.4,
      "precipChance": 65,
      "precipAmount": 4.2,
      "windMax": 22.7,
      "gustMax": 41.0,
      "uvIndexMax": 2.1,
      "sunrise": "2026-10-16T07:07",
      "sunset": "2026-10-16T17:58"
    }
  ]
}

precipChance can be null late in the window when the underlying model does not publish it. sunrise/sunset are local times at the location. Sample truncated to 2 of N days.

GET

/v1/forecast/hourly

Hour-by-hour forecast starting from the current hour.

ParameterTypeRequiredDescription
latnumberrequiredLatitude, -90 to 90.
lonnumberrequiredLongitude, -180 to 180.
unitsstringoptionalmetric (default) or imperial.
hoursintegeroptional1–384 (16 days). Default 48. Out-of-range values are clamped.
200 OK · application/json
{
  "lat": 40.71,
  "lon": -74.01,
  "timezone": "America/New_York",
  "hours": 2,
  "units": {
    "temperature": "°C",
    "wind": "km/h",
    "precipitation": "mm"
  },
  "hourly": [
    {
      "time": "2026-10-15T14:00",
      "hour": 14,
      "temp": 16.8,
      "feelsLike": 15.2,
      "humidity": 58,
      "precipChance": 10,
      "precipAmount": 0,
      "code": 3,
      "condition": "overcast",
      "description": "Overcast",
      "windSpeed": 14.1,
      "windGusts": 27.4
    },
    {
      "time": "2026-10-15T15:00",
      "hour": 15,
      "temp": 17.1,
      "feelsLike": 15.6,
      "humidity": 56,
      "precipChance": 10,
      "precipAmount": 0,
      "code": 2,
      "condition": "partly_cloudy",
      "description": "Partly cloudy",
      "windSpeed": 15.0,
      "windGusts": 28.8
    }
  ]
}

time is local to the location; hour is its 0–23 hour. Sample truncated to 2 of N hours.

GET

/v1/history

Daily observations from the ERA5 reanalysis archive for any date range up to 366 days per request.

ParameterTypeRequiredDescription
latnumberrequiredLatitude, -90 to 90.
lonnumberrequiredLongitude, -180 to 180.
unitsstringoptionalmetric (default) or imperial.
startdateoptionalYYYY-MM-DD. Default: 6 days before end.
enddateoptionalYYYY-MM-DD. Default: yesterday (UTC).
200 OK · application/json
{
  "lat": 40.71,
  "lon": -74.01,
  "timezone": "America/New_York",
  "start": "2026-10-08",
  "end": "2026-10-09",
  "units": {
    "temperature": "°C",
    "wind": "km/h",
    "precipitation": "mm"
  },
  "history": [
    {
      "date": "2026-10-08",
      "code": 2,
      "condition": "partly_cloudy",
      "description": "Partly cloudy",
      "high": 19.6,
      "low": 12.3,
      "precipAmount": 0,
      "windMax": 16.4
    },
    {
      "date": "2026-10-09",
      "code": 63,
      "condition": "rain",
      "description": "Moderate rain",
      "high": 16.2,
      "low": 11.8,
      "precipAmount": 9.7,
      "windMax": 24.9
    }
  ]
}

start must be on or before end, and the range can be at most 366 days. Sample truncated to 2 days.

GET

/v1/alerts

Threshold-based heads-ups computed from the next 16 days of forecast. These are not official government warnings, and the response says so.

ParameterTypeRequiredDescription
latnumberrequiredLatitude, -90 to 90.
lonnumberrequiredLongitude, -180 to 180.
200 OK · application/json
{
  "lat": 40.71,
  "lon": -74.01,
  "timezone": "America/New_York",
  "alerts": [
    {
      "id": "wind-2026-10-19",
      "type": "wind",
      "severity": "watch",
      "date": "2026-10-19",
      "title": "Strong wind gusts",
      "detail": "Gusts up to 56 km/h.",
      "value": 56,
      "threshold": 50
    }
  ],
  "derived": true,
  "disclaimer": "Generated automatically from forecast thresholds (heavy rain, heat, frost, wind, UV, thunderstorms). These are not official government warnings."
}

Thresholds are metric and this endpoint takes no units parameter. alerts is an empty array when nothing crosses a threshold.

Alert thresholds
typewatchwarningBased on
heavy_rain≥ 25 mm≥ 50 mmDaily precipitation total
heat≥ 35 °C≥ 38 °CDaily high
frost≤ 0 °C≤ -10 °CDaily low
wind≥ 50 km/h≥ 70 km/hDaily max gust
uv≥ 8≥ 11Daily max UV index
thunderstormcode 95code 96+Weather code (96+ means hail)

Condition codes

Each period carries a numeric WMO code, a stable condition key for your icons and logic, and a human description.

conditionWMO codeMeaning
clear0Clear sky
mostly_clear1Mainly clear
partly_cloudy2Partly cloudy
overcast3Overcast
fog45, 48Fog, depositing rime fog
drizzle51, 53, 55Light to dense drizzle
freezing_drizzle56, 57Freezing drizzle
rain61, 63, 65Slight to heavy rain
freezing_rain66, 67Freezing rain
snow71, 73, 75, 77Snow and snow grains
showers80, 81, 82Rain showers
snow_showers85, 86Snow showers
thunderstorm95Thunderstorm
thunderstorm_hail96, 99Thunderstorm with hail
unknown—Code not recognized

Rate limits

Quotas are per account per UTC day and reset at 00:00 UTC. Every authenticated call counts, including ones that return an error.

PlanDaily allowance
Developer1,000 calls / day
Startup100,000 calls / day
Business1,000,000 calls / day
Licensed accountsNot metered

Metered responses include these headers:

HeaderMeaning
X-RateLimit-LimitCalls allowed today.
X-RateLimit-RemainingCalls left today.
X-RateLimit-ResetUnix time (seconds) when the counter resets.
Retry-AfterSeconds to wait. Sent on 429 and 502 responses.

Errors

Errors use a normal HTTP status and a consistent body.

400 Bad Request
{
  "error": {
    "code": "invalid-argument",
    "message": "`lat` (-90 to 90) and `lon` (-180 to 180) are required query parameters."
  }
}
StatuscodeWhen
400invalid-argumentA parameter is missing or out of range. The message says which.
401unauthenticatedMissing, invalid or revoked API key.
429resource-exhaustedDaily quota reached. Check Retry-After.
502provider-unavailableUpstream weather data is unreachable or rate-limited. Retry after 30 s.
500internalUnexpected error on our side. Safe to retry.
401 Unauthorized
{
  "error": {
    "code": "unauthenticated",
    "message": "Missing, invalid, or revoked API key."
  }
}
429 Too Many Requests
{
  "error": {
    "code": "resource-exhausted",
    "message": "Daily quota of 1,000 calls reached for your plan. It resets at 00:00 UTC; upgrade your plan for a higher limit."
  }
}
502 Bad Gateway
{
  "error": {
    "code": "provider-unavailable",
    "message": "The weather data provider is unreachable. Please retry shortly."
  }
}

Try it

Call the live API from your browser and see the exact response. Your key is sent only to the API and is never stored.

No key yet? Create one in the dashboard.