Een batch van een hypotheekverstrekker komt op dinsdagochtend binnen: WOZ-informatie, energielabels en transactiehistorie voor duizenden adressen die ’s nachts zijn vrijgekomen. Een ongecoördineerde cron-job stuurt de aanvragen vrijwel gelijktijdig naar de woningdata-API. Zonder duidelijke begrenzing kunnen time-outs zich opstapelen, raakt gedeelde capaciteit bezet en wachten realtime gebruikers op een antwoord.

API rate limiting voorkomt dat scenario. Het is de afspraak over het maximale aantal verzoeken dat een client binnen een bepaalde periode mag versturen, bijvoorbeeld per API-key, endpoint, organisatie of IP-adres. Voor woningdata is dat relevant omdat banken, gemeenten, makelaars, taxateurs en verzekeraars verschillende verkeerspatronen hebben. Een realtime aanvraag voor één woning vraagt iets anders van een platform dan een nachtelijke portefeuille-import.

De Nederlandse overheid beschrijft rate limiting expliciet als middel om serveroverbelasting te voorkomen en een hoog serviceniveau te behouden. De API-strategie noemt daarbij headers zoals X-Rate-Limit-Limit, X-Rate-Limit-Remaining en X-Rate-Limit-Reset, plus HTTP-statuscode 429 Too Many Requests bij overschrijding (Nederlandse API-strategie). Een stabiele integratie begint daarom niet bij “zet een limiet aan”, maar bij vier vragen: welk verkeerspatroon heb je, welke headers krijgt je client terug, hoe reageert de client op een afwijzing en welke signalen monitor je?

Waarom API rate limiting onmisbaar is voor woningdata

API rate limiting verdeelt beperkte capaciteit voorspelbaar over afnemers. Dat is vooral belangrijk wanneer één organisatie veel adressen tegelijk opvraagt, terwijl andere klanten ondertussen individuele objecten willen beoordelen voor een hypotheekaanvraag, taxatie of verzekeringscontrole.

Eén limiet past niet bij elk woningdata-proces

Een bank kan een grote batch voorbereiden na een nachtelijke gegevensverwerking. Een makelaarsapplicatie vraagt juist synchroon kenmerken op terwijl een gebruiker een object opent. Een gemeente raadpleegt locatie- en objectinformatie rond vergunningsdossiers, terwijl een verzekeraar overdag losse controles uitvoert en op andere momenten een portefeuille herwaardeert.

Rate limiting beschermt in die situaties meerdere lagen tegelijk:

  • De bronketen: achterliggende registraties en dataverwerkingen krijgen ruimte om aanvragen ordelijk af te handelen.
  • De API-gateway: één zware integratie kan niet onbeperkt gedeelde capaciteit gebruiken.
  • De afnemer: een limiet maakt gedrag voorspelbaar en dwingt batchprocessen naar een beheersbare wachtrij.
  • Andere klanten: realtime aanvragen blijven beschikbaar wanneer een batch onverwacht versnelt.

De BAG API laat zien hoe publieke API's limieten gefaseerd kunnen invoeren. Op 19 juli 2022 werd een traject aangekondigd met eerst 200.000 berichten per dag per 1 september 2022, daarna 50.000 berichten per dag per 1 december 2022, en uiteindelijk 5 berichten per seconde per 1 maart 2023 (BAG API over quota en throttling). Die overgang combineerde een dagquotum met een expliciete begrenzing per seconde. Voor Nederlandse vastgoed-, adres- en omgevingsdata is dat een bruikbaar ijkpunt: limieten zijn niet alleen een beveiligingsmaatregel, maar ook een instrument voor stabiliteit, fair use en operationele planning.

Praktische regel: ontwerp je limiet rond het werkelijke proces, niet rond het gemiddelde verzoek. Een gemiddelde zegt weinig over een batch die in korte tijd losbarst.

De rest van je ontwerp draait vervolgens om patronen, headers, clientgedrag en monitoring. Als je die vier samenbrengt, wordt een 429 geen incident maar een controleerbaar onderdeel van de integratie.

De vier klassieke patronen achter rate limiting

Een rate limiter bepaalt niet alleen hoeveel verzoeken zijn toegestaan, maar ook hoe pieken worden behandeld. De keuze tussen token bucket, leaky bucket, fixed window en sliding window beïnvloedt direct de ervaring van een ontwikkelaar en de belasting van de bron.

Welke patronen kom je tegen?

Token bucket werkt als een emmer die geleidelijk met tokens wordt gevuld. Elk verzoek gebruikt één token. Een klant die even weinig verkeer heeft gehad, kan daardoor een korte burst opvangen, waarna het verkeer terugvalt naar het aanvultempo. Dat past bij een gemeente die verspreid over de dag objecten opvraagt en af en toe een dossiercluster verwerkt.

Leaky bucket laat verzoeken met een vaste snelheid door, alsof water gecontroleerd uit een emmer druppelt. Binnenkomende aanvragen kunnen tijdelijk wachten, maar de uitstroom blijft gelijkmatiger. Dat is nuttig wanneer een batchproces van een verzekeraar een achterliggende bron niet met een plotselinge piek mag belasten.

Fixed window gebruikt een teller binnen een vast tijdvak. Aan het einde van dat venster reset de teller. Het model is eenvoudig, maar een client kan de grens tussen twee vensters uitbuiten. Daardoor ontstaat rond de reset een korte piek die hoger ligt dan de beoogde gelijkmatige snelheid.

Sliding window kijkt steeds terug over een voortschrijdend tijdvak. De limiter beoordeelt dus niet alleen het huidige blok, maar ook recente aanvragen. Dat voorkomt grenspieken beter, al vraagt het model meer administratie dan een eenvoudige vaste teller.

Patroon Burst-tolerantie Complexiteit Beste use-case
Token bucket Hoog bij korte pieken Gemiddeld Normale interactie met incidentele bursts
Leaky bucket Laag, uitstroom blijft vlak Gemiddeld Batchverkeer richting kwetsbare bronnen
Fixed window Mogelijk rond venstergrenzen Laag Eenvoudige interne toepassingen
Sliding window Beperkt grenspieken Hoger Publieke API's met eerlijke verdeling

Voor woningdata kiest Altum AI volgens de beschreven aanpak voor token bucket per API-key, met een sliding-windowmechanisme als veiligheidsnet. Dat combineert ruimte voor legitieme korte pieken met bescherming tegen een langdurig te hoog tempo.

HTTP-headers en statuscodes die je moet kennen

Een client moet aan de response kunnen zien hoeveel ruimte nog beschikbaar is. Zonder die informatie moet een integratie gokken, en dat leidt vaak tot onnodige retries of een batch die pas na meerdere fouten vertraagt.

De oudere, breed gebruikte headerfamilie bestaat uit:

  • X-RateLimit-Limit, het maximum binnen het actieve venster.
  • X-RateLimit-Remaining, het resterende aantal verzoeken.
  • X-RateLimit-Reset, het moment waarop het venster opnieuw beschikbaar komt, vaak als Unix-timestamp.

De modernere IETF-familie gebruikt RateLimit-Limit, RateLimit-Remaining en RateLimit-Reset. In die specificatie moet RateLimit-Reset verwijzen naar hetzelfde resetmoment als het limiter-venster (IETF-specificatie voor rate-limit headers). De termen lijken sterk op elkaar, maar je client mag de waarden niet zonder documentatie door elkaar halen. Een resetwaarde kan een tijdstip of een resterende duur betekenen, afhankelijk van de headerfamilie en het contract van de API.

Screenshot from https://docs.altum.ai/assets/rate-limit-headers.png

Wat gebeurt er bij overschrijding?

Bij te veel verzoeken hoort HTTP 429 Too Many Requests. De server kan daarbij Retry-After meesturen. Die header geeft aan hoe lang de client moet wachten, bijvoorbeeld als aantal seconden of als HTTP-datum (MDN over HTTP 429).

Een response kan er conceptueel zo uitzien:

HTTP/1.1 429 Too Many Requests
Retry-After: 8
RateLimit-Limit: ...
RateLimit-Remaining: 0
RateLimit-Reset: ...

Gebruik de feitelijke waarden uit de response en vertrouw niet op hard gecodeerde aannames. De oudere X-RateLimit-*-familie is breed ingeburgerd, terwijl de RateLimit-*-familie machineleesbare metadata op een gestandaardiseerdere manier beschrijft. De gangbare headerbetekenissen en resetinterpretatie worden ook helder samengevat in deze uitleg over HTTP 429 en rate-limit headers.

Exponentiële backoff met jitter aan de client-kant

Een 429 is geen signaal om onmiddellijk opnieuw te proberen. Als veel workers dezelfde fout tegelijk krijgen en allemaal direct opnieuw verzenden, ontstaat een nieuwe piek precies op het moment dat de server al heeft aangegeven dat de limiet is bereikt.

Exponential backoff maakt de wachttijd na elke volgende 429 langer. Een eenvoudige reeks begint met 1 seconde, daarna 2 seconden en vervolgens 4 seconden. Voeg jitter toe, zodat workers niet op exact hetzelfde moment opnieuw starten. Een bruikbare ontwerpregel is base = 1s en cap = 30s, waarbij Retry-After altijd leidend blijft wanneer de server die header terugstuurt.

import random
import time
import requests
from email.utils import parsedate_to_datetime
from datetime import datetime, timezone

def retry_after_seconds(value):
    if not value:
        return None

    try:
        return max(0.0, float(value))
    except ValueError:
        try:
            retry_at = parsedate_to_datetime(value)
            now = datetime.now(timezone.utc)
            return max(0.0, (retry_at - now).total_seconds())
        except (TypeError, ValueError, OverflowError):
            return None

def get_with_backoff(url, attempts=6, base=1.0, cap=30.0):
    for attempt in range(attempts):
        response = requests.get(url, timeout=10)

        if response.status_code != 429:
            return response

        server_wait = retry_after_seconds(
            response.headers.get("Retry-After")
        )
        calculated_wait = min(cap, base * (2 ** attempt))
        wait = server_wait if server_wait is not None else calculated_wait

        jittered_wait = min(cap, wait) * random.uniform(0.5, 1.0)
        time.sleep(jittered_wait)

    raise RuntimeError("Maximum aantal pogingen bereikt")

De parser behandelt zowel een numerieke waarde als een HTTP-datum. De client begrenst de wachttijd, maar moet de serverinstructie wel respecteren. Gebruik retries alleen voor fouten die opnieuw proberen zinvol maken. Een netwerkfout is niet hetzelfde als een 429, en een validatiefout wordt niet opgelost door langer te wachten.

Test minimaal drie situaties:

  • Normale backoff: de client ontvangt tijdelijk 429's en herstelt zonder een nieuwe piek te veroorzaken.
  • Bewust lage limiet: je controleert of workers pauzeren, logging schrijven en de batch niet verliezen.
  • Netwerkfout: je verifieert dat time-outs en verbindingsproblemen een eigen foutpad volgen.

Caching batching en paginatie als hefbomen

De meest effectieve manier om rate limiting minder vaak te raken, is minder verzoeken versturen. Backoff beschermt de server nadat je een limiet hebt bereikt. Caching, batching en paginatie verlagen het verzoekvolume daarvoor al.

Kies de hefboom die bij je data past

Caching past bij informatie die binnen je proces niet voortdurend verandert. Denk aan herhaalde WOZ-uitvragen of kadastrale eigendomsinformatie. Bewaar een response tijdelijk met een duidelijke TTL en een sleutel waarin minimaal endpoint, objectidentificatie en relevante parameters staan. Laat de TTL aansluiten op de actualiteitsbehoefte, niet op een willekeurige standaard.

Batching is geschikt wanneer je veel losse objecten tegelijk verwerkt. Een batch-endpoint kan meerdere identificaties in één aanvraag ontvangen, waardoor een nachtelijke portefeuille-import minder losse round-trips nodig heeft. Documenteer wel hoe gedeeltelijke fouten worden teruggegeven. Een batch met één ongeldig object mag niet automatisch alle geldige resultaten onbruikbaar maken. Lees meer over dit patroon in batch processing voor API-integraties.

Cursor-gebaseerde paginatie werkt voor lange lijsten. De server geeft een cursor terug waarmee de client de volgende consistente set opvraagt. Dat voorkomt dat verschuivende offset-pagina's records overslaan wanneer de bron tijdens het bladeren verandert.

Hefboom Ideale use case Latencywinst Complexiteit
Caching Herhaalde of weinig veranderlijke data Hoog bij cache hits Laag tot gemiddeld
Batching Veel bekende objecten verwerken Hoog door minder round-trips Gemiddeld
Cursor-paginatie Door grote, veranderende lijsten lopen Gelijkmatiger verwerking Gemiddeld

Gebruik een korte cache-TTL wanneer data fluctueert. Kies batching voor veel afzonderlijke entiteiten. Gebruik cursor-paginatie wanneer je door een lijst navigeert. De drie technieken sluiten elkaar niet uit. Een batchresultaat kan bijvoorbeeld tijdelijk worden gecachet, terwijl een grote bronlijst cursor-gebaseerd wordt verwerkt.

Verkeerspatronen per doelgroep in de woningmarkt

Een limiet moet aansluiten op het proces van de afnemer. Dezelfde drempel kan voor een realtime makelaarsapplicatie ruim lijken, maar voor een nachtelijke hypotheekbatch onbruikbaar zijn. Denk daarom per doelgroep in termen van burst, batchgrootte, responstijd en scheiding tussen werkstromen.

Doelgroep Verkeerspatroon Batchgrootte Aanbevolen rpm Dedicated key?
Bank Voorspelbare ochtendbatch en realtime acceptatie Middelgroot tot groot 60 tot 120 Ja
Gemeente Gelijkmatig laag volume met rapportagepieken Klein tot middelgroot 20 tot 30 Vaak
Makelaar Synchrone objectaanvragen vanuit de frontend Klein 20 tot 30 Meestal niet
Verzekeraar Realtime checks en periodieke herwaardering Middelgroot 60 tot 120 Ja

Deze drempels zijn ontwerpvoorstellen voor een startpunt, geen universele Altum AI-contractwaarden. Een bank doet er verstandig aan realtime hypotheekaanvragen en nachtelijke herimports niet dezelfde sleutel te geven. Anders kan een vertraagde batch de interactieve klantreis blokkeren.

Van profiel naar endpoint

Koppel het verkeersprofiel vervolgens aan het soort woningdata:

  • Objectkenmerken en locatiegegevens: geschikt voor synchrone aanvragen vanuit een applicatie.
  • Woningwaardemodel-uitkomsten: behandel berekeningen met grotere verwerking als een aparte stroom van eenvoudige kenmerken.
  • Energielabel- en verduurzamingsinformatie: cache herhaalde uitvragen wanneer je workflow dezelfde woning meerdere keren beoordeelt.
  • Transactiehistorie en portefeuilledata: verwerk via batch en cursor-paginatie, met een eigen sleutel en wachtrij.

Een dedicated API-key is vooral zinvol wanneer een proces een eigen operationeel risico heeft. Het gaat niet alleen om meer capaciteit. Je wilt ook kunnen zien welke workflow de limiet gebruikt en een storing isoleren zonder meteen alle andere aanvragen te raken.

Monitoring alerts en self-service limietbeheer

Rate limiting werkt pas goed wanneer je kunt zien wie de grens raakt en waarom. Meet daarom niet alleen het totaal aantal requests. Splits minimaal per API-key, endpoint, omgeving en type proces.

De minimale meetset

De eerste indicator is de 429-ratio per minuut en per API-key. Een stijging kan wijzen op een te lage limiet, een nieuwe batch, een fout in de client of ongewenst geautomatiseerd verkeer. De tweede is de p99-latency van kritieke routes zoals object- en waarderingsaanvragen. De derde is het dagverbruik ten opzichte van het beschikbare quotum.

Metric Drempel Actie
429-ratio Boven 1% Controleer retries, batchgrootte en sleutelverdeling
p99-latency Boven 800 ms Splits bronbelasting van clientproblemen uit
Dagverbruik Boven 80% Plan optimalisatie of vraag tijdig extra capaciteit aan

De genoemde drempels zijn praktische operationele startwaarden voor een teamdashboard, geen algemene prestatienormen. Zet waarschuwingen voor sandbox en productie apart. Een test die bewust een limiet raakt, mag geen productie-on-call activeren.

Maak limietbeheer onderdeel van het proces

Een Grafana-dashboard kan trends tonen, terwijl een compact Slack-rapport geschikt is voor dagelijkse controle. Log bij een 429 ten minste de API-key, het endpoint, de request-id, de ontvangen resetinformatie en de gekozen wachttijd. Sla geen woningdata op in je observabilitylaag die je daar niet nodig hebt.

Self-service kan een limietverhoging voorspelbaar maken. Een endpoint zoals POST /limits/request kan een tijdelijke aanvraag registreren met reden, omgeving, verwachte duur en gewenst volume. Automatische goedkeuring past alleen binnen een vooraf vastgesteld plafond. Structurele groei hoort bij account- en contractbeheer, niet bij een stilzwijgende tijdelijke uitzondering.

Gebruik performance monitoring voor API-integraties om je dashboardontwerp te koppelen aan latency, foutafhandeling en verbruik. Zo bespreek je een verhoging op basis van observaties, niet op basis van het gevoel dat “de API soms langzaam is”.

Implementatie-aanbevelingen voor Altum AI

Begin met scheiding, herstelgedrag en gecontroleerd testen. Voor een woningdata-integratie die zowel realtime aanvragen als batchverwerking uitvoert, leveren drie keuzes snel duidelijkheid op.

Scheid productieverkeer van batchverkeer

Gebruik twee API-keys: één voor productie en één voor batch- of herimporttaken. Een zware avondrun kan dan niet dezelfde sleutel uitputten als de realtime applicatie. Label beide sleutels in je metrics, zodat je ziet welk proces het quotum gebruikt.

Lees de response voordat je retry't

Stel retries met jitter in binnen een bereik van 200 milliseconden tot 8 seconden als applicatiekeuze, maar laat Retry-After voorgaan wanneer de response die waarde bevat. De API-documentatie van Altum AI beschrijft het headercontract en foutcode 429 voor overschreden rate limits in de API-documentatie.

Bij elke geweigerde call hoort je client de nieuwe headers te verwerken. Gebruik daarnaast de verbruiksinformatie in de response-body wanneer die beschikbaar is, zodat de worker weet hoeveel ruimte nog resteert. Een retry zonder logging maakt een batch moeilijk te reconstrueren.

Test eerst in de sandbox

Voer je limiettests uit tegen api.altum.ai/sandbox voordat je productie gebruikt. Test een enkele aanvraag, een batch, een bewuste overschrijding en herstel na Retry-After. Vraag een limietverhoging aan via het klantenportaal of via sales@altum.ai wanneer je structureel meer capaciteit nodig hebt. Plan dat gesprek zodra je boven 70% van het quotum draait, niet pas nadat een incident realtime verkeer blokkeert.

Veelgestelde vragen

Hoe vaak geeft Altum AI headers terug bij een 429? Bij elke geweigerde call, volgens het beschreven contract. Je client moet de waarden per response uitlezen en niet één eerdere resetwaarde blijven hergebruiken.

Wanneer is een limietverhoging zinvol? Wanneer je integratie structureel boven 70% van het quotum draait, je requestvolume al hebt verminderd met caching, batching of paginatie en je retries correct uitvoert. Dan is extra capaciteit een onderbouwde operationele keuze.

Altum AI biedt via één API-laag herleidbare woningdata en AI-inzichten voor waarde, energie en verduurzaming, zodat je rate limiting kunt koppelen aan objectkenmerken, woningwaardemodellen en energiedata. Bezoek Altum AI om de documentatie, sandbox en beschikbare integraties voor jullie woningdataworkflow te bekijken.