Base URL
https://api.withleaf.io/services/weather/api
Endpoints
| Description | Method | Path |
|---|---|---|
| Get daily forecast (field) | GET | /users/{leafUserId}/weather/forecast/field/{fieldId}/daily |
| Get hourly forecast (field) | GET | /users/{leafUserId}/weather/forecast/field/{fieldId}/hourly |
| Get daily forecast (lat/lon) | GET | /weather/forecast/daily/{lat},{lon} |
| Get hourly forecast (lat/lon) | GET | /weather/forecast/hourly/{lat},{lon} |
| Get daily historical (field) | GET | /users/{leafUserId}/weather/historical/field/{fieldId}/daily |
| Get hourly historical (field) | GET | /users/{leafUserId}/weather/historical/field/{fieldId}/hourly |
| Get daily historical (lat/lon) | GET | /weather/historical/daily/{lat},{lon} |
| Get hourly historical (lat/lon) | GET | /weather/historical/hourly/{lat},{lon} |
Daily endpoints accept a maximum range of 366 days per request. Hourly endpoints accept a maximum of 30 days.
Historical data less than 5 days old is unavailable. Use the forecast endpoints for recent weather data.
Field-based endpoints
These endpoints retrieve weather data centered on a Leaf user’s field. The API uses the field’s centroid coordinates automatically.Get daily forecast (field)
GET/users/{leafUserId}/weather/forecast/field/{fieldId}/daily
Returns daily forecast weather data for a field.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| leafUserId | string | path | Yes | UUID of the Leaf user. |
| fieldId | string | path | Yes | UUID of the field. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Forecast model: gfs (default), icon, ifs, metNordic, jma, gem, arpegeArome. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/users/{leafUserId}/weather/forecast/field/{fieldId}/daily?startTime=2026-03-09&endTime=2026-03-15'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = (
"https://api.withleaf.io/services/weather/api"
"/users/{leafUserId}/weather/forecast/field/{fieldId}/daily"
)
params = {"startTime": "2026-03-09", "endTime": "2026-03-15"}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api" +
"/users/{leafUserId}/weather/forecast/field/{fieldId}/daily";
axios
.get(url, { headers, params: { startTime: "2026-03-09", endTime: "2026-03-15" } })
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"date": "2026-03-09",
"temperatureMax": 18.2,
"temperatureMin": 6.4,
....
},
{
"date": "2026-03-10",
"temperatureMax": 20.1,
"temperatureMin": 7.8,
....
}
]
Get hourly forecast (field)
GET/users/{leafUserId}/weather/forecast/field/{fieldId}/hourly
Returns hourly forecast weather data for a field.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| leafUserId | string | path | Yes | UUID of the Leaf user. |
| fieldId | string | path | Yes | UUID of the field. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Forecast model: gfs (default), icon, ifs, metNordic, jma, gem, arpegeArome. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/users/{leafUserId}/weather/forecast/field/{fieldId}/hourly?startTime=2026-03-09&endTime=2026-03-10'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = (
"https://api.withleaf.io/services/weather/api"
"/users/{leafUserId}/weather/forecast/field/{fieldId}/hourly"
)
params = {"startTime": "2026-03-09", "endTime": "2026-03-10"}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api" +
"/users/{leafUserId}/weather/forecast/field/{fieldId}/hourly";
axios
.get(url, { headers, params: { startTime: "2026-03-09", endTime: "2026-03-10" } })
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"timestamp": "2026-03-09T00:00:00Z",
"temperature": 12.3,
"humidity": 65,
....
},
{
"timestamp": "2026-03-09T01:00:00Z",
"temperature": 11.8,
"humidity": 68,
....
}
]
Get daily historical (field)
GET/users/{leafUserId}/weather/historical/field/{fieldId}/daily
Returns daily historical weather data for a field.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| leafUserId | string | path | Yes | UUID of the Leaf user. |
| fieldId | string | path | Yes | UUID of the field. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Historical model: era5 (default) or era5Land. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/users/{leafUserId}/weather/historical/field/{fieldId}/daily?startTime=2025-06-01&endTime=2025-06-30'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = (
"https://api.withleaf.io/services/weather/api"
"/users/{leafUserId}/weather/historical/field/{fieldId}/daily"
)
params = {"startTime": "2025-06-01", "endTime": "2025-06-30"}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api" +
"/users/{leafUserId}/weather/historical/field/{fieldId}/daily";
axios
.get(url, { headers, params: { startTime: "2025-06-01", endTime: "2025-06-30" } })
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"date": "2025-06-01",
"temperatureMax": 29.4,
"temperatureMin": 17.1,
....
},
{
"date": "2025-06-02",
"temperatureMax": 31.0,
"temperatureMin": 18.6,
....
}
]
Get hourly historical (field)
GET/users/{leafUserId}/weather/historical/field/{fieldId}/hourly
Returns hourly historical weather data for a field.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| leafUserId | string | path | Yes | UUID of the Leaf user. |
| fieldId | string | path | Yes | UUID of the field. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Historical model: era5 (default) or era5Land. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/users/{leafUserId}/weather/historical/field/{fieldId}/hourly?startTime=2025-06-01&endTime=2025-06-02'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = (
"https://api.withleaf.io/services/weather/api"
"/users/{leafUserId}/weather/historical/field/{fieldId}/hourly"
)
params = {"startTime": "2025-06-01", "endTime": "2025-06-02"}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api" +
"/users/{leafUserId}/weather/historical/field/{fieldId}/hourly";
axios
.get(url, { headers, params: { startTime: "2025-06-01", endTime: "2025-06-02" } })
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"timestamp": "2025-06-01T00:00:00Z",
"temperature": 22.1,
"humidity": 55,
....
},
{
"timestamp": "2025-06-01T01:00:00Z",
"temperature": 21.5,
"humidity": 58,
....
}
]
Lat/lon endpoints
These endpoints retrieve weather data for an arbitrary latitude/longitude pair. They support additionalmodel and units query parameters.
Get daily forecast (lat/lon)
GET/weather/forecast/daily/{lat},{lon}
Returns daily forecast weather data for a coordinate pair.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| lat | number | path | Yes | Latitude coordinate. |
| lon | number | path | Yes | Longitude coordinate. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Forecast model: gfs (default), icon, ifs, metNordic, jma, gem, arpegeArome. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/weather/forecast/daily/39.7128,-86.1580?startTime=2026-03-09&endTime=2026-03-15&model=gfs&units=metric'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = "https://api.withleaf.io/services/weather/api/weather/forecast/daily/39.7128,-86.1580"
params = {
"startTime": "2026-03-09",
"endTime": "2026-03-15",
"model": "gfs",
"units": "metric",
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api/weather/forecast/daily/39.7128,-86.1580";
axios
.get(url, {
headers,
params: { startTime: "2026-03-09", endTime: "2026-03-15", model: "gfs", units: "metric" },
})
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"date": "2026-03-09",
"temperatureMax": 15.6,
"temperatureMin": 3.2,
....
},
{
"date": "2026-03-10",
"temperatureMax": 17.0,
"temperatureMin": 4.8,
....
}
]
Get hourly forecast (lat/lon)
GET/weather/forecast/hourly/{lat},{lon}
Returns hourly forecast weather data for a coordinate pair.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| lat | number | path | Yes | Latitude coordinate. |
| lon | number | path | Yes | Longitude coordinate. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Forecast model: gfs (default), icon, ifs, metNordic, jma, gem, arpegeArome. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/weather/forecast/hourly/39.7128,-86.1580?startTime=2026-03-09&endTime=2026-03-10&model=gfs&units=metric'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = "https://api.withleaf.io/services/weather/api/weather/forecast/hourly/39.7128,-86.1580"
params = {
"startTime": "2026-03-09",
"endTime": "2026-03-10",
"model": "gfs",
"units": "metric",
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api/weather/forecast/hourly/39.7128,-86.1580";
axios
.get(url, {
headers,
params: {
startTime: "2026-03-09",
endTime: "2026-03-10",
model: "gfs",
units: "metric",
},
})
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"timestamp": "2026-03-09T00:00:00Z",
"temperature": 8.4,
"humidity": 72,
....
},
{
"timestamp": "2026-03-09T01:00:00Z",
"temperature": 7.9,
"humidity": 74,
....
}
]
Get daily historical (lat/lon)
GET/weather/historical/daily/{lat},{lon}
Returns daily historical weather data for a coordinate pair.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| lat | number | path | Yes | Latitude coordinate. |
| lon | number | path | Yes | Longitude coordinate. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Historical model: era5 (default) or era5Land. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/weather/historical/daily/39.7128,-86.1580?startTime=2025-06-01&endTime=2025-06-30&model=era5&units=metric'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = "https://api.withleaf.io/services/weather/api/weather/historical/daily/39.7128,-86.1580"
params = {
"startTime": "2025-06-01",
"endTime": "2025-06-30",
"model": "era5",
"units": "metric",
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api/weather/historical/daily/39.7128,-86.1580";
axios
.get(url, {
headers,
params: { startTime: "2025-06-01", endTime: "2025-06-30", model: "era5", units: "metric" },
})
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"date": "2025-06-01",
"temperatureMax": 30.2,
"temperatureMin": 18.4,
....
},
{
"date": "2025-06-02",
"temperatureMax": 28.7,
"temperatureMin": 17.9,
....
}
]
Get hourly historical (lat/lon)
GET/weather/historical/hourly/{lat},{lon}
Returns hourly historical weather data for a coordinate pair.
Parameters
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
| lat | number | path | Yes | Latitude coordinate. |
| lon | number | path | Yes | Longitude coordinate. |
| startTime | string | query | No | Start date in YYYY-MM-DD format. |
| endTime | string | query | No | End date in YYYY-MM-DD format. |
| model | string | query | No | Historical model: era5 (default) or era5Land. |
| units | string | query | No | Unit system: metric (default) or imperial. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/weather/api/weather/historical/hourly/39.7128,-86.1580?startTime=2025-06-01&endTime=2025-06-02&model=era5&units=metric'
import requests
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
url = "https://api.withleaf.io/services/weather/api/weather/historical/hourly/39.7128,-86.1580"
params = {
"startTime": "2025-06-01",
"endTime": "2025-06-02",
"model": "era5",
"units": "metric",
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require("axios");
const TOKEN = "YOUR_TOKEN";
const headers = { Authorization: `Bearer ${TOKEN}` };
const url =
"https://api.withleaf.io/services/weather/api/weather/historical/hourly/39.7128,-86.1580";
axios
.get(url, {
headers,
params: {
startTime: "2025-06-01",
endTime: "2025-06-02",
model: "era5",
units: "metric",
},
})
.then((res) => console.log(res.data))
.catch(console.error);
Response
[
{
"timestamp": "2025-06-01T00:00:00Z",
"temperature": 22.1,
"humidity": 55,
....
},
{
"timestamp": "2025-06-01T01:00:00Z",
"temperature": 21.5,
"humidity": 58,
....
}
]
Models reference
Forecast models
| Model | Description |
|---|---|
gfs | Global Forecast System (default) |
icon | ICON by DWD |
ifs | IFS by ECMWF |
metNordic | MET Nordic by MET Norway |
jma | JMA by Japan Meteorological Agency |
gem | GEM by Environment Canada |
arpegeArome | ARPEGE/AROME by Meteo-France |
Historical models
| Model | Description |
|---|---|
era5 | ERA5 reanalysis (default) |
era5Land | ERA5-Land reanalysis (higher resolution) |
Use
era5Land when you need finer spatial resolution for land-surface variables like soil temperature and soil moisture.
