API Access
This guide demonstrates how to access Jua's weather forecasts through our REST API.
Setting up Authentication
All API requests require authentication using the X-API-Key
header in the format {API_KEY_ID}:{API_SECRET}
. Here's how to set it up:
API_KEY_ID = os.environ["JUA_API_KEY_ID"]
API_SECRET = os.environ["JUA_API_SECRET"]
AUTH_HEADER = {"X-API-Key": f"{API_KEY_ID}:{API_SECRET}"}
The examples below assume you have already set up the AUTH_HEADER
as shown above.
Check forecast availability and timing
To check which forecast hours are currently available, use this API endpoint:
requests.get("https://api.jua.ai/v1/forecasting/ept1_5/forecasts/latest", headers=AUTH_HEADER).json()
Which will return the following fields:
forecast_url
: A link to the specific forecast.model_id
: The model that was used to generate the forecast.init_time
: The initial conditions timestamp.available_forecasted_hours
: The number of hours, after the init_time, that have been forecasted.available_variables
: The available variables for this forecast.
Forecast Data
Single Point Request
Our REST API gives access to the forecast at a single point:
requests.get("https://api.jua.ai/v1/forecasting/ept1_5/forecasts/latest/47.38,8.52", headers=AUTH_HEADER).json()
For more information about available models and endpoints, please see our Release Notes.
By default, this request will return all available variables and only the first 24 hours of the forecast. Here is an example of requesting a single variable for a longer time range:
requests.get("https://api.jua.ai/v1/forecasting/ept1_5/forecasts/latest/47.38,8.52?variables=air_temperature_2m&max_lead_time=48", headers=AUTH_HEADER).json()
Multiple Points Request
If you're interested in more than one location, use the POST endpoint to retrieve up to 25 locations in a single request:
response = requests.post(
"https://api.jua.ai/v1/forecasting/ept1_5/forecasts/latest",
json={
"min_lead_time": 48,
"max_lead_time": 96,
"points": [
{"lat": 48.857, "lon": 2.352}, # Paris
{"lat": 52.520, "lon": 3.405}, # Amsterdam
{"lat": 40.417, "lon": -3.703}, # Madrid
],
"variables": [
"air_temperature_at_height_level_2m",
"wind_speed_at_height_level_100m"
]
},
headers=AUTH_HEADER
)
Response Notes
The server returns the nearest available points to what have been requested. For example, if you request (48.857, 2.352), it will return the values at (48.829, 2.351). The
returned_latlon
field lists the actual returned locations.If you request more hours than what is currently available from the latest forecast (because the forecast is currently disseminating), then the response will contain all of the available data only.
The variables and units are documented in:
Real-World Example
Get 100m wind speed at 4 locations in Germany
import os
import requests
import matplotlib.pyplot as plt
import pandas as pd
from datetime import datetime, timezone
# Authentication
API_KEY_ID = os.environ["JUA_API_KEY_ID"]
API_SECRET = os.environ["JUA_API_SECRET"]
AUTH_HEADER = {"X-API-Key": f"{API_KEY_ID}:{API_SECRET}"}
VARIABLES = ["wind_speed_at_height_level_100m"]
LOCATIONS= [
{"name": "Berlin", "lat": 52.52, "lon": 13.41},
{"name": "Hamburg", "lat": 53.55, "lon": 10.00},
{"name": "Munich", "lat": 48.14, "lon": 11.58},
{"name": "Frankfurt", "lat": 50.11, "lon": 8.68}
]
# Request data for 4 German cities
response = requests.post(
"https://api.jua.ai/v1/forecasting/ept1_5/forecasts/latest",
json={
"min_lead_time": 0,
"max_lead_time": 120,
"points": LOCATIONS,
"variables": VARIABLES
},
headers=AUTH_HEADER
)
data = response.json()['forecast']
# Create DataFrames for plotting
dfs = {}
init_time = datetime.fromisoformat(data["init_time"].replace("Z", "+00:00"))
# Process each location
for i, point in enumerate(data["points"]):
# match location to city
city_name = LOCATIONS[i]["name"]
values = point[VARIABLES].indexOf
timestamps = [init_time.replace(tzinfo=timezone.utc) + pd.Timedelta(hours=h) for h in range(len(values))]
# Create DataFrame
dfs[city_name] = pd.DataFrame({
'timestamp': timestamps,
'wind_speed': values
})
# Plot the data
plt.figure(figsize=(12, 6))
for city, df in dfs.items():
plt.plot(df['timestamp'], df['wind_speed'], label=city)
plt.title(f'100m Wind Speed Forecast - Init: {init_time.strftime("%Y-%m-%d %H:%M")} UTC')
plt.xlabel('Time (UTC)')
plt.ylabel('Wind Speed (m/s)')
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.savefig('wind_forecast.png')
plt.show()
If you have any further questions, please have a look at our FAQ or reach out to us at [email protected].
Last updated