Je hebt net je orderkoppeling aangezet. De eerste honderd aanvragen lopen goed. Dan antwoordt de API met 429 Too Many Requests, een timeout volgt, en je worker begint dezelfde orders opnieuw aan te bieden. Een uur later weet niemand meer welke facturen veilig zijn, welke betaling al bestaat en welke records nog wachten.
Een rate limit is geen fout die je wegprogrammeert met “nog een keer proberen”. Je moet verkeer doseren, herstelbaar opslaan en bij een onbekende uitkomst eerst bewijs zoeken. Deze route is voor ondernemers en integratieverantwoordelijken die een order-, betaal- of factuurflow productiegeschikt willen maken.
Een herstelbare API-flow is een koppeling die haar aanvragen begrenst, Retry-After en exponentiële backoff toepast, werk in een queue bewaart en iedere mutatie aan een zakelijke sleutel koppelt. Bij een timeout maakt de flow geen nieuwe opdracht. Hij zoekt eerst uit wat de andere kant al heeft gedaan, reconcileert bron en doel en vraagt menselijke vrijgave zodra geld, voorraad of een klantbelofte geraakt kan zijn.
Wat heb je nodig voor een herstelbare API-flow?
Begin niet met de retry-knop. Verzamel eerst het contract en de gegevens waarmee je later kunt bewijzen wat er is gebeurd. Zonder die basis is een queue alleen een wachtrij voor onzekerheid.
Neem ook de mensen en het budget mee. Voor een kleine flow heb je minimaal deze rollen en vaardigheden nodig:
| Rol | Vaardigheden | Verantwoordelijkheid |
|---|---|---|
| Integratie-eigenaar | API-contracten, idempotentie en proceskeuzes | Beslist wanneer een write mag doorgaan en wie eigenaar is van een uitzondering |
| Backend- of platformengineer | HTTP, databases, workers, locks, secrets en observability | Bouwt ledger, queue, backoff, read-back en stopregels |
| Proces- of finance-eigenaar | Order-, betaal- en factuurregels en reconciliatie | Beoordeelt zakelijke verschillen en geeft financiële effecten vrij |
| Beheerder | Dashboards, alerts, incidenten en backfills | Bewaakt de flow en voert herstel uit volgens het runbook |
Eén persoon mag meerdere rollen dragen, maar wijs ze expliciet toe. Als niemand de zakelijke uitkomst mag vrijgeven, is een technisch correcte queue nog geen herstelproces.
Gebruik voor één provider en één schrijvende flow deze grove planorde, exclusief btw en providerkosten. Dit is een planningsraming, geen offerte:
| Onderdeel | Eenmalige inrichting | Doorlopend |
|---|---|---|
| Ledger, zakelijke sleutels en reconciliatiemodel | €4.000 tot €12.000 | €20 tot €200 per maand voor opslag en back-ups |
| Queue, worker, backoff en herstelpad | €5.000 tot €15.000 | €20 tot €250 per maand voor queue en runtime |
| Monitoring, dashboards en alerts | €1.500 tot €5.000 | €0 tot €300 per maand, afhankelijk van volume en retentie |
| Runbook, beheer en periodieke reconciliatie | €2.000 tot €6.000 | €500 tot €2.000 per maand voor beheer |
Bij meerdere providers, geld- of voorraadwrites of een oproepbare 24-uursdienst loopt deze orde snel op. Begroot ontwerp en beheer apart van de abonnementskosten van n8n, Make of je cloudinfrastructuur.
1. Een limietcontract per endpoint
Leg per API vast:
- de limiet per account, app, winkel, endpoint of IP-adres;
- of de limiet telt in aanvragen, punten, bytes, records of moduleacties;
- de burst-capaciteit en de herstelsnelheid;
- welke headers, foutcodes en responsevelden de provider geeft;
- de betekenis van
Retry-After,X-RateLimit-*of een eigen throttleveld; - de toegestane batchgrootte, paginering en maximale querykosten;
- welke bewerkingen veilig opnieuw kunnen en welke een zakelijke sleutel nodig hebben.
De limiet hoort bij de combinatie van jouw app en het doel, niet bij “de API” in het algemeen. Shopify gebruikt bijvoorbeeld verschillende modellen per API. De GraphQL Admin API werkt met berekende querykosten. De Shopify-documentatie over GraphQL-limieten (publicatiedatum niet vermeld, gecontroleerd op 18 oktober 2026) noemt 100 punten per seconde voor Standard, 200 voor Advanced Shopify, 1.000 voor Shopify Plus en 2.000 voor Commerce Components. Een enkele query mag 1.000 punten kosten en lijsten als invoer mogen maximaal 250 elementen bevatten. De actuele GraphQL-limieten van Shopify verschillen dus per API, plan en soort aanvraag.
2. Een duurzame verwerkingsledger
Bewaar vóór een externe write minimaal:
| Veld | Voorbeeld |
|---|---|
business_key | order-2026-10482 |
operation | create_invoice |
idempotency_key | order-2026-10482:invoice:v1 |
source_version | shopify:updated_at:2026-10-18T07:44:10Z |
payload_hash | SHA-256 van de verzonden inhoud |
status | queued, processing, verified, write_unconfirmed |
attempt_count | 0 |
next_attempt_at | UTC-tijdstip |
owner | finance of integration |
Een event-ID zegt welke aflevering je ontving. De idempotente sleutel zegt welke zakelijke handeling je voor welk doel uitvoert. Dat verschil voorkomt dat twee webhookafleveringen ook twee facturen worden. De praktische kern uit de uitleg over financiële replay en eigen ledgers is bruikbaar buiten betalingen: registreer de handeling vóór je neveneffect, bewaar het doelresultaat en hergebruik bij herstel dezelfde zakelijke sleutel.
Brandur Leach publiceerde deze technische uitwerking op 27 oktober 2017, gecontroleerd op 18 oktober 2026. Hij beschrijft hetzelfde patroon: de sleutel wordt eerst lokaal vastgelegd, daarna volgt de externe mutatie, waarna het doel-ID en de eindstatus terug de ledger in gaan. Dat is vooral belangrijk wanneer het proces na een timeout niet meer weet of de andere kant de aanvraag heeft uitgevoerd. De ledger maakt die onzekerheid een herstelbaar besluit.
De Developer Overheid-pagina Veilige retries met volledige idempotency heeft geen vermelde publicatiedatum, maar is gecontroleerd op 18 oktober 2026. De kern is gelijk: bewaar de Idempotency-Key duurzaam vóór de request en gebruik bij herstel exact dezelfde key. Een idempotency-key maakt een retry dezelfde handeling.
3. Een queue en een worker die je kunt stoppen
Je hebt een echte opslag nodig voor werk dat later mag gebeuren. Dat kan PostgreSQL, Redis Streams, SQS, RabbitMQ, BullMQ of een queue in n8n zijn, zolang je de zakelijke gegevens niet alleen in een vluchtig uitvoeringslog bewaart.
Een queue-item heeft een reden, prioriteit, pogingnummer, volgende poging, lease, eigenaar en maximale leeftijd. Houd live verkeer en herstelwerk uit elkaar. Een grote backfill mag geen nieuwe betalingen blokkeren omdat beide dezelfde workerpool gebruiken.
4. Testdata met lastige uitkomsten
Maak minstens deze proefrecords:
- een normale order met één factuur;
- dezelfde order twee keer aangeboden;
- een timeout na een
POSTwaarvan je de uitkomst niet kent; - een
429metRetry-Afterin seconden; - een
408op een leesaanvraag en na een write; - een
429met een HTTP-datum; - een
503zonder header; - een onherstelbare
400, zoals een ongeldig btw-nummer; - een late annulering of refund;
- een bronrecord dat tijdens de verwerking verandert;
- een pagina die precies op de grens van de limiet valt.
Gebruik een testwinkel in Shopify, een testaccount in Stripe en een testadministratie in Moneybird of Exact Online. Laat een tweede persoon controleren of de queue na elke test een begrijpelijke beslissing toont.
Concrete stappen: van 429 naar veilige vrijgave
Met dit stappenplan bouw je een herstelbare API-flow: je classificeert 429, 408 en tijdelijke fouten, legt vóór elke write een zakelijke sleutel vast, doseert batches, wacht met begrensde jitter, zoekt na timeouts eerst bewijs en geeft alleen gereconcilieerde orders of facturen vrij.
Voer deze acht controles in deze volgorde uit.
1. Classificeer de foutsoort
Een 429 betekent dat je in een bepaald tijdvak te veel aanvragen deed. RFC 6585 is gepubliceerd in april 2012 en gecontroleerd op 18 oktober 2026. De RFC beschrijft die status als rate limiting en zegt dat de response een Retry-After-header kan bevatten. De standaardtekst maakt ook duidelijk dat de server zelf bepaalt waarop hij telt. Dat kan per gebruiker, resource, credential of hele server zijn.
Maak in je verwerker minstens deze categorieën:
| Categorie | Voorbeelden | Automatisch handelen |
|---|---|---|
| Rate limit | 429, provider-throttle, quota op | Wachten volgens header en opnieuw aanbieden |
| Tijdelijk transport | 408, timeout, verbinding verbroken, 502, 503, 504 | Bij een read begrensd retryen; bij een write write_unconfirmed, eerst het doel opzoeken en nooit een nieuwe key maken |
| Conflict | 409, bronversie gewijzigd | Eerst opnieuw lezen, niet blind herhalen |
| Autorisatie | 401, 403 | Stoppen en eigenaar waarschuwen |
| Inhoudelijk | 400, schemafout, ongeldig bedrag | Naar herstelqueue, geen retry-loop |
| Leveranciersuitval | statuspagina rood, alle routes onbereikbaar | Incidentpad met fallback en backfill |
Een 429 is dus iets anders dan SaaS-uitval. Bij een limiet werkt de dienst, maar moet jouw werk langzamer. Bij uitval moet je vaak de schrijfroute stoppen en later een bronbackfill doen. De gids voor SaaS-uitval en herstel trekt dezelfde grens: een provider kan weer online zijn terwijl jouw ontbrekende events, dubbele aanbiedingen en openstaande vrijgave nog niet zijn opgelost.
2. Leg de zakelijke sleutel vast
Genereer de zakelijke sleutel uit een stabiele bronreferentie en het doel, niet uit het tijdstip van de retry. Voorbeelden:
shopify:order-10482:moneybird:invoice:v1;stripe:payment-intent-778:erp-payment:v1;shopify:order-10482:refund-1:creditnota:v1.
Schrijf die sleutel met status queued of processing weg voordat je de externe aanvraag doet. Bij een bestaande sleutel geldt het volgende:
verified: maak de retry een no-op en gebruik het bewaarde doel-ID;processing: voorkom een tweede gelijktijdige worker met een lease of database-lock;write_unconfirmed: zoek eerst het doelresultaat, schrijf niet opnieuw;failed: retry alleen als de foutcategorie dat toestaat;rejected: laat alleen een bevoegde nieuwe zakelijke handeling een nieuwe sleutel maken.
Bij kritieke writes moet de provider zelf idempotentie ondersteunen of moet jouw laag de onzekerheid op een andere manier oplossen. De Stripe-documentatie over idempotente requests vermeldt geen publicatiedatum, maar is gecontroleerd op 18 oktober 2026. Stripe bewaart bij API v1 de eerste statuscode en response voor een idempotency key nadat de endpointuitvoering is gestart. Keys kunnen na minimaal 24 uur worden verwijderd. Een hergebruikte key kan daarna dus een nieuwe aanvraag worden. De actuele Stripe-documentatie zegt ook dat parameters bij hergebruik moeten overeenkomen. Bewaar daarom jouw eigen ledger langer dan de bewaartermijn van de provider.
3. Doseer het verkeer
Batching maakt minder aanvragen, maar een batch is geen vrijbrief om de payload zo groot mogelijk te maken. Kies de kleinste maat die de verwerking efficiënt maakt en die na een fout opnieuw te bepalen is.
Stel per endpoint in:
- een maximum aantal gelijktijdige workers;
- een lokaal budget per minuut of per seconde;
- een batchgrootte die onder de invoerlimiet blijft;
- een cursor die je pas opslaat na een gecontroleerde verwerking;
- een overlapvenster voor backfill;
- een aparte capaciteit voor live events.
Gebruik cursor-based paginering wanneer de bron die levert. Offset-paginering kan records overslaan als er tijdens de import nieuwe orders tussenkomen. Sla per pagina de cursor, eerste sleutel, laatste sleutel, responsehash en aantal verwerkte records op. Bij een crash hervat je vanaf de laatst bevestigde cursor, met een kleine overlap die door dezelfde idempotente verwerker gaat.
De algemene Shopify-pagina over API-limieten heeft geen vermelde publicatiedatum en is gecontroleerd op 18 oktober 2026. Arrays mogen maximaal 250 elementen bevatten en arraypaginering wordt op 25.000 objecten afgekapt. Voor grote reads adviseert Shopify bulk operations. Dat betekent praktisch: stuur geen 250 mutaties omdat het toevallig mag. Meet de kosten, knip de opdracht op en gebruik voor grote backfills een speciaal pad dat live verkeer niet verdringt.
4. Respecteer Retry-After en voeg daarna begrensde jitter toe
Lees Retry-After in twee vormen:
delta-secondsis volgens RFC 9110, gepubliceerd in juni 2022 en gecontroleerd op 18 oktober 2026, een niet-negatief geheel aantal seconden, bijvoorbeeld2;- een HTTP-datum, die je omzet naar seconden vanaf de huidige UTC-klok.
Een waarde als 2.0 is dus geen standaardvorm. Parse decimalen alleen als expliciet gedocumenteerde provideruitzondering. Anders behandel je de header als ongeldig en gebruik je je lokale standaard. Een bruikbare formule is:
base = min(max_delay, initial_delay * 2^attempt)
wait = max(server_delay, willekeurig getal tussen 0 en base)
Zet ook een absolute bovengrens, bijvoorbeeld 60 seconden voor een interactieve orderflow en 15 minuten voor een grote backfill. Die getallen zijn startwaarden, geen providerregels. Maak ze instelbaar per endpoint.
Exponential backoff zonder willekeur laat alle workers op dezelfde momenten opnieuw beginnen. AWS beschreef in 2015, met een update in mei 2023, hoe jitter de pieken spreidt. In hun simulatie met 100 gelijktijdige clients daalde het aantal calls met meer dan de helft ten opzichte van backoff zonder jitter. Gebruik jitter daarom als bescherming tegen een tweede piek. Google Cloud raadt dezelfde combinatie aan wanneer de response én de bewerking idempotent zijn, en waarschuwt voor kettingreacties door onmiddellijk opnieuw te proberen. De actuele retry-strategie van Google Cloud is gecontroleerd op 18 oktober 2026.
Respecteer de serverdelay eerst. Voeg alleen een kleine positieve spreiding toe, zodat je niet eerder dan de aangegeven grens belt. Bij een ontbrekende header gebruik je full jitter of een andere gekozen variant. Log de berekende wachttijd, de bron van die waarde en het ingestelde plafond.
5. Maak stopcriteria zichtbaar
Een retry is geslaagd als de zakelijke uitkomst bekend is, niet als de worker vijf keer heeft geprobeerd. Geef elk item een maximaal aantal pogingen én een maximale leeftijd. Bijvoorbeeld: vijf pogingen in 20 minuten voor een orderstatus en daarna een herstelqueue. Voor een backfill kan de tijdgrens ruimer zijn, maar hij moet nog steeds bestaan.
Maak de retry-status leesbaar:
| Status | Betekenis | Volgende actie |
|---|---|---|
queued | Klaar voor een worker | Wachten op quota en lease |
retry_wait | Tijdelijk uitgesteld | Uitvoeren na next_attempt_at |
processing | Worker heeft het item geclaimd | Lease bewaken |
write_unconfirmed | Externe uitkomst onbekend | Doel opzoeken, niet opnieuw schrijven |
needs_review | Automatiek mag niet beslissen | Menselijk besluit |
verified | Doel en bewijs sluiten aan | Klaar |
dead_letter | Grens bereikt zonder veilig besluit | Escaleren met oorzaak en eigenaar |
Laat een worker zichzelf uitschakelen wanneer het aandeel 429’s boven een ingestelde grens komt, wanneer de wachtrij groeit terwijl de provider geen capaciteit teruggeeft of wanneer de reconciliatie een bedrijfstotaal niet meer sluit. Een stopregel is geen storing in je proces. Het is het moment waarop je voorkomt dat een kleine overschrijding een financiële achterstand wordt.
6. Herstel een onbekende write
Na een timeout weet je niet of de aanvraag niet aankwam, onderweg is uitgevoerd of wel klaar is maar het antwoord verloor. Zet de status dus op write_unconfirmed.
Zoek eerst op:
- jouw idempotency key;
- de zakelijke sleutel bij het doel;
- een providerobject dat bij de bronactie hoort;
- de eigen ledger en de laatst opgeslagen response;
- de bronstatus, inclusief eventuele late webhook.
Vind je hetzelfde doelobject met dezelfde payloadhash, dan leg je de doelreferentie vast en markeer je de handeling als verified na read-back. Vind je niets en ondersteunt de provider idempotentie, hergebruik je dezelfde key. Blijft het onbekend, dan gaat het item naar de herstelqueue. Een nieuwe key is alleen toegestaan wanneer iemand bewust een nieuwe zakelijke correctie vrijgeeft.
De Stripe-documentatie over webhook endpoints heeft geen vermelde publicatiedatum, maar is gecontroleerd op 18 oktober 2026. Volgens deze documentatie worden niet-afgeleverde events tot drie dagen automatisch opnieuw aangeboden. Je kunt handmatig zoeken op delivery_success=false, een eventtype en een venster; de List Events API kijkt tot 30 dagen terug. Gebruik die backlog als bron voor herstel, niet als aanleiding om een tweede boeking te maken.
7. Reconcileer vóór vrijgave
Een geslaagde HTTP-response is geen bewijs dat je bedrijfsuitkomst klopt. Voer per herstelbatch vier controles uit:
- Telling: aantal bronrecords, queue-items, doelrecords en afwijzingen.
- Sleutelset: alleen bron, alleen doel, aan beide kanten gelijk, aan beide kanten verschillend.
- Waarden: status, bedrag, valuta, btw, orderregels en doelreferentie.
- Totalen: totaalbedrag, aantal facturen, betalingen, refunds en eventueel voorraad.
Leg per verschil een oorzaak vast: dubbele aflevering, ontbrekende webhook, late wijziging, annulering, ongeldig record, onbekende write of stale write. Een bronversie beschermt je tegen een oude snapshot, maar niet tegen iedere race tussen lezen en schrijven. Bij meerdere schrijvers heb je een voorwaardelijke write zoals If-Match, een compare-and-swap of een post-write broncheck nodig. De gids over bronversies, read-back en stale writes werkt dat onderscheid uit: idempotentie beschermt tegen dubbel effect, versiecontrole tegen oude data.
Voor geld en facturen is menselijke vrijgave geen zwaktebod. Toon de bronwaarde, doelwaarde, sleutel, payloadhash, foutreden, bedrag, voorgestelde actie en bewijslink. Finance mag een boeking vrijgeven. Operations mag een orderconflict beoordelen. De technische eigenaar mag de flow stoppen. Leg die rollen vast en laat de invoerder van een fallback niet automatisch zijn eigen correctie goedkeuren.
8. Hervat gecontroleerd
Open na een incident niet meteen de volledige achterstand. Verwerk bijvoorbeeld tien records, vergelijk opnieuw en geef daarna pas de volgende batch vrij. Houd live events en backfill apart, laat de queue open voor late webhooks en controleer na de eerste volledige cyclus nogmaals de totalen.
Meet minimaal:
- percentage 429’s per endpoint en per credential;
- p50 en p95 wachttijd tot retry;
- queue-leeftijd en aantal
write_unconfirmed-items; - retries per business key;
- dubbele doelobjecten, liefst nul;
- tijd van eerste fout tot menselijke beslissing;
- aantal records zonder bron- of doelmatch;
- verschil tussen providerquota en jouw lokale budget.
Test ook een limietwijziging en een provider die tijdelijk Retry-After anders invult. De flow moet niet alleen werken bij de quota die je vandaag ziet. Hij moet stoppen wanneer het limietcontract verandert.
Valkuilen die je orderflow laten ontsporen
Je retryt iedere fout
Een ongeldige payload wordt niet geldig door hem vijf keer te versturen. Een 401 wordt geen quota-issue en een 403 geen tijdelijke storing.
Mitigatie: koppel iedere status en foutcode aan één categorie. Retry alleen tijdelijke fouten of een expliciet rate-limitantwoord. Stuur inhoudelijke fouten naar een queue met reden en eigenaar.
Je gebruikt alleen een vaste wachttijd
Tien workers die allemaal twee seconden wachten, komen opnieuw tegelijk. Dat is een tweede piek die de provider en jouw eigen workerpool verder belast.
Mitigatie: lees Retry-After, gebruik begrensde exponentiële backoff en voeg jitter toe. Reserveer capaciteit voor live werk.
Je batcht vóór je de limiet begrijpt
Een batch van 250 kan bij de ene endpoint legaal zijn en bij de andere te zwaar. Bij GraphQL telt de querykosten, niet alleen het aantal objecten.
Mitigatie: meet requested en actual cost, begrens batchgrootte per endpoint en sla de cursor pas op nadat de batch veilig is verwerkt.
Je laat meerdere workers hetzelfde quota gebruiken
Een lokale rate limiter per proces kan drie containers ieder 2 aanvragen per seconde laten doen op een limiet die voor de hele app geldt.
Mitigatie: deel het budget in Redis, PostgreSQL of een queue-coördinator, en neem in je sleutel de provider, app, store en endpoint op.
Je verwart event-ID en zakelijke sleutel
Een bron kan dezelfde gebeurtenis meerdere keren afleveren. Twee event-ID’s kunnen dus één betaling of één order vertegenwoordigen.
Mitigatie: bewaar de event-ID voor aflevering en maak een afzonderlijke idempotency key voor de bedrijfsactie. Laat de tweede aanbieding een gecontroleerde no-op worden.
Je behandelt 200 OK als vrijgave
Een 200 kan alleen betekenen dat de API jouw verzoek ontving. Een asynchrone downstreamactie kan nog wachten, mislukken of door een andere writer worden overschreven.
Mitigatie: gebruik aparte statussen voor received, processing, verified en needs_review. Lees het doel terug en controleer de actuele bronversie.
Je maakt een nieuwe key na een timeout
Dat is precies hoe één refund of factuur twee keer wordt uitgevoerd. De nieuwe key verbergt de onzekerheid in plaats van haar op te lossen.
Mitigatie: hergebruik dezelfde sleutel zolang het om dezelfde zakelijke handeling gaat. Maak een nieuwe sleutel alleen voor een bewust vrijgegeven correctie.
Je gebruikt je workflowlog als audittrail
n8n of Make kan laten zien dat een stap draaide. Dat bewijst niet dat jouw doelobject later nog bestaat, dat een response bij de juiste order hoort of dat een mens het verschil heeft beoordeeld.
Mitigatie: schrijf ledger, queue, payloadhash, doelreferentie en vrijgavebesluit naar duurzame opslag buiten de uitvoeringshistorie.
Je verwart rate limiting met SaaS-uitval
Bij 429 moet je meestal langzamer werken. Bij provideruitval moet je mogelijk schrijven stoppen, een fallback gebruiken en later een bronbackfill uitvoeren.
Mitigatie: geef beide situaties een eigen runbook, incidentstatus en stopcriterium. Laat een groene statuspagina de reconciliatie niet overslaan.
Je vergeet stale writes
Een oude order- of voorraadlezing kan na een wachttijd alsnog een nieuwere waarde overschrijven. Een keurige retry maakt die fout alleen opnieuw.
Mitigatie: bewaar de bronversie in de ledger, gebruik een voorwaardelijke write waar dat kan en voer anders een post-write broncheck uit. Bij een gewijzigde bronversie gaat de publicatie naar de queue.
Beslis-kader: kant-en-klaar, workflowlaag of maatwerk?
Kies niet op het gemiddelde volume. Kies op de zwaarste fout die je moet kunnen uitleggen. Eén onomkeerbare factuuractie kan meer controle vereisen dan duizenden veilige leesaanvragen.
Kant-en-klaar past wanneer
Kies een native connector of SDK wanneer één systeem bronhouder is, de richting vaststaat, writes omkeerbaar zijn en de tool het volgende aantoonbaar kan:
Retry-Afteren providerquota lezen;- bestaande doelobjecten herkennen;
- idempotente writes uitvoeren;
- cursorpaginering hervatten;
- read-back en foutstatus bewaren;
- een mislukte of onbekende write in een eigen queue zetten.
Ontbreekt één van die punten, dan is “native” vooral een snelle start. Voor een flow die alleen productinformatie leest of statussen synchroniseert, kan dat prima zijn. Voor geld of facturen niet zonder extra controlelaag.
Een workflowlaag past wanneer
Gebruik n8n of Make als de regels stabiel zijn, je één technische eigenaar hebt en je de duurzame ledger buiten de workflowtool kunt opslaan. Laat de workflow de API’s orkestreren, niet jouw enige bewijs vormen.
De n8n-prijspagina, gecontroleerd op 18 oktober 2026, rekent met volledige workflowuitvoeringen. Starter staat op €20 per maand bij jaarlijkse betaling voor 2.500 uitvoeringen met onbeperkte stappen. Pro staat op €50 voor 10.000 uitvoeringen. De Community Edition is self-hosted beschikbaar. De Make-prijspagina, ook gecontroleerd op 18 oktober 2026, gebruikt credits: de meeste moduleacties kosten één credit, en bij een lege bundel pauzeren scenario’s terwijl inkomende webhooks in de beschikbare wachtrij kunnen blijven staan. Controleer bedragen opnieuw per valuta en betaalperiode wanneer je begroot.
De eigen database blijft nodig voor bronversies, idempotente sleutels, onbekende writes, reconciliatie en menselijke besluiten. Een workflowplatform versnelt de orkestratie. Het neemt je datamodel voor herstel niet automatisch over. Bekijk de actuele n8n-plannen en Make-prijsdetails opnieuw wanneer je de flow begroot.
Maatwerk past wanneer
Bouw een eigen integratielaag wanneer meerdere systemen dezelfde velden kunnen wijzigen, writes geld of voorraad raken, de providercontracten sterk verschillen of je een audittrail over meerdere jaren nodig hebt. Maatwerk betekent niet dat iedere API-client nieuw moet worden gebouwd. Het betekent dat jij de zakelijke sleutel, quota, queue, reconciliatie en vrijgave beheert rond de bestaande tools.
Kan een dubbele of late write geld, voorraad of een klantbelofte raken?
De keuzehulp geeft dezelfde drie uitkomsten als het geschreven kader. Het verschil zit in de foutkosten, de bronhouders en de vraag of je na een retry nog kunt bewijzen welke bedrijfsactie bestaat.
Uitgewerkt voorbeeld: Shopify-orders naar Moneybird met n8n
Dit is een fictief oefenscenario met echte productnamen en voorbeeldwaarden. De getallen illustreren de beslislogica en zijn geen prestatiebelofte.
Een webshop gebruikt Shopify voor ordercreatie, Stripe voor betalingen, n8n voor de orkestratie en Moneybird voor facturen. De flow verwerkt gemiddeld 180 orders per dag. Eén Shopify-order kan maximaal één factuurvoorstel maken. De factuur mag pas worden vrijgegeven als de betaalstatus, het orderbedrag en de zakelijke sleutel bij elkaar passen.
De voorbereiding
Voor iedere order maakt de flow deze ledgerregel:
business_key: shopify:order-10482
operation: moneybird:create-invoice
idempotency_key: shopify:order-10482:moneybird:invoice:v1
source_version: shopify:updated_at:2026-10-18T07:44:10Z
status: queued
De n8n-worker heeft aparte limieten voor Shopify, Stripe en Moneybird. Shopify gebruikt de GraphQL Admin API. De worker leest de throttleStatus uit de response en houdt een gedeeld budget per winkel bij. De invoer blijft onder 250 elementen. De cursor gaat pas vooruit wanneer de order, betaalmatch en ledgerstatus veilig zijn opgeslagen.
De 429
Om 09:02 komt een piek van 40 orders binnen. De eerste batch wordt geaccepteerd. De tweede aanvraag krijgt 429 met Retry-After: 2. De worker zet de batch op retry_wait, plant hem niet eerder dan twee seconden later en voegt een kleine positieve spreiding toe. Hij maakt geen nieuwe order of ledgerregel.
De monitoring toont nu:
| Meting | Waarde in dit voorbeeld |
|---|---|
| Nieuwe orders in de batch | 40 |
| Eerste 429’s | 1 batch |
| Nieuwe zakelijke sleutels door retry | 0 |
| Live capaciteit gereserveerd | 30% |
| Maximum pogingnummer | 2 |
Een derde poging krijgt een 503. De itemstatus blijft retry_wait; de backoff groeit en de poging telt mee tegen de maximale leeftijd. De worker blijft andere orders verwerken die een eigen sleutel en beschikbare quota hebben. Eén vastgelopen batch blokkeert de hele orderstroom niet.
De onbekende factuurwrite
Na een geslaagde betaalmatch stuurt n8n een factuurvoorstel naar Moneybird. De verbinding valt weg nadat de aanvraag is verstuurd. De flow zet de order op write_unconfirmed. Hij maakt geen tweede moneybird:create-invoice-key.
De herstelworker zoekt eerst in zijn ledger, op de orderreferentie en op de opgeslagen payloadhash. Hij vindt een Moneybird-doelreferentie die inhoudelijk gelijk is. Daarna leest hij de factuurstatus terug en controleert hij opnieuw dat Stripe de betaling voor dezelfde order bevestigt. De status wordt verified. Als Moneybird niets had teruggegeven, was de order naar needs_review gegaan. Finance had dan de opdracht gekregen om de factuur te zoeken of vrij te geven, niet om blind opnieuw te boeken.
De reconciliatie
Om 09:18 vergelijkt de flow het venster van 09:00 tot 09:15 met vijf minuten overlap:
| Controle | Uitslag in dit voorbeeld |
|---|---|
| Unieke Shopify-orders | 40 |
| Geldige Stripe-betaalmatches | 39 |
| Moneybird-facturen met doelreferentie | 39 |
| Onbekende writes | 1, teruggevonden |
| Onverklaarde orderverschillen | 0 |
| Openstaande menselijke besluiten | 1 betaling ontbreekt |
De ene order zonder betaalmatch wordt niet gefactureerd en niet verzonden. De order blijft in een herstelqueue met eigenaar Finance, reden payment_not_confirmed, deadline en bronlink. De overige 39 worden in een kleine batch vrijgegeven. Daarna wordt de volgende queue-batch geopend.
Een tweede controle ontdekt dat één klant tijdens de piek twee keer heeft besteld. De Shopify-orders hebben verschillende order-ID’s en verschillende betaal-ID’s. Dit is geen technische duplicaat maar een zakelijke tweede aankoop. De sleutelcontrole maakt dat onderscheid zichtbaar. De flow annuleert niet automatisch, maar laat Operations de klantcontext beoordelen.
Het besluit
De webshop hervat de normale route niet zodra Shopify weer antwoordt. Hij hervat wanneer de quota, de queue, de betaalmatches, de factuurreferenties en de open besluiten zichtbaar zijn. De 429 is dan geen incident dat uit de log verdween, maar een verklaarde vertraging met nul nieuwe zakelijke sleutels.
Vergelijkingstabel: welke bouwroute past bij deze klus?
De productdetails en prijsinformatie hieronder zijn gecontroleerd op 18 oktober 2026. Abonnementskosten zijn niet de totale projectkosten. Ontwerp, testdata, monitoring, opslag, secrets, beheer en reconciliatie horen apart in je begroting.
| Route | Actuele details | Prijsbeeld | Past wanneer | Breekpunt |
|---|---|---|---|---|
| Native SDK of connector | Provider beheert client en basislimieten. Controleer zelf Retry-After, cursor, idempotentie, read-back en onbekende writes | Meestal onderdeel van providerpakket of apart abonnement | Eén bron, vaste richting, omkeerbare writes | Geen eigen ledger of geen herstelstatus |
| Make | Credits zijn de rekeneenheid. De meeste moduleacties kosten één credit. Bij lege credits pauzeren scenario’s en kunnen webhooks in de beschikbare queue wachten | Free bevat 1.000 credits per maand; betaalde plannen worden per creditbundel en valuta getoond | Stabiele regels, beperkte uitzonderingen, weinig custom code | Veel acties per order, complexe ledger en streng auditbewijs |
| n8n Cloud | Starter €20 per maand bij jaarlijkse betaling voor 2.500 uitvoeringen; Pro €50 voor 10.000. Beide rekenen per volledige workflowuitvoering met onbeperkte stappen. Community Edition is self-hosted beschikbaar | Actuele n8n-plannen en uitvoeringslimieten | Meerdere API’s, technische eigenaar, eigen opslag voor ledger en queue | Hosting, secrets, back-ups en audit blijven jouw verantwoordelijkheid bij self-hosting |
| Eigen integratieservice | Eigen PostgreSQL-ledger, gedeeld quota, queue, read-back, reconciliatie en vrijgave | Geen pakketprijs. Bouw, infrastructuur en onderhoud zijn projectwerk | Geld, voorraad, meerdere schrijvers, meerdere providers, langdurig bewijs | Hogere startinspanning en blijvend eigenaarschap |
Een native route is geschikt als hij de onbekende toestand kan benoemen. Make of n8n is sterk wanneer je de flow snel wilt orkestreren en de controlelaag zelf bezit. Maatwerk verdient zijn plek zodra de uitzonderingen het normale werk worden.
De beste rate-limitstrategie is uiteindelijk geen formule. Het is een contract: wanneer mag de flow wachten, wanneer moet hij stoppen, wanneer is een retry dezelfde handeling en wanneer moet een mens beslissen? Als je dat contract kunt testen op een order, een betaling en een factuur, blijft een quota-overschrijding een beheersbare vertraging. Zonder dat contract wordt één verloren response de plek waar je administratie begint te gokken.
Veelgestelde vragen
API-flow die blijft lopen
Ik ontwerp met je mee hoe jouw koppeling quota, retries en onbekende uitkomsten afhandelt, bouw de herstelqueue en reconciliatie en lever de integratie end-to-end op.
Dit artikel is geproduceerd samen met het Agent Team. Meer over de redactie.
