Air quality

Environment: weather from openweather, air quality from irceline

Format
GeoJSON
Updates
Every 5 minutes
Latest snapshot
Snapshots stored
about 207,005
curl -H "Authorization: Bearer $MOBILITYTWIN_TOKEN" "https://api.mobilitytwin.brussels/environment/air-quality"
Get a token

Air quality measurements in Brussels from Irceline (SOS).

Which days have data

Data from 21 Aug 2024 to 2 Nov 2026, on 799 days. 30 of the last 30 days have data. A typical day holds 264 snapshots. Days are in UTC.

2026
JanFebMarAprMayJunJulAugSepOctNovDec
2025
JanFebMarAprMayJunJulAugSepOctNovDec
2024
JanFebMarAprMayJunJulAugSepOctNovDec
  • Full day
  • Partial, 50–90% of a typical day
  • Low, under 50%
  • No snapshot
  • Not expected

Click a day above, or pick a date, to get its requests.

Parameters

NameMeaning
timestampReturn the last snapshot at or before this moment, in Unix seconds or ISO 8601 (e.g. 2026-05-06T12:00:00Z). Without it, the latest snapshot is returned.

Response fields

A GeoJSON FeatureCollection. Field names without a prefix are in each feature's properties.

FieldType
firstValue.timestampinteger
firstValue.valuenull or number
idstring
labelstring
lastValue.timestampinteger
lastValue.valuenull or number
parameters.category.idstring
parameters.category.labelstring
parameters.feature.idstring
parameters.feature.labelstring
parameters.offering.idstring
parameters.offering.labelstring
parameters.phenomenon.idstring
parameters.phenomenon.labelstring
parameters.procedure.idstring
parameters.procedure.labelstring
station.properties.idinteger
station.properties.labelstring
uomstring

Python example

import requests
import geopandas as gpd

from datetime import datetime, timedelta, timezone

yesterday_noon = (datetime.now(timezone.utc) - timedelta(days=1)).replace(
    hour=12, minute=0, second=0, microsecond=0
)
params = {
    "timestamp": yesterday_noon.isoformat(),   # ISO accepted; epoch also works
}

url = "https://api.mobilitytwin.brussels/environment/air-quality"

data = requests.get(url, headers={
        'Authorization': 'Bearer [MY_API_KEY]'
}, params=params).json()

gdf = gpd.GeoDataFrame.from_features(data["features"])

# One feature per station and pollutant: keep nitrogen dioxide
no2 = gdf[gdf['parameters.phenomenon.label'] == 'Nitrogen dioxide']
for _, series in no2.head(10).iterrows():
    print(f"{series['station.properties.label']}: {series['lastValue.value']} {series['uom']}")

# Plot the monitoring stations by their latest NO2 value
no2.plot(figsize=(10, 8), column='lastValue.value', legend=True, markersize=20, cmap='RdYlGn_r')