303.525 datasets geïndexeerd1.419 uitgevers
Open Data IndexDe index van open data over Nederland
Open Data Index›Bouwen›Stemgedrag-tracker: hoe stemde elke partij?
AppOm te beginnenBestuur

Stemgedrag-tracker: hoe stemde elke partij?

Zoek een onderwerp en zie hoe elke fractie in de Tweede Kamer stemde over de moties erover: hoe vaak voor, hoe vaak tegen, en welke moties het haalden.

Je AI-assistentOpen Data Index MCP aan
De MCP-server van Open Data Index staat aan in je chat. Zo leest de assistent dit project en de bronnen zelf.
Jij plakt de prompt van dit project
De assistent haalt op bij Open Data Index
  • geef_project("stemgedrag-tracker")
  • geef_bron("tweedekamer-opendata")
De assistent

Ik heb het project, de geteste aanroepen en de valkuilen. Ik bouw een app met Tweede Kamer open data. Zo kan het eruitzien:

Dit bouw je zelf. Kopieer de prompt naar Claude, ChatGPT of Cursor, met de MCP-server aan, of volg de stappen hieronder.

Volg de stappen
21:04
Handopsteken4 / 28
stikstof26 gestemd · 8 aangenomen
17 sep 20262026Z19131

Motie van het lid Teunissen over de oproep voor een actieplan ‘Meer Plantaardige Voeding’ meenemen in de verdere uitwerking van het stikstofpakket en de voedselstrategie

Aangenomen79 – 71
voor76tegen
  • D6626
  • PRO20
  • CDA18
  • SP3
  • PvdD3
  • ChristenUnie3
  • DENK3
  • 50PLUS2
  • Volt1
  • VVD22
  • PVV19
  • JA219
  • FVD7
  • Groep Markuszower7
  • BBB3
  • SGP3
  • Keijzer1
Wat had jij gestemd?
Meest voor bij stikstofBBB 69%ChristenUnie 69%SGP 65%
Mockup

Dit is een mockup, geen werkende versie, met de stemming over motie 2026Z19131 uit een aanroep op 17 oktober 2026, 23:33 (Tweede Kamer, Gegevensmagazijn) en de totalen uit onze proefdraai van 16 oktober 2026. De MCP-server zet je aan met het adres op Voor AI.

Voor wie

Kiezers die willen weten wat een partij echt stemt, journalisten en factcheckers, scholieren en studenten politicologie, en makers van stemhulpen.

Wat je krijgt

Een zoekpagina: je typt een onderwerp en krijgt per fractie hoeveel moties over dat onderwerp ze steunde en hoeveel niet, plus de lijst met moties en hun uitslag.

Proefdraai op 16 oktober 2026 voor 'stikstof' in de Kamer die op 12 november 2025 begon: 28 moties, waarvan 26 in stemming en 8 aangenomen. BBB en ChristenUnie stemden bij 18 van de 26 voor (69%), VVD, PvdD en DENK bij 6 (23%). Voor 'asiel' waren het 78 moties (72 in stemming, 25 aangenomen); FVD stemde bij 90% voor, PVV bij 89%.

Ingediende moties in de Tweede Kamer: 4.440 per jaar in 2025, 70% meer dan in 2009

Ingediende moties in de Tweede Kamer, 2009 – 2025, per jaar. Het hoogste punt was 2022 (5.010).

Bron: Tweede Kamer, Gegevensmagazijn (Zaak, alleen volle jaren) · opgehaald 25 oktober 2026Open de tabel Los blok

Zo zou je kunnen starten5 stappen

  1. 1

    Welke fracties zitten er nu?

    Fracties met DatumInactief leeg zijn de huidige. Samen 150 zetels in 17 fracties op 16 oktober 2026, waaronder afsplitsingen als Groep Markuszower en de eenmansfractie Keijzer.

    https://gegevensmagazijn.tweedekamer.nl/OData/v5/Fractie?$filter=Verwijderd eq false and DatumInactief eq null&$select=Afkorting,NaamNL,AantalZetels&$orderby=AantalZetels desc&$top=5
    {"@odata.context":"https://gegevensmagazijn.tweedekamer.nl/OData/v5/$metadata#Fractie(Afkorting,NaamNL,AantalZetels)","value":[
      {"Afkorting":"D66","NaamNL":"Democraten 66","AantalZetels":26},
      {"Afkorting":"VVD","NaamNL":"Volkspartij voor Vrijheid en Democratie","AantalZetels":22},
      {"Afkorting":"PRO","NaamNL":"Progressief Nederland","AantalZetels":20},
      {"Afkorting":"PVV","NaamNL":"Partij voor de Vrijheid","AantalZetels":19},
      {"Afkorting":"CDA","NaamNL":"Christen-Democratisch Appèl","AantalZetels":18}]}
  2. 2

    Zoek moties op onderwerp, met de stemmingen erbij

    contains(Onderwerp,'stikstof') zoekt in de onderwerpregel, hoofdletterongevoelig, en vindt ook 'stikstofbeleid'. Met $expand haal je in één aanroep het besluit en per fractie de stem: Soort (Voor, Tegen, Niet deelgenomen) en FractieGrootte (zetels). $count=true geeft het totaal (28).

    https://gegevensmagazijn.tweedekamer.nl/OData/v5/Zaak?$filter=Soort eq 'Motie' and Verwijderd eq false and contains(Onderwerp,'stikstof') and Datum ge 2025-11-12&$count=true&$top=1&$orderby=Datum desc&$select=Nummer,Onderwerp,Datum&$expand=Besluit($select=Soort;$filter=Verwijderd eq false;$expand=Stemming($select=Soort,FractieGrootte,FractieNaam;$filter=Verwijderd eq false))
    {"@odata.context":"…/$metadata#Zaak(Nummer,Onderwerp,Datum,Besluit(Soort,Stemming(Soort,FractieGrootte,FractieNaam)))","@odata.count":28,"value":[
      {"Nummer":"2026Z20455","Onderwerp":"Motie van het lid Van der Plas over de maatschappelijke en sociaal-economische gevolgen voor de landbouw en het platteland expliciet meewegen bij de uitwerking van het stikstofbeleid ","Datum":"2026-09-29T00:00:00+02:00",
       "Besluit":[{"Soort":"Stemmen - verworpen","Stemming":[
         {"Soort":"Tegen","FractieGrootte":26,"FractieNaam":"D66"},{"Soort":"Tegen","FractieGrootte":18,"FractieNaam":"CDA"},
         {"Soort":"Voor","FractieGrootte":3,"FractieNaam":"BBB"},{"Soort":"Tegen","FractieGrootte":3,"FractieNaam":"DENK"}, …
  3. 3

    Let op hoofdelijke stemmingen

    Meestal stemt een fractie als geheel: één regel met FractieGrootte. Bij een hoofdelijke stemming is er één regel per Kamerlid, met Persoon_Id en Naam, en staat bij elk lid nog steeds de hele FractieGrootte. Tel dan per persoon 1, anders tel je een fractie twintig keer met twintig zetels.

    https://gegevensmagazijn.tweedekamer.nl/OData/v5/Stemming?$filter=Verwijderd eq false and Persoon_Id ne null&$orderby=GewijzigdOp desc&$top=2&$select=Soort,Naam,FractieNaam,FractieGrootte,Persoon_Id,Besluit_Id
    {"@odata.context":"…/$metadata#Stemming(Soort,Naam,FractieNaam,FractieGrootte,Persoon_Id,Besluit_Id)","value":[
      {"Besluit_Id":"f15d2d9f-85ed-42df-baa1-33706bd5f7f0","Soort":"Voor","FractieGrootte":1,"Naam":"Keijzer, M.C.G.","FractieNaam":"Keijzer","Persoon_Id":"8c5a8186-8f46-4bca-956d-06d4fa521635"},
      {"Besluit_Id":"f15d2d9f-85ed-42df-baa1-33706bd5f7f0","Soort":"Tegen","FractieGrootte":20,"Naam":"Mohandis, M.","FractieNaam":"PRO","Persoon_Id":"b7a52679-bac9-4e00-9dfd-06a22a7cf088"}]}
  4. 4

    Een fractie die van naam wisselt

    GroenLinks-PvdA heet sinds 9 juni 2026 PRO (Progressief Nederland) en kreeg een nieuwe Fractie_Id. In de stemmingen van dit jaar staan beide namen. Zoek opvolgers op met DatumActief en DatumInactief en voeg ze samen, anders lijkt het alsof er twee fracties zijn.

    https://gegevensmagazijn.tweedekamer.nl/OData/v5/Fractie?$filter=Afkorting eq 'PRO' or Afkorting eq 'GroenLinks-PvdA'&$select=Id,Afkorting,NaamNL,DatumActief,DatumInactief
    {"@odata.context":"…/$metadata#Fractie(Id,Afkorting,NaamNL,DatumActief,DatumInactief)","value":[
      {"Id":"d60f373a-5bb2-477f-9979-a8f3a0514e6b","Afkorting":"PRO","NaamNL":"Progressief Nederland","DatumActief":"2026-06-09T00:00:00+02:00","DatumInactief":null},
      {"Id":"0208097d-ef04-438a-8c29-eebb84956204","Afkorting":"GroenLinks-PvdA","NaamNL":"GroenLinks-PvdA","DatumActief":"2023-10-27T00:00:00+02:00","DatumInactief":"2026-06-10T00:00:00+02:00"}]}
  5. 5

    Tel per jaar in de API zelf

    Met $apply tel je zonder alles op te halen. Zet het filter dan binnen $apply (filter(…)/groupby(…)); een losse $filter naast een groupby gaf een foutmelding. Stikstofmoties: 91 in 2022, 26 in 2026 tot nu toe.

    https://gegevensmagazijn.tweedekamer.nl/OData/v5/Zaak?$apply=filter(Soort eq 'Motie' and Verwijderd eq false and contains(Onderwerp,'stikstof'))/compute(year(Datum) as Jaar)/groupby((Jaar),aggregate($count as n))
    {"@odata.context":"…/$metadata#Zaak(Jaar,n,Jaar)","value":[
      {"@odata.id":null,"Jaar":2008,"n":2}, … {"@odata.id":null,"Jaar":2019,"n":34},{"@odata.id":null,"Jaar":2020,"n":27},
      {"@odata.id":null,"Jaar":2021,"n":18},{"@odata.id":null,"Jaar":2022,"n":91},{"@odata.id":null,"Jaar":2023,"n":52},
      {"@odata.id":null,"Jaar":2024,"n":23},{"@odata.id":null,"Jaar":2025,"n":19},{"@odata.id":null,"Jaar":2026,"n":26}]}

Laat AI het bouwen

Plak deze prompt in Claude, ChatGPT, Cursor of Lovable. Hij noemt de echte endpoints, de koppelsleutels en de valkuilen, zodat de assistent meteen werkende code schrijft. Controleer de uitkomst altijd met de bron zelf.

Bouw een webapp (één HTML-bestand met JavaScript, of Next.js) waarin ik een onderwerp intyp en zie hoe elke fractie in de Tweede Kamer stemde over moties over dat onderwerp.

API: Tweede Kamer Gegevensmagazijn, OData v5, geen sleutel, CORS open:
https://gegevensmagazijn.tweedekamer.nl/OData/v5/Zaak?$filter=Soort eq 'Motie' and Verwijderd eq false and contains(Onderwerp,'stikstof') and Datum ge 2025-11-12&$select=Nummer,Onderwerp,Datum&$expand=Besluit($select=Soort;$filter=Verwijderd eq false;$expand=Stemming($select=Soort,FractieGrootte,FractieNaam,Persoon_Id;$filter=Verwijderd eq false))&$orderby=Datum&$top=250

Wat je moet weten:
- Gebruik v5-veldnamen. Oude v4-namen (GestartOp, ActorFractie, ActorNaam) geven een foutmelding: in v5 heten ze Datum, FractieNaam en Naam.
- Filter overal op Verwijderd eq false (ook binnen $expand).
- $top hoogstens 250; volg @odata.nextLink voor de volgende pagina.
- contains() is hoofdletterongevoelig en zoekt alleen in de onderwerpregel van de motie.
- Uitslag: het besluit met Soort 'Stemmen - aangenomen' of 'Stemmen - verworpen' en een gevulde Stemming-lijst. Andere besluiten ('Ingediend', 'Overgenomen', 'Stemmen - aangehouden') hebben geen stemmen. De besluiten komen niet op volgorde.
- Stemming.Soort is Voor, Tegen of Niet deelgenomen. Bij een fractiestemming één regel per fractie met FractieGrootte (zetels). Bij een hoofdelijke stemming één regel per Kamerlid (Persoon_Id gevuld): tel dan 1 per persoon en neem per fractie de meerderheid.
- Fracties veranderen: GroenLinks-PvdA heet sinds 9 juni 2026 PRO. Haal /Fractie op (Afkorting, NaamNL, AantalZetels, DatumActief, DatumInactief) en voeg voorgangers en opvolgers samen.
- De huidige Kamer begon op 12 november 2025. Wil je eerdere Kamers, vergelijk dan per periode: fracties en zetelaantallen verschillen.
- Het veld Vergissing (true bij 1.437 van ruim 1 miljoen stemregels) markeert een stem die als vergissing is gemeld. Laat de stem staan en toon een voetnoot.

Uitkomst: een zoekveld; een tabel per fractie (zetels, aantal voor, aantal tegen, percentage voor), gesorteerd op percentage; daaronder de moties met datum, onderwerp, uitslag en een balk met voor- en tegenstemmen in zetels. Optioneel: kies twee fracties en zie hoe vaak ze hetzelfde stemden.

Probeer het zelf

De kern van het project in een klein script. Nodig: Node 20 of nieuwer (ingebouwde fetch); draai met: node stemgedrag.mjs [woord] [vanaf-datum]. Getest op 2026-10-16; hieronder de echte uitvoer van die proefdraai.

// Stemgedrag-tracker: hoe stemde elke fractie over moties over een onderwerp?
// Bron: Tweede Kamer Gegevensmagazijn, OData v5 (geen sleutel). Node 20+.
const UA = { "User-Agent": "mijn-project/1.0 (+jij@voorbeeld.nl)" };
const TK = "https://gegevensmagazijn.tweedekamer.nl/OData/v5";
const WOORD = process.argv[2] ?? "stikstof";
const VANAF = process.argv[3] ?? "2025-11-12";   // Kamer na de verkiezing van 29 oktober 2025

// Moties met het woord in het onderwerp, met besluiten en per besluit de stemmingen per fractie.
let url = `${TK}/Zaak?` + new URLSearchParams({
  $filter: `Soort eq 'Motie' and Verwijderd eq false and contains(Onderwerp,'${WOORD}') and Datum ge ${VANAF}`,
  $select: "Nummer,Onderwerp,Datum",
  $expand: "Besluit($select=Soort;$filter=Verwijderd eq false;$expand=Stemming($select=Soort,FractieGrootte,FractieNaam,Persoon_Id,Vergissing;$filter=Verwijderd eq false))",
  $orderby: "Datum", $top: "250",                  // meer dan 250 geeft een fout; volg @odata.nextLink
});
const moties = [];
while (url) { const j = await (await fetch(url, { headers: UA })).json(); moties.push(...j.value); url = j["@odata.nextLink"]; }

// Fracties veranderen van naam en krijgen dan een nieuwe Fractie_Id: GroenLinks-PvdA heet sinds 9 juni 2026 PRO
// (Progressief Nederland). Voeg ze hier samen; zoek andere gevallen op met /Fractie (DatumActief, DatumInactief).
const ZELFDE = { "GroenLinks-PvdA": "PRO" };
const perFractie = {};   // fractie -> { voor, tegen }
let gestemd = 0, aangenomen = 0;
for (const m of moties) {
  // Het besluit met de stemming: Soort 'Stemmen - aangenomen' of 'Stemmen - verworpen' en een gevulde Stemming-lijst.
  const b = m.Besluit.find((b) => /^Stemmen - (aangenomen|verworpen)/.test(b.Soort) && b.Stemming.length);
  if (!b) continue;
  gestemd++; if (b.Soort.includes("aangenomen")) aangenomen++;
  // Hoofdelijke stemming: één rij per Kamerlid (Persoon_Id gevuld). Tel dan per fractie de meerderheid.
  const stem = {};
  for (const s of b.Stemming) {
    if (s.Soort === "Niet deelgenomen") continue;
    const f = (stem[ZELFDE[s.FractieNaam] ?? s.FractieNaam] ??= { Voor: 0, Tegen: 0 });
    f[s.Soort] += s.Persoon_Id ? 1 : s.FractieGrootte;
  }
  for (const [f, t] of Object.entries(stem)) {
    const p = (perFractie[f] ??= { voor: 0, tegen: 0 });
    t.Voor >= t.Tegen ? p.voor++ : p.tegen++;
  }
}
console.log(`Moties met '${WOORD}' in het onderwerp sinds ${VANAF}: ${moties.length}, waarvan ${gestemd} in stemming (${aangenomen} aangenomen)`);
console.log("fractie              voor  tegen  % voor");
for (const [f, p] of Object.entries(perFractie).sort((a, b) => b[1].voor / (b[1].voor + b[1].tegen) - a[1].voor / (a[1].voor + a[1].tegen)))
  console.log(`  ${f.padEnd(18)} ${String(p.voor).padStart(4)}  ${String(p.tegen).padStart(5)}  ${Math.round((100 * p.voor) / (p.voor + p.tegen)).toString().padStart(5)}`);
const laatste = moties.filter((m) => m.Besluit.some((b) => b.Stemming.length)).at(-1);
if (laatste) console.log(`\nLaatste: ${laatste.Nummer} (${laatste.Datum.slice(0, 10)}) ${laatste.Onderwerp.trim()}`);
Uitvoer
Moties met 'stikstof' in het onderwerp sinds 2025-11-12: 28, waarvan 26 in stemming (8 aangenomen)
fractie              voor  tegen  % voor
  BBB                  18      8     69
  ChristenUnie         18      8     69
  SGP                  17      9     65
  Groep Markuszower    15      9     63
  JA21                 16     10     62
  PVV                  16     10     62
  FVD                  16     10     62
  Keijzer              13      9     59
  50PLUS               12     14     46
  SP                   12     14     46
  PRO                  10     16     38
  Volt                  9     17     35
  D66                   8     18     31
  CDA                   8     18     31
  PvdD                  6     20     23
  VVD                   6     20     23
  DENK                  6     20     23

Laatste: 2026Z20455 (2026-09-29) Motie van het lid Van der Plas over de maatschappelijke en sociaal-economische gevolgen voor de landbouw en het platteland expliciet meewegen bij de uitwerking van het stikstofbeleid

Waar het misgaat

  • Hoofdelijke stemmingen geven één regel per Kamerlid, en elk lid draagt de hele FractieGrootte mee. Wie FractieGrootte optelt, telt een fractie van twintig zetels twintig keer. Tel per persoon 1 als Persoon_Id gevuld is.
  • Fracties wisselen van naam en Id (GroenLinks-PvdA werd op 9 juni 2026 PRO) en splitsen (Groep Markuszower, Keijzer). Zonder samenvoegen lijkt PRO in 2026 maar op een deel van de moties te stemmen.
  • Een $filter naast een $apply met groupby geeft een foutmelding ('grouping expression must evaluate to a property access value'). Zet het filter binnen $apply: $apply=filter(…)/groupby(…).
  • Niet elke motie komt in stemming: van de 28 stikstofmoties waren er 26 in stemming, de rest werd overgenomen, aangehouden of ingetrokken. Tel die apart en reken percentages alleen over moties met een stemming.
  • Zoeken op een woord in het onderwerp mist moties die het anders zeggen ('Natura 2000', 'PAS-melders'). Laat gebruikers meerdere woorden opgeven en toon welke moties je vond, zodat ze kunnen controleren.
  • Gebruik v5 (/OData/v5). Het oude v4-adres zou vanaf 1 oktober 2026 stoppen en heeft andere veldnamen; een oude naam in v5 geeft 'Could not find a property named …'.

Verder bouwen

  • Maak een overeenstemmingsmatrix: voor elk paar fracties het percentage moties waarop ze hetzelfde stemden. Zo zie je welke partijen in de praktijk samen optrekken.
  • Zet de indieners erbij: ZaakActor (Rol 'Indiener', met Naam en FractieNaam) vertelt wie de motie indiende. Hoe vaak stemt een fractie tegen haar eigen soort moties?
  • Volg een onderwerp door de tijd: met $apply en groupby per jaar zie je wanneer het in de Kamer speelde (stikstof: 91 moties in 2022).
  • Stuur een melding bij nieuwe stemmingen: vraag elke dag Besluit op met GewijzigdOp ge <gisteren> en Soort 'Stemmen - …' en zoek de bijbehorende moties.

Meer met deze data

Zetels in de Tweede Kamer: D66 is het grootste deel, 17% in oktober 2026

Verdeling in oktober 2026: D66 17%, VVD 15%, PRO 13%, PVV 13%, CDA 12%, JA21 6%, Groep Markuszower 4,7%, overig (10) 19%. Totaal: 150 zetels.

Bron: Tweede Kamer, Gegevensmagazijn (Fractie) · opgehaald 25 oktober 2026Open de tabel Los blok

De bronnen1

Tweede Kamer open data

Tweede KamerNederland, motie, stemming, Kamerlid

Alles wat de Tweede Kamer doet, als open API: moties en amendementen, hoe elke fractie stemde, schriftelijke Kamervragen, debatten en commissies, Kamerstukken, en de Kamerleden zelf, met hun nevenfuncties, geschenken en reizen.

OpenAPIBestuur
Actueel
bijgewerkt gisteren

Meer om te bouwen