-
Notifications
You must be signed in to change notification settings - Fork 3
API documentation
This file describes the API used in this repository to get the weather data.
The API is not publicly documented and has been reversed engineered using the Android app be.irm.kmi.meteo
.
Data available for the following countries: Belgium, The Netherlands and Luxembourg.
Please be mindful if you plan to use this API:
- This is not a publicly documented API: behavior could change without notice
- Avoid spamming: this integration refreshes the data every 7 minutes by default
- Make your client identifiable: this integration uses the following HTTP header
User-Agent: github.com/jdejaegh/irm-kmi-ha
This is a personal project and isn't in any way affiliated with, sponsored or endorsed by The Royal Meteorological Institute of Belgium.
API endpoint: https://app.meteo.be/services/appv4/
Operations and parameters are passed using a query string. All requests are HTTP GET requests.
Example: GET https://app.meteo.be/services/appv4/?l=fr&s=searchCities&n=Bru
method name | description |
---|---|
getForecasts |
Main operation to get current weather as well as hourly and daily forecast |
searchCities |
Search a city to get its city code (used to get forecasts) |
getWarnings |
Get a global list of all warnings, for the three countries |
getIncaImage |
Get precipitation radar image (observation and forecast) |
getLocalizationLayer |
Get image with a dot at the given coordinates (for radar animation) |
getSvg |
Get SVG graph for max temp, min temp and rain for 14-days forecast |
getCommunesPerProvince |
Lists all municipalities in the specified province (why not?) |
Not all parameters are used for each method. There are other parameters, but they seem useless (they can be omitted without modifying the output).
parameter name | type | description | example |
---|---|---|---|
s |
string | operation to perform (see Available operations) | getForecasts |
l |
string | language for the response | fr |
lat |
float | latitude (avoid putting lots of decimals) | 51.2213 |
long |
float | longitude (avoid putting lots of decimals) | 4.4051 |
th |
string | theme modifier (d for day theme, n for night theme) |
n |
rs |
int | other theme modifier | 1 |
ins |
int | city number (different from postal code) | 92094 |
i |
string | date and time | 202412301830 |
k |
string | key to use the service (md5 hex-encoded, changes based on time and method) | 53355e94f33c3abba785ecc064a17a55 |
The key for the parameter k
is required for most methods.
The key is generated by MD5 hashing the following values, separated by semicolon: r9EnW374jkJ9acc
, method name and today's date (dd/mm/yyyy).
The following Python snippet is an example:
import hashlib
hashlib.md5("r9EnW374jkJ9acc;getForecasts;31/12/2024".encode()).hexdigest()
This section briefly describes what each method returns and how the parameters are used.
As you will notice, some values that are integers or floats are sometimes returned as strings. Keep that in mind when using the values.
Required parameters: s
, k
, and either lat
and long
or ins
Optional parameters: l
(seems to default to English)
Example: GET https://app.meteo.be/services/appv4/?lat=51.2213&long=4.4051&k=585940aff31585bcfff7f3aa0dc290de&s=getForecasts
Output schema is as follows. Some full examples can be found in the tests/fixtures
folder (example)
{
"cityName": "Antwerp",
"country": "BE",
"obs": {},
"for": {},
"module": [],
"animation": [],
"todayObsCount": 569
}
The keys cityName
and country
are self-explanatory.
The cityName
key is subject to translation according to the l
parameter (could have been Anvers or Antwerpen here).
The key todayObsCount
indicates how many observations the users of the application submitted today.
Other keys have their own section below
Give the current weather observation, with temperature (in Celsius) and weather condition.
Example
{
"temp": 6,
"timestamp": "2024-12-30T14:50:00+01:00",
"ww": 15,
"dayNight": "d"
}
The combination of ww
and dayNight
(d
if the sun is above the horizon, n
if below) determines which icon is shown for the weather condition.
Table with icons matching
ww-dayNight | icon |
---|---|
0-d |
|
0-n |
|
10-d |
|
10-n |
|
11-d |
|
11-n |
|
12-d |
|
12-n |
|
13-d |
|
13-n |
|
14-d |
|
14-n |
|
15-d |
|
15-n |
|
16-d |
|
16-n |
|
17-d |
|
17-n |
|
18-d |
|
18-n |
|
19-d |
|
19-n |
|
1-d |
|
1-n |
|
20-d |
|
20-n |
|
21-d |
|
21-n |
|
22-d |
|
22-n |
|
23-d |
|
23-n |
|
24-d |
|
24-n |
|
25-d |
|
25-n |
|
26-d |
|
26-n |
|
27-d |
|
27-n |
|
2-d |
|
2-n |
|
3-d |
|
3-n |
|
4-d |
|
4-n |
|
5-d |
|
5-n |
|
6-d |
|
6-n |
|
7-d |
|
7-n |
|
8-d |
|
8-n |
|
9-d |
|
9-n |
This key provides information about daily and hourly forecasts, as well as warnings for the current location.
The list in for.daily
is sorted by time: today is the first element of the list. The list may also contain one element for the next (or current) night prevision.
It generally contains 7 days of forecast.
Example of list item
{
"dayName": {"fr": "Lundi", "nl": "Maandag", "en": "Monday", "de": "Montag"},
"period": "1",
"day_night": "1",
"dayNight": "d",
"text": {
"nl": "Deze namiddag...",
"fr": "Cette après-midi..."
},
"dawnRiseSeconds": "31500",
"dawnSetSeconds": "60360",
"tempMin": null,
"tempMax": 7,
"ww1": 15,
"ww2": null,
"wwevol": null,
"ff1": 4,
"ff2": null,
"ffevol": null,
"dd": 45,
"ddText": {"fr": "SO", "nl": "ZW", "en": "SW", "de": "SW"},
"wind": {
"speed": 20,
"peakSpeed": null,
"dir": 45,
"dirText": { "fr": "SO", "nl": "ZW", "en": "SW", "de": "SW"}
},
"precipChance": 0,
"precipQuantity": "0"
}
Note that no matter the language set by the parameter l
, all the languages will be present in the output show here.
-
dayName
is self-explanatory. -
period
: ? -
day_night
anddayNight
: are1
andd
respectively when the forecast is for daytime; are0
andn
respectively when the forecast is for nighttime. -
text
: gives weather forecast in plain language, for Dutch en French only. -
dawnRiseSeconds
anddawnSetSeconds
: sunrise and sunset time in seconds after midnight that day. -
tempMin
andtempMax
: minimum and maximum temperature. Minimum isnull
when not relevant anymore (in the today's forecast when it's the afternoon) -
ww1
andww2
: weather condition, which, in combination withday_night
, give the icon to show (see table inobs
key section). Two values may be given if the condition is forecasted to change during the day. -
wwevol
: how the condition will evolve betweenww1
andww2
. Nonnull
only ifww2
is nonnull
. Values are null or integer, but I did not investigate what they produce in the app.
In this image, the partly cloudy icon is given by ww1
, the rainy icon is given by ww2
and the double arrow is given by wwevol
.
-
ff1
,ff2
andffevol
: ? -
dd
andwind.dir
: wind direction, but WATCH OUT! To get the real direction (where the wind is coming from), you have to do:(dd + 180) mod 360
. They use that value to rotate an arrow that defaults to north (when dd=0), hence the trick. -
ddText
andwind.dirText
: wind direction (no trick here) -
wind.speed
andwind.peakSpeed
: forecasted wind speed and wind gusts speed (if any, might benull
), in km/h. -
precipChance
: precipitation probability in percents (between 0 and 100) -
precipQuantity
: forecasted amount of precipitation in mm/m²
The list in for.hourly
is sorted by time: current hour is the first element of the list.
It generally contains 48 hours of forecast.
Example of list item
{
"hour": "14",
"dayNight": "d",
"temp": 7,
"ww": "15",
"precipChance": "0",
"precipQuantity": 0,
"pressure": 1028,
"windSpeedKm": 25,
"windPeakSpeedKm": null,
"windDirection": 23,
"windDirectionText": {"nl": "ZZW", "fr": "SSO", "en": "SSW", "de": "SSW"}
}
Note that no matter the language set by the parameter l
, all the languages will be present in the output show here.
-
hour
: hour of the day for which the forecast is. This is represented as a zero-padded string ("01"
is 1 AM) and there is no indication of the day. The list starts with the current hour, and it is up to the client to keep track of the day. -
dayNight
:d
when the forecast is for daytime;n
when the forecast is for nighttime. -
temp
: forecasted temperature in Celsius. -
ww
: weather condition, which, in combination withdayNight
, give the icon to show (see table inobs
key section). -
precipChance
: precipitation probability in percents (between 0 and 100) -
precipQuantity
: forecasted amount of precipitation in mm/m² -
pressure
: atmospheric pressure in hPa. -
windSpeedKm
andwindPeakSpeedKm
: forecasted wind speed and wind gusts speed (if any, might benull
), in km/h. -
windDirection
: wind direction, but WATCH OUT! To get the real direction (where the wind is coming from), you have to do:(windDirection + 180) mod 360
. They use that value to rotate an arrow that defaults to north (when windDirection=0), hence the trick. -
windDirectionText
: wind direction (no trick here)
List of upcoming and current warnings for the current location.
The for.showWarningTab
is true
when the list in for.warning
is not empty.
Example of list item
{
"icon_country": "BE",
"warningType": {
"id": "2",
"name": {
"fr": "Conditions glissantes",
"nl": "Gladheid",
"en": "Ice or snow",
"de": "Glätte"
}
},
"warningLevel": "1",
"text": {
"fr": "Ce soir...",
"nl": "Vanavond, vannacht...",
"en": "The ground...",
"de": "Der Boden..."
},
"fromTimestamp": "2025-01-03T21:00:00+01:00",
"toTimestamp": "2025-01-04T10:00:00+01:00"
}
Note that no matter the language set by the parameter l
, all the languages will be present in the output show here.
-
icon_country
: country code for the warning. -
warningType.id
: id of the warning, see table below for all the known ids. -
warningType.name
: translated names for the warning, see table below for all names. -
warningLevel
: level of the warning from 1 (weak) to 3 (strong). -
text
: translated descriptions for the warning text. -
fromTimestamp
andtoTimestamp
: timespan of the warning. Note that warnings may appear before thefromTimestamp
. They are generally not shown after thetoTimestamp
.
Table with known warning ids and names
This table may not be exhaustive: it was build by observing the data returned by the API over time. You can open an issue if you find a new id and name.
Warning id | Warning name (en, fr, nl, de) |
---|---|
0 | Wind, Vent, Wind, Wind |
1 | Rain, Pluie, Regen, Regen |
2 | Ice or snow, Chute de neige ou verglas, Sneeuw of ijzel, Glätte |
3 | Thunder, Orage, Onweer, Gewitter |
7 | Fog, Brouillard, Mist, Nebel |
9 | Cold, Froid, Koude, Kalt |
12 | Thunder Wind Rain, Orage, rafales et averses, Onweer Wind Regen, Gewitter Windböen Regen |
13 | Thunderstorm & strong gusts, Orage et rafales, Onweer en wind, Gewitter und Windböen |
14 | Thunderstorm & large rainfall, Orage et averses, Onweer en regen, Gewitter und Regen |
15 | Storm surge, Marée forte, Stormtij, Sturmflut |
17 | Coldspell, Vague de froid, Koude, Koude |
This key contains three graphs for the 14-days forecast: maximum temperature, minimum temperature and rainfall.
The graphs are always nested under the svg
key, which contains a list of objects.
Each graph is translated in the four languages.
Here is an example
{
"svg": [
{
"url": {
"nl": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tx&l=nl&k=c10e09ed15d26f241cfc056ccac49b5e",
"fr": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tx&l=fr&k=c10e09ed15d26f241cfc056ccac49b5e",
"en": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tx&l=en&k=c10e09ed15d26f241cfc056ccac49b5e",
"de": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tx&l=de&k=c10e09ed15d26f241cfc056ccac49b5e"
},
"ratio": 1.3638709677419354
},
{
"url": {
"nl": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tn&l=nl&k=c10e09ed15d26f241cfc056ccac49b5e",
"fr": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tn&l=fr&k=c10e09ed15d26f241cfc056ccac49b5e",
"en": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tn&l=en&k=c10e09ed15d26f241cfc056ccac49b5e",
"de": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=tn&l=de&k=c10e09ed15d26f241cfc056ccac49b5e"
},
"ratio": 1.3638709677419354
},
{
"url": {
"nl": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=rr&l=nl&k=c10e09ed15d26f241cfc056ccac49b5e",
"fr": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=rr&l=fr&k=c10e09ed15d26f241cfc056ccac49b5e",
"en": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=rr&l=en&k=c10e09ed15d26f241cfc056ccac49b5e",
"de": "https:\/\/app.meteo.be\/services\/appv4\/?s=getSvg&ins=11002&e=rr&l=de&k=c10e09ed15d26f241cfc056ccac49b5e"
},
"ratio": 1.3638709677419354
}
]
}
The e
query parameter determines the kind of graph:
-
tx
for maximum temperature -
tn
for minimum temperature -
rr
for rainfall
I don't know what ratio
is used for, maybe display settings.