Push readings as JSON
A documented JSON format for feeding a Pro Weather site from a script, a Raspberry Pi or a home-built sensor with no weather-station firmware.
For a script, a Raspberry Pi or a home-built sensor, POST JSON to your upload URL with a JSON content type:
curl -X POST https://pro-weather.com/api/ingest/YOUR-INGEST-TOKEN \
-H 'Content-Type: application/json' \
-d '{
"units": { "temperature": "C", "windspeed": "kph", "rainfall": "mm", "pressure": "hPa" },
"lastupdated": "2026-08-07T14:30:00Z",
"temperature": { "outdoor": 18.4, "indoor": 21.0 },
"humidity": { "outdoor": 67 },
"wind": { "speed": 11.2, "direction": 213, "gust10m": 24.0 },
"rain": { "counter": 812.4, "rate": 0.0 },
"pressure": { "sealevel": 1013.2, "absolute": 998.4 },
"solar": { "irradiation": 286, "uvi": 2 }
}'An accepted reading returns success. A payload with no usable reading returns
HTTP 400.
Declare your units
Say what units you send and we convert. A value whose unit is missing or not recognised is dropped, never guessed: a temperature read in the wrong scale is worse than none. The rest of the payload still lands.
| Group | Accepted values |
|---|---|
temperature | C, F |
windspeed | mph, ms, kph, knots |
rainfall | mm, cm, in |
pressure | hPa, mb, kPa, inHg |
lightning | km, mi |
laserdist | mm, cm, in |
soilmoisture | % (the default; any other unit drops the readings) |
Fields
Everything is optional, but send at least one of outdoor temperature, humidity, wind speed, sea-level pressure, rain, solar radiation or PM2.5. A field you leave out means "no sensor", not zero.
| Field | Contents |
|---|---|
lastupdated | ISO 8601 or unix seconds. Anything unreadable falls back to arrival time. |
temperature | outdoor, indoor, dewpoint |
humidity | outdoor, indoor (percent) |
wind | speed, gust10m, direction (degrees) |
rain | counter (a running total, see below), year, rate (per hour) |
pressure | sealevel, absolute |
solar | irradiation (W/m²), uvi |
co2 | co2, co2_24h, pm2p5, pm2p5avg24h, pm10, pm10avg24h, temperature, humidity |
lightning | distance, strikes (a running total), time |
rain.counter and lightning.strikes are running totals, not today's figure.
Today's rain and strike count are worked out from the difference between
uploads and reset at your station's local midnight, so the first upload only
sets the starting point. A counter that resets itself at midnight works too.
Multi-channel sensors are arrays, each entry with its own index (1-16):
| Field | Entry shape |
|---|---|
extratemp | { index, temperature, humidity } |
usertemp | { index, temperature } |
soiltemp | { index, temperature } |
soilmoisture | { index, value } (percent) |
leafwetness | { index, value } |
airquality | { index, pm2p5, pm2p5avg24h, pm10, pm10avg24h } (PM10 on channel 1 only) |
laserdist | { index, range, depth } (snow depth sensors, channels 1-4) |
Good to know
- Dew point, feels-like and cloud base are calculated for you. A dew point you send wins over the calculated one.
- A reading outside a plausible range is dropped on its own, so one stuck channel cannot spoil the whole upload.
- Once a minute is plenty. More than about one upload every 4 seconds is rate-limited (HTTP 429). The archive keeps one reading about every 4 minutes however often you post.
- The format matches the JSON station format documented for CumulusMX, so a sender that already emits it can point here unchanged.
Connect through a vendor cloud
Connect an Ecowitt or WeatherFlow Tempest station through its vendor cloud with an API key: nothing to set up on the station, and your history comes too.
Import your weewx history
Bring years of weewx history into Pro Weather - the database is read in your browser, and re-running is safe.
