
Samen Meten (RIVM)
Citizens, municipalities and researchers put up their own sensor boxes; RIVM collects their measurements in the Samen Meten data portal and produces calibrated series for particulate matter. On 16 October 2026 the API held 12,419 measuring points with 56,391 data streams: particulate matter (PM10, PM2.5), nitrogen dioxide, ammonia, temperature, humidity and air pressure, per hour. The largest group is Luftdaten (6,099 points).

Samen Meten measuring points by project: most Luftdaten (6,103 measuring points), then Palmes and Luchtclub
Samen Meten measuring points by project, October 2026, in measuring points. Total: 12,439; the largest 12 of 60 categories are shown. Luftdaten is 49% of the total. A measuring point is a sensor box or, in the Palmes projects, a tube that measures nitrogen dioxide. All points in the API are counted, including those no longer measuring.
What you can build with it1
What can you do with it?4 ideas
How dirty is the air in my street?
Find the measuring points around an address with geo.distance and fetch the calibrated particulate series (pm25_kal). Around the Utrecht Dom tower there are 10 points within 0.005 degrees.
Who is measuring?
Every point belongs to a project: Luftdaten (6,099), Palmes (1,837), Luchtclub (704), Hollandse Luchten (573). The chart on this page counts them.
Citizen sensor next to the official station
Every point names the nearest Luchtmeetnet station (e.g. no2closecode NL10131). Put the two series side by side and see how well the calibration works.
Show fireworks and wood burning
There are projects named Vuurwerk (fireworks, 75 points) and Houtstook (wood burning, 28). Look at the particulate peaks around New Year or on cold winter evenings.
How to process it4 steps
Measuring points of one project
Things are the measuring points. Filter on properties/project; $count=true gives the count, $top at most 200 per page (follow @iot.nextLink).
https://api-samenmeten.rivm.nl/v1.0/Things?$filter=properties/project%20eq%20'Smartcitizen'&$count=true&$top=5
The latest values of a series
Every series (Datastream) is named <point>-<number>-<quantity>. With $expand you fetch the latest values in the same call.
https://api-samenmeten.rivm.nl/v1.0/Datastreams?$filter=name%20eq%20'SMC_20058-21-pm25_kal'&$expand=Observations($top=2;$orderby=phenomenonTime%20desc)
Measuring points around a place
geo.distance only works with SRID=4326 in the geography. Coordinates in the responses are rounded to three decimals (about 100 metres).
https://api-samenmeten.rivm.nl/v1.0/Locations?$filter=geo.distance(location,geography'SRID=4326;POINT(5.121314%2052.090654)')%20le%200.005&$expand=Things($select=name)
Which quantities exist
Nine: pres, rh, temp, nh3, no2, pm25_kal, pm10_kal, pm25 and pm10. For particulate matter use the calibrated ones (_kal).
https://api-samenmeten.rivm.nl/v1.0/ObservedProperties
Interesting combinations


Is the citizen sensor right?
Every point names its nearest, regional and city station. Fetch the same hours for that station from Luchtmeetnet and compare.


More particulate matter with little wind?
The KNMI station is listed for each point. Compare the daily wind speed with the daily mean particulate matter.
Similar sources
Luchtmeetnet air quality networkThe official network of RIVM, health services and provinces; far fewer points, but with reference equipment.
Large-scale concentration maps (GCN)Calculated annual averages on a map of the whole country, not hourly measurements.
EEA air qualityOfficial measurements across Europe, comparable between countries.
What to watch out for
- Many points no longer measure
The API counts every point ever registered. A Palmes point we looked at had no measurements at all. Check the latest value per series.
- Raw sensor values are unreliable
Cheap particulate sensors can be far off, for example at high humidity. Use the calibrated series (pm25_kal, pm10_kal), not pm25 and pm10.
- Broad queries time out
Observations without a filter, or an $expand over many points at once, returned a 504 (Gateway Time-out). A filter on Observations/phenomenonTime from Datastreams returned an empty reply. Work per series.
- Licence not named
Samen Meten says "Our data are Open Data" without naming a licence. An older Utrecht dataset on data.overheid.nl is CC0, but for the RIVM portal this is not established.
- Locations rounded
Coordinates have three decimals (about 100 metres). Enough for a neighbourhood, not for a house number.
APIOGC SensorThings API 1.0 (OData-achtig, JSON) · read 16 Oct 2026
No key; the API is public (tested). tested
Things (sensor boxes) with 56,418 datastreams, 24,613 locations and 52 sensor types ($count, 16 Oct 2026) tested
json
Base URL
https://api-samenmeten.rivm.nl/v1.0
Endpoints 9
- GET
/ThingsSensor boxes; properties with project, owner, municipality code and the nearest official stations per substance (no2closecode, pm25regiocode …). - GET
/DatastreamsOne series per box and quantity, named <box>-<no>-<quantity> (SMC_20058-21-pm25_kal), with unit. - GET
/Datastreams({id})/ObservationsHourly values of one series (phenomenonTime, result). - GET
/ObservationsAll observations; always filter, the whole set is too big to count. - GET
/ObservedPropertiesThe 9 quantities: pm10, pm25, pm10_kal, pm25_kal (calibrated), no2, nh3, temp, rh, pres. - GET
/SensorsThe 52 sensors by name (Sensirion SEN5x, AirVisual …); the number in description reappears in the datastream name. - GET
/LocationsBox locations (GeoJSON point); search nearby with geo.distance. - GET
/HistoricalLocationsEarlier locations of a box (moved). - GET
/FeaturesOfInterestWhat an observation is about (usually the location).
Filtering platform
OData-like expressions in $filter (SensorThings), also on properties/… and with geo.distance(location, geography'SRID=4326;POINT(lon lat)') le <degrees>.
Parameters 6
$filter | Filter, e.g. name eq 'SMC_20058-21-pm25_kal', properties/project eq 'Smartcitizen', phenomenonTime ge 2026-10-16T00:00:00Z, startswith(name,'ZWL'). | tested |
$expand | Include related entities, with their own options: Observations($top=2;$orderby=phenomenonTime desc). | tested |
$select | Only these fields (phenomenonTime,result). | tested |
$orderby | Sort. | tested |
$top / $skip | Paging; $top at most 200 (more silently becomes 200). | tested |
$count | Total in @iot.count. | tested |
Fields in the response (selection) 8
| Name | Type | Meaning |
|---|---|---|
@iot.id | integer | Id van de entiteit |
name | tekst | Naam van kastje of reeks |
properties.project / owner | tekst | Meetproject (Smartcitizen, …) en eigenaar |
properties.codegemeente | tekst | CBS-gemeentecode zonder GM (935 = Maastricht) |
unitOfMeasurement.symbol | tekst · µg/m³, %, °C, hPa | Eenheid van de reeks |
phenomenonTime | datetime · UTC | Uur van de waarneming |
result | getal | De waarde |
location.coordinates | punt · lon, lat (WGS84) | Plaats van het kastje |
Limits and pitfalls
- $top at most 200 per page; follow @iot.nextLink for the rest. tested
- Counting over all Observations or all active boxes timed out (HTTP 504). Count per series or per project. experience
- Particulate matter has two series per box: raw (pm25, pm10) and calibrated (pm25_kal, pm10_kal, 'fijnstof gekalibreerd' in ObservedProperties). Compare only the _kal series with official measurements. tested
- geo.distance only works with geography'SRID=4326;POINT(lon lat)', distance in degrees (0.005 ≈ 350 m east-west). experience
- A mistake in $filter returns 400 with the raw database error ('pq: column "bogus" does not exist'): handy to check field names. tested
- Each box lists in properties the nearest official Luchtmeetnet stations per substance: compare directly with the reference measurement. tested
Try it HTTP 200 · 387 ms · 16 Oct
https://api-samenmeten.rivm.nl/v1.0/Datastreams?$filter=name eq 'SMC_20058-21-pm25_kal'&$expand=Observations($top=3;$orderby=phenomenonTime desc)
{
"value": [
{
"@iot.id": 56399,
"@iot.selfLink": "https://api-samenmeten.rivm.nl/v1.0/Datastreams(56399)",
"name": "SMC_20058-21-pm25_kal",
"description": "SMC_20058-21-pm25_kal",
"unitOfMeasurement": {
"definition": "https://qudt.org/vocab/unit/MicroGM-PER-M3",
"symbol": "ug/m3"
},
"observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement",
"Thing@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Datastreams(56399)/Thing",
"Sensor@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Datastreams(56399)/Sensor",
"ObservedProperty@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Datastreams(56399)/ObservedProperty",
"Observations": [
{
"@iot.id": 733886641,
"@iot.selfLink": "https://api-samenmeten.rivm.nl/v1.0/Observations(733886641)",
"phenomenonTime": "2026-10-16T20:00:00.000Z",
"result": 3.01,
"Datastream@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Observations(733886641)/Datastream",
"FeatureOfInterest@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Observations(733886641)/FeatureOfInterest",
"resultTime": null
},
{
"@iot.id": 733875902,
"@iot.selfLink": "https://api-samenmeten.rivm.nl/v1.0/Observations(733875902)",
"phenomenonTime": "2026-10-16T19:00:00.000Z",
"result": 15.09,
"Datastream@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Observations(733875902)/Datastream",
"FeatureOfInterest@iot.navigationLink": "https://api-samenmeten.rivm.nl/v1.0/Observations(733875902)/FeatureOfInterest",
"resultTime": null
}
]
}
]
}Shortened response, saved at harvest time. Click the URL for the real, current response.
Read from Service root: the 8 SensorThings entities with their URL · Samen Meten guide with example calls · OGC SensorThings API 1.0 (the standard). Labels: from the description stated in what the api itself publishes. tested from our own small call. platform applies to every api on this platform, per its documentation. experience learned while building open data index.
How to fetch it
curl "https://api-samenmeten.rivm.nl/v1.0/Datastreams?\$filter=name%20eq%20'SMC_20058-21-pm25_kal'&\$expand=Observations(\$top=24;\$orderby=phenomenonTime%20desc)"
More from RIVM in our index
929 datasets in data.overheid.nl, Nationaal Georegister, CBS, tabellen van derden, RIVM GCN en GDN. These changed most recently.
- Emissies naar het riool vanuit de industrie (2019 - heden) (INSPIRE)2026-10-29
- Geluid van windturbines (Lden)2026-10-28
- Gemeten fijnere fractie van Fijn stof concentraties in buitenlucht.2026-10-27
- Gemeten Ammoniak concentraties in buitenlucht.2026-10-27
- Gemeten Stikstofmonoxide concentraties in buitenlucht.2026-10-27
- Emissies naar het riool vanuit de industrie (2019 - heden) (INSPIRE)2026-10-27
More in this topic
See how this page is built
bron: rivm-samenmeten blokken: [] secties: - ideeen - verwerken - koppelingen - vergelijkbaar - beperkingen - code cache: tag: bron:rivm-samenmeten ververs: na statuscheck, als de bron nieuwer is statuscheck: methode: nieuwste uurwaarde van één vast meetpunt (gekalibreerd PM2,5 van SMC_20058) verwacht: elk uur
Source: content/bronnen/rivm-samenmeten.yaml · Markdown



