Actueel blijven
Wijzigingen en versies
Overheidsportalen zeggen wat vandaag geldt. De change feed zegt wat er veranderde sinds je laatst keek: een nieuwe oproep, een deadline die van 1 naar 15 oktober schoof, een verhoogd maximum, een grootteregel die nu ook grote ondernemingen toelaat.
Versies en events
Telkens de inhoud van een maatregel verandert, wordt een nieuwe versie geschreven, met de verschillen per veld tegenover de vorige. Een bron opnieuw nakijken zonder wijziging schrijft niets, dus een versie is altijd een echte wijziging. Elke versie levert één event op in de change feed, getypeerd naar de belangrijkste wijziging en met elke categorie die ze raakte. Versies blijven voor altijd bewaard, events 400 dagen.
De change feed
Developer en hogerGET /v1/changes vraagt de functie change_feed.
curl "https://api.subsido.be/v1/changes?since=2026-09-01&type=subsidy.created,subsidy.deadline_changed®ion=flanders" \ -H "Authorization: Bearer sb_live_..."| Parameter | Betekenis |
|---|---|
| since | RFC 3339 of YYYY-MM-DD (het begin van die dag in Brussel): events vanaf dat moment. Hoogstens 400 dagen terug; versies gaan verder terug. |
| type | Kommalijst van eventtypes. Een event past als zijn hoofdtype of een van zijn categorieën in de lijst staat. match.*-types worden geweigerd: die staan nooit in de publieke feed. |
| subsidy | Het id van één maatregel (niet de slug). |
| source | Kommalijst van bron-id’s. Past ook op de eigen actualiteitsevents van de bron. |
| region | Kommalijst van gewesten: events over maatregelen daar, en over federale en Europese maatregelen, die overal gelden. Bronevents gaan erdoor. |
| limit, cursor | Paginagrootte en positie; zie paginering. |
Events komen het oudste eerst, in de volgorde van seq. De pagina is { data, pagination, meta }, en meta.latest_seq is de nieuwste seq in de hele feed, zodat je ziet hoe ver je achterloopt.
{
"id": "chg_06f8s2k1c9t4r7m3q5v0x8z2yw",
"seq": 18422,
"type": "subsidy.status_changed",
"categories": [
"subsidy.status_changed",
"subsidy.deadline_changed"
],
"subject": "subsidy",
"subject_id": "eu:HORIZON-EIC-2026-ACCELERATOR-01",
"version": 4,
"changes": [
{
"field": "status",
"before": "open",
"after": "closed"
},
{
"field": "application_window.closes_at",
"before": "2026-10-01T17:00:00+02:00",
"after": "2026-09-20T17:00:00+02:00"
}
],
"summary": {
"title": {
"nl": null,
"fr": null,
"en": "EIC Accelerator",
"de": null
},
"status": "closed",
"instrument_type": "grant",
"issuer": "European Commission",
"closes_at": "2026-09-20T17:00:00+02:00",
"regions": [],
"topics": [
"innovation",
"growth_scaleup"
],
"url": "https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/opportunities/topic-details/HORIZON-EIC-2026-ACCELERATOR-01",
"source_id": "eu_funding_tenders"
},
"occurred_at": "2026-09-27T06:12:40+02:00"
}| Veld | Betekenis |
|---|---|
| id | Het id van het event, chg_…. Hetzelfde id is de id van de webhooklevering. |
| seq | Stijgt over de hele feed. De cursor is erop gebouwd. |
| type | Het hoofdtype van het event. |
| categories | Elke categorie die de versie raakte. Een versie die status en deadline samen wijzigde, heeft type subsidy.status_changed met beide categorieën. |
| subject, subject_id | subsidy en het id van de maatregel, of source en het id van de bron. |
| version | De versie van de maatregel die dit event opleverde, of null voor events die geen versie zijn (nakende deadline, bronevents). |
| changes[] | { field, before, after } voor elk eindveld dat verschilt. Zie verder. |
| summary | Genoeg om te handelen zonder tweede request: title (in elke taal), status, instrument_type, issuer, closes_at, regions, topics, de officiële url en source_id. Events over een nakende deadline voegen days_left en threshold_days toe; bronevents bevatten freshness en previous. |
| occurred_at | Wanneer de wijziging geregistreerd werd, in Brusselse tijd. |
Eventtypes en categorieën
| Type | Wanneer |
|---|---|
| subsidy.created | Een maatregel verschijnt voor het eerst. |
| subsidy.status_changed | Het veld status veranderde: geopend, gesloten, gepauzeerd, budget op. |
| subsidy.deadline_changed | Alles onder application_window: een deadline, de openingsdatum, doorlopend indienen, uitputting van het budget. |
| subsidy.funding_changed | Alles onder funding: percentages, bedragen, plafonds, het programmabudget. |
| subsidy.eligibility_changed | Alles onder eligibility behalve thema’s: soorten aanvragers, groottes, sectoren, regels, kostensoorten. |
| subsidy.updated | Al de rest: titels, samenvattingen, thema’s, links, de rechtsgrond. |
| subsidy.closing_soon | De deadline van een open maatregel ligt 14 dagen verder, en opnieuw op 3 dagen. Geen versie: een controle elk uur verstuurt het één keer per maatregel, deadline en drempel. |
| subsidy.removed | De bron vermeldt de maatregel niet meer. Hij verschijnt niet meer in lijsten, tenzij je include_withdrawn meegeeft. |
| source.stale | Een bron ging van fresh of delayed naar stale, unavailable of unreadable. |
| source.recovered | Ze is terug. |
| match.created, match.status_changed, match.removed | Watchlist-events, alleen voor de webhooks van de eigenaar. Zie watchlists. |
Het hoofdtype van een versie is de belangrijkste categorie die ze raakte, in de volgorde status, deadline, financiering, voorwaarden, overige. Filter of abonneer je op een categorie, niet alleen op het hoofdtype, anders mis je de gewijzigde deadline die samen met een statuswijziging kwam.
Verschillen per veld
fieldis een pad met punten naar een eindveld:status,application_window.closes_at,funding.amount_max,titles.nl. Arrays worden in hun geheel vergeleken, dus een gewijzigde lijst gewesten is één wijziging met de oude en de nieuwe lijst.- De lijst regels wordt regel per regel vergeleken op hun id:
eligibility.rules[age_max]met de regel ervoor en erna (null als hij toegevoegd of verwijderd werd). Alleen een andere herkomst van een regel, zoals een nieuwe controledatum, is geen wijziging van de regel. - Administratieve velden worden wel geversioneerd maar nooit gemeld:
provenance.last_checked_at,provenance.content_hash,provenance.first_seen_atenprovenance.fields. Een versie waarvan alleen die velden verschillen, levert geen event op.
Verstreken datums
Elk uur normaliseren we elk actueel record opnieuw tegen het huidige tijdstip. Een oproep waarvan de deadline verstreken is, wordt closed, een aangekondigde oproep die geopend is, wordt open, en closes_at schuift door naar de volgende deadline van een oproep in meerdere rondes. Elk daarvan is een nieuwe versie met oorzaak date_passed en een gewoon event, meestal subsidy.status_changed of subsidy.deadline_changed. Dezelfde controle elk uur verstuurt subsidy.closing_soon.
De feed volgen
Doe de eerste call met since (of zonder, vanaf het oudste bewaarde event) en volg daarna next_cursor. Elke pagina heeft er een, ook de laatste: is has_more false, dan ben je bij, en met dezelfde cursor begint de volgende poll. Bewaar hem samen met het werk dat hij dekt, dan gaat een herstart precies verder waar hij stopte.
Er wordt niets overgeslagen en niets herhaald, ook al schrijft een importrun veel events tegelijk weg en kunnen runs overlappen: een event krijgt zijn plaats in de feed (zijn seq) pas nadat het vastgelegd is, dus een event dat laat vastgelegd wordt, komt na alles wat je al gelezen hebt. Een overlapvenster of een lijst van geziene id’s is niet nodig. seq is de volgorde van de feed; occurred_at is wanneer de wijziging vastgesteld werd en kan iets ouder zijn dan dat van een event ervoor.
let cursor = await loadCursor(); // null on the very first run
async function poll() {
for (;;) {
const url = new URL("https://api.subsido.be/v1/changes");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
else url.searchParams.set("since", "2026-09-01");
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.SUBSIDY_API_KEY}` },
});
const page = await res.json();
if (!res.ok) throw new Error(page.error.code);
for (const e of page.data) await handle(e);
cursor = page.pagination.next_cursor; // always set
await saveCursor(cursor);
if (!page.pagination.has_more) return; // caught up; poll again later
}
}Of laat ons jou verwittigen
Versies en historiek
Pro en hogerVersies en as_of vragen de functies history en as_of.
GET /v1/subsidies/{id}/versions geeft de versies van een maatregel, de nieuwste eerst: { version, valid_from, valid_to, cause, content_hash, changes }. GET /v1/subsidies/{id}/versions/{version} geeft het record zoals het was, en GET /v1/subsidies/{id}?as_of= de versie die op een bepaald moment gold. Voorbeelden staan bij maatregelen zoeken.
Waarom een versie geschreven werd
| cause | Betekenis |
|---|---|
| source_change | De bron publiceerde iets anders. |
| date_passed | De controle elk uur: een deadline of een openingsdatum is verstreken. |
| reprocess | We normaliseerden de laatste lezing van de bron opnieuw, na een correctie in hoe ze gelezen wordt. |
| withdrawn | De bron vermeldt de maatregel niet meer (dit geeft subsidy.removed). |
| closed_at_source | De bron vermeldt hem niet meer, en bij die bron betekent een ontbrekend item dat de oproep gesloten is. |
| restored | Een maatregel die de bron niet meer vermeldde, is terug. |
| curation, merge | Voorbehouden voor een correctie door een persoon en voor twee records die samengevoegd worden. Oude id’s van een samengevoegd record blijven werken; zie merged_from. |
Met versies en de change feed wordt “wat staat er open?” ook “wat veranderde er, wanneer, en wat wisten we op de dag van ons advies?”. Zie prijzen.
