Voor ontwikkelaars
AfvalBakkie werkt samen met bestaande afvalapps, afvalplatforms en chatbots. Een app blijft gewoon bestaan; Bakkie brengt dezelfde informatie naar inwoners in WhatsApp. Hier staat hoe je koppelt, met voorbeelden die je direct kunt proberen.
| Koppeling | Adres | Toegang |
|---|---|---|
| MCP-server | POST https://www.afval-bakkie.nl/mcp | Openbaar, alleen lezen |
| Agendafeed | GET https://www.afval-bakkie.nl/api/ics/{postcode}/{huisnummer}.ics | Openbaar |
| Koppelcode | POST https://www.afval-bakkie.nl/api/v1/koppelcode | API-sleutel per partner |
| Meldingen per e-mail | naar het e-mailadres dat de gemeente instelt | Instelling per gemeente |
Testen kan op https://uat.afval-bakkie.nl: dezelfde koppelingen, met testgegevens. Een sleutel voor de testomgeving is een andere dan voor productie.
MCP-server
Met het Model Context Protocol gebruikt elke AI-assistent de kennis van Bakkie: de chatbot op de website van een gemeente, Copilot, ChatGPT of Claude. De server werkt met Streamable HTTP en JSON-RPC 2.0, en zonder sessie: elke aanvraag staat op zichzelf, een initialize vooraf mag maar hoeft niet. Alleen POST; een GET geeft 405.
Toevoegen aan een MCP-client
{
"mcpServers": {
"afvalbakkie": { "url": "https://www.afval-bakkie.nl/mcp" }
}
}claude mcp add --transport http afvalbakkie https://www.afval-bakkie.nl/mcpTools
| Tool | Wat het doet en de invoer |
|---|---|
zoek_adres | Zoekt een Nederlands adres op in de BAG (via PDOK) en geeft straat, woonplaats en gemeente terug.
|
ophaaldagen | Geeft de ophaaldagen (afvalkalender) voor een adres: welke container wanneer aan de straat moet. Inclusief gewijzigde dagen rond feestdagen. Gebruik dit voor elke vraag over wanneer afval wordt opgehaald.
|
afval_scheiden | Zoekt in de afvalscheidingswijzer waar een voorwerp of materiaal hoort (GFT, PMD, papier, restafval, glas, textiel, milieustraat, statiegeld, e-waste, klein chemisch afval…), met tips en wat het wordt na recycling. Houdt rekening met regels van de gemeente (bijv. nascheiding).
|
inzamelpunten | Vindt inzamelpunten in de buurt van het adres: glasbakken, textielcontainers, papier- en PMD-containers, ondergrondse containers, batterij- en e-waste-inzamelpunten, kringloopwinkels. Bron: containerdata van de gemeente en OpenStreetMap.
|
milieustraat_info | Geeft de dichtstbijzijnde milieustraat (afvalbrengstation) met openingstijden, of hij nu open is, verwachte drukte per uur en welke afvalsoorten er worden geaccepteerd.
|
melding_maken | Maakt een melding bij de gemeente: container niet geleegd, container kapot of kwijt, zwerfafval, afvaldumping/bijplaatsing, ondergrondse container vol. In de app wordt eerst een concept getoond dat de inwoner zelf bevestigt.
|
weer_en_afval | Weersverwachting (Open-Meteo) voor de komende dagen met afvaladvies voor ophaaldagen: harde wind, hitte (maden in GFT), vorst.
|
kennisbank | Tips over afval scheiden, GFT-onderhoud, voedselverspilling en duurzaamheid, en het ontkrachten van afvalmythes.
|
nieuws | Laatste nieuws en berichten over afval in de gemeente.geen invoer |
barcode_opzoeken | Zoekt een product op via de barcode (EAN) in Open Food Facts en leidt uit het verpakkingsmateriaal af in welke bak de onderdelen horen.
|
Adresgebonden tools vragen postcode en huisnummer. melding_maken bereidt een melding voor; de inwoner rondt die af in WhatsApp.
Aanroepen met curl
Stuur Accept: application/json, text/event-stream mee. Het antwoord komt als één server-sent event; het resultaat staat in content[0].text als JSON.
curl -X POST https://www.afval-bakkie.nl/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"afval_scheiden","arguments":{"voorwerp":"pizzadoos"}}}'event: message
data: {"result":{"content":[{"type":"text","text":"{\n \"gevonden\": true,\n \"resultaten\": [ { \"voorwerp\": \"Pizzadoos\", \"hoort_bij\": \"Papier & karton\", \"waar\": \"Blauwe container\", \"tip\": \"Vetvlekken zijn geen probleem. Etensresten eruit (GFT).\" } ] }"}],"isError":false},"jsonrpc":"2.0","id":1}{
"adres": "Kerkstraat 12, 1234AB Voorbeelddorp",
"vandaag": "maandag 28 september",
"ophaaldagen": [
{ "datum": "2026-09-28", "dag": "vandaag (maandag 28 september)", "afval": "Papier & karton", "container": "Blauwe container" },
{ "datum": "2026-10-01", "dag": "donderdag 1 oktober", "afval": "GFT", "container": "Groene container" }
]
}Met een MCP-bibliotheek
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const client = new Client({ name: 'mijn-app', version: '1.0.0' });
await client.connect(new StreamableHTTPClientTransport(new URL('https://www.afval-bakkie.nl/mcp')));
const res = await client.callTool({
name: 'ophaaldagen',
arguments: { postcode: '1234AB', huisnummer: 12 },
});
const data = JSON.parse(res.content[0].text);
console.log(data.ophaaldagen[0]); // { datum, dag, afval, container }
await client.close();import asyncio, json
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
async def main():
async with streamable_http_client("https://www.afval-bakkie.nl/mcp") as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("afval_scheiden", {"voorwerp": "pizzadoos"})
print(json.loads(result.content[0].text)["resultaten"][0]["hoort_bij"])
asyncio.run(main())Fouten: een tool die niets kan vinden geeft gewoon een resultaat met uitleg; een ongeldige aanroep geeft isError: true of een JSON-RPC-fout. Te veel aanvragen geeft HTTP 429.
Agendafeed (ICS)
De ophaaldagen per adres als agenda-abonnement: twee weken terug en een jaar vooruit. Agenda's halen de feed dagelijks opnieuw op, dus wijzigingen komen vanzelf mee. Elke ophaaldag heeft een herinnering om 19:00 uur de avond ervoor.
GET https://www.afval-bakkie.nl/api/ics/{postcode}/{huisnummer}.ics| Deel | Uitleg |
|---|---|
{postcode} | Zonder spatie, bijvoorbeeld 1234AB |
{huisnummer} | Met toevoeging na een streepje: 12, 12-A, 12-2HG |
?streams= | Optioneel, alleen deze afvalsoorten: gft, pmd, papier, rest, textiel (komma's ertussen) |
| Antwoord | 200 text/calendar, of 404 als het adres niet bestaat of er (nog) geen ophaaldagen zijn |
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//AfvalBakkie//NL
X-WR-CALNAME:Afvalkalender Kerkstraat 12
REFRESH-INTERVAL;VALUE=DURATION:P1D
BEGIN:VEVENT
UID:1234AB-12-gft-2026-10-01@afvalbakkie
DTSTART;VALUE=DATE:20261001
DTEND;VALUE=DATE:20261002
SUMMARY:GFT ophalen
DESCRIPTION:Groene container. Los in de container\, zonder plastic zakje.
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:Morgen GFT: zet de container vanavond buiten
TRIGGER:-PT5H
END:VALARM
END:VEVENT
END:VCALENDAR<a href="webcal://www.afval-bakkie.nl/api/ics/1234AB/12.ics">Zet je ophaaldagen in je agenda</a>Koppelcode: van je app naar WhatsApp
Heeft een inwoner jouw afvalapp, en wil hij de seintjes liever in WhatsApp? Met één tik stuur je hem naar Bakkie, met het adres al ingevuld. Hij hoeft niets over te typen, en de code bevat geen naam of telefoonnummer.
Inwoner Jouw app Jouw server AfvalBakkie
| tikt "Seintjes | | |
| in WhatsApp" ->| | |
| |-- adres -------->| |
| | |-- POST /koppelcode ->|
| | |<- code + link -------|
| |<- link ----------| |
|<- WhatsApp opent met "KOPPEL ABC123" |
|-- verstuurt het bericht ---------------------------------->|
|<- "Top, je bent aangemeld voor Kerkstraat 12!" ------------|Aanvraag
| Veld | Type | Uitleg |
|---|---|---|
postcode | string | Verplicht. Met of zonder spatie: 1234AB of 1234 AB |
huisnummer | integer | Verplicht |
toevoeging | string | Optioneel, bijvoorbeeld A of 2HG |
curl -X POST https://www.afval-bakkie.nl/api/v1/koppelcode \
-H 'Authorization: Bearer abk_…' \
-H 'Content-Type: application/json' \
-d '{"postcode":"1234AB","huisnummer":12,"toevoeging":"A"}'HTTP/1.1 201 Created
Content-Type: application/json
{
"code": "ABC123",
"tekst": "KOPPEL ABC123",
"whatsapp": "https://wa.me/3197006533338?text=KOPPEL%20ABC123",
"adres": "Kerkstraat 12A, 1234AB Voorbeelddorp",
"verloopt": "2026-10-01T08:42:00.000Z"
}| Status | Betekenis |
|---|---|
201 | Code aangemaakt. Hij is 30 minuten geldig en werkt één keer. Open whatsapp meteen in je app. |
401 | Geen of geen geldige API-sleutel. |
404 | Het adres staat niet in de BAG. |
422 | Postcode of huisnummer ontbreekt of klopt niet. |
429 | Te veel aanvragen; maximaal 120 per minuut. |
503 | Adressen opzoeken lukt even niet; probeer het zo nog eens. |
{ "fout": "Dit adres staat niet in de BAG. Controleer postcode, huisnummer en toevoeging." }// Route op jouw server: de app vraagt hier een link op, de sleutel blijft op de server.
app.post('/whatsapp-link', async (req, res) => {
const { postcode, huisnummer, toevoeging } = req.user.adres; // het adres dat al in je app staat
const r = await fetch('https://www.afval-bakkie.nl/api/v1/koppelcode', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.AFVALBAKKIE_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ postcode, huisnummer, toevoeging }),
});
if (!r.ok) return res.status(r.status).json(await r.json());
const { whatsapp } = await r.json();
res.json({ link: whatsapp }); // de app opent deze link
});- Roep de API aan vanaf je eigen server. De sleutel is geheim en hoort niet in een app of browser.
- Vraag de code pas aan als de inwoner op de knop tikt, en open de link meteen: na 30 minuten vervalt hij.
- Een goede knoptekst is "Seintjes in WhatsApp". In WhatsApp noemt Bakkie de naam van je app niet.
- Stoppen kan altijd: de inwoner stuurt
STOP. MetVERWIJDERwist hij al zijn gegevens.
Een API-sleutel vraag je aan via het contactformulier. Je krijgt hem één keer te zien; wij bewaren alleen een controlegetal.
Meldingen per e-mail
Gemeenten kunnen elke melding uit Bakkie laten doorsturen naar hun meldingen- of zaaksysteem. Dat werkt met elk systeem dat e-mail kan inlezen. De gemeente zet dit aan in Beheer → Data → Meldingen → Afhandeling: doorsturen per e-mail. De status zet de gemeente daarna in Beheer; de inwoner krijgt het nieuws in WhatsApp.
From: AfvalBakkie <meldingen@afval-bakkie.nl>
To: meldingen@gemeente.nl
Subject: Melding M-2026-000042 · Container niet geleegd · Kerkstraat 12, 1234AB Voorbeelddorp
X-AfvalBakkie-Referentie: M-2026-000042
X-AfvalBakkie-Soort: niet_geleegd
Content-Type: multipart/mixed
tekst en HTML: dezelfde gegevens, leesbaar
bijlage melding.json (application/json, zie hieronder)
bijlage melding-foto.jpg (alleen als de inwoner een foto stuurde){
"schema": "afvalbakkie.melding.v1",
"referentie": "M-2026-000042",
"soort": "niet_geleegd",
"soortLabel": "Container niet geleegd",
"afvalstroom": "gft",
"omschrijving": "GFT-container staat sinds vanochtend vol aan de straat.",
"locatie": {
"tekst": "Kerkstraat 12, 1234AB Voorbeelddorp",
"lat": 52.2812,
"lon": 5.159
},
"gemeente": {
"code": "1942",
"naam": "Voorbeeldgemeente"
},
"kanaal": "whatsapp",
"ontvangen": "2026-10-01T08:12:00.000Z",
"foto": "melding-foto.jpg",
"statusBijwerken": "https://www.afval-bakkie.nl/beheer?gemeente=1942"
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://www.afval-bakkie.nl/schemas/afvalbakkie.melding.v1.json",
"title": "Melding uit AfvalBakkie (v1)",
"type": "object",
"required": [
"schema",
"referentie",
"soort",
"soortLabel",
"omschrijving",
"locatie",
"kanaal",
"ontvangen"
],
"properties": {
"schema": {
"const": "afvalbakkie.melding.v1"
},
"referentie": {
"type": "string",
"pattern": "^M-\\d{4}-\\d{6}$",
"description": "Uniek per melding, ook in het onderwerp en de kopregel X-AfvalBakkie-Referentie"
},
"soort": {
"enum": [
"niet_geleegd",
"container_kapot",
"container_weg",
"zwerfafval",
"dumping",
"ondergrondse_vol",
"overig"
]
},
"soortLabel": {
"type": "string",
"description": "De soort in gewone taal"
},
"afvalstroom": {
"type": [
"string",
"null"
],
"description": "Bijvoorbeeld gft, pmd, papier, rest, textiel of glas"
},
"omschrijving": {
"type": "string",
"maxLength": 1000
},
"locatie": {
"type": "object",
"required": [
"tekst"
],
"properties": {
"tekst": {
"type": "string"
},
"lat": {
"type": [
"number",
"null"
]
},
"lon": {
"type": [
"number",
"null"
]
}
}
},
"gemeente": {
"type": "object",
"properties": {
"code": {
"type": [
"string",
"null"
],
"description": "CBS-gemeentecode"
},
"naam": {
"type": [
"string",
"null"
]
}
}
},
"kanaal": {
"enum": [
"whatsapp",
"app"
]
},
"ontvangen": {
"type": "string",
"format": "date-time"
},
"foto": {
"type": [
"string",
"null"
],
"description": "Bestandsnaam van de foto in de bijlagen, of null"
},
"statusBijwerken": {
"type": "string",
"format": "uri",
"description": "Link naar de melding in Beheer"
}
}
}- Filter op de kopregel
X-AfvalBakkie-Referentieof op het onderwerp dat metMelding M-begint. - Er staat geen telefoonnummer, naam of apparaat van de inwoner in.
- Nieuwe velden kunnen erbij komen; bestaande velden blijven in
afvalbakkie.melding.v1gelijk.
Afspraken
- Eerlijk gebruik: MCP maximaal 60 en de partner-API maximaal 120 aanvragen per minuut per IP-adres.
- Privacy: de openbare onderdelen gebruiken geen persoonsgegevens. De koppelcode bevat alleen een adres. Zie de privacyverklaring.
- Versies: de partner-API heet v1. Wijzigingen die bestaande koppelingen raken, kondigen we vooraf aan.
- Contact: WhatsApp: +3197006533338.