Recept
Linkscores synchroniseren vanuit een sheet of n8n
De meeste tool-dirs leven in een spreadsheet, een Airtable-basis of een kleine database. Dit recept zet een tool backlink-check om in een kolomvulling: één request per 2.000 rijen.
SEO Tools AI onderzoeksteam ·

Het recept in vijf stappen
Exporteer de domeinen
Haal de website-kolom van je listings, verwijder protocol en paden, en verwijder dubbele entries. Dubbele entries kosten niets extra, maar maken de mapping-stap rommelig.
Chunk in groepen van 2.000
bulk_dr accepteert maximaal 2.000 domeinen per call. Een sheet met 5.000 rijen vereist dus drie calls.
Verstuur, controleer ok
Roep de API aan, lees de JSON, en stop als ok false is. Log _credits zodat je het saldo na elke run ziet.
Schrijf terug met een datum
Sla de rating en de datum van vandaag op in twee kolommen. Overschrijf een goede waarde nooit met een lege waarde.
Plan één keer per maand
Voer het uit op de eerste van de maand. De index verandert ongeveer maandelijks, dus vaker uitvoeren levert niets op.
Kies wat de taak start
De trigger bepaalt hoe vaak de calls plaatsvinden, dus kies deze voordat je de mapping bouwt. Twee startmethoden dekken bijna elke directory.
Een planning op de eerste van de maand is de eenvoudigste optie. Het sluit aan bij het ritme van de index, en niemand hoeft aan een knop te denken.
Een planning voor de maandelijkse refresh
Zet een schedule trigger eerst, stel deze in op de eerste dag van elke maand, en laat hem de hele listing-tabel lezen. Elke run maakt dan één batch van bulk_dr calls, grootte afhankelijk van het aantal rijen.
Houd de planning ook aan als de tabel klein is. Een maandelijkse taak die op een kleine sheet draait kost één credit, en het houdt de scores gedateerd en actueel.
Een trigger op elke nieuwe rij
Stel je voor dat listings één voor één binnenkomen, om de paar dagen. Een trigger die afvuurt per nieuwe rij is verleidelijk, maar elke call wordt apart gefactureerd, dus één call per rij kost meer dan één batch voor de maand.
Als je de score snel wilt, laat de new-row flow een lege dr schrijven en laat de maandelijkse run deze invullen. De rij krijgt zijn nummer zonder een call bij elke aankomst.
Als listings in bursts binnenkomen, groepeer de nieuwe rijen dan in één batch aan het einde van de week. Dat kost één call, en de sheet verandert niet alleen nog maar één keer per maand.
Een datum die voltooide rijen markeert
Sla dr_checked_on op elke rij op die je scoort. Een run die start met een filter op die datum slaat over wat deze maand al klaar is, en er is geen aparte queue nodig.
Als een run halverwege stopt, blijven de rijen die al gestempeld zijn gestempeld. De volgende run pakt waar de vorige ophield, wat de goedkoopste recovery is.
Voordat je iets automatiseert
Voer de check eerst handmatig uit op vijf listings. Gebruik de gratis overview action voor elk, die geen key nodig heeft, en vergelijk wat je ziet met wat je verwachtte.
Dit vangt de veelvoorkomende verrassingen vroeg: een listing die naar een subdomein verwijst, een product dat op een pad van een grotere site leeft, een domein dat vorige lente doorverwees. Een rating behoort bij een domein, niet bij een product.
Bepaal hoe je sheet deze gevallen markeert, bijvoorbeeld met een notitie-kolom die shares domain leest. Lezers vergeven een voetnoot veel makkelijker dan een score die er verkeerd uitziet.
Als de vijf er gezond uitzien, ga dan over op de batch. Je field reference geeft de kolommen weer, en het cost example toont wat een run kost.
Een kleine Python-versie
Vereist het requests package. Het is een schets voor de vorm van de taak: print eerst één echte response, map daarna de velden die je nodig hebt naar je eigen kolommen.
import csv, requests
KEY = "sk_live_..."
BASE = "https://seotoolsai.org/api.php"
rows = list(csv.DictReader(open("listings.csv")))
domains = sorted({r["domain"] for r in rows})
for i in range(0, len(domains), 2000):
chunk = domains[i:i + 2000]
r = requests.post(BASE, params={"action": "bulk_dr", "key": KEY},
data={"domains": ",".join(chunk)}, timeout=60)
if r.status_code in (401, 402):
raise SystemExit(f"stop: HTTP {r.status_code}")
data = r.json()
if not data.get("ok"):
raise SystemExit("api said not ok")
print(data["_credits"]) # cost and remaining balance
open(f"raw_{i}.json", "w").write(r.text)
Doen in Google Sheets of n8n
Sheets kunnen een URL aanroepen vanuit Apps Script met UrlFetchApp, en n8n heeft een HTTP Request node. Beide doen hetzelfde als het script hierboven.
In n8n, zet een schedule trigger eerst, dan een node die je sheet of tabel leest, dan een item-splitting stap die groepen van 2.000 bouwt, dan de HTTP Request. Voeg een laatste node toe die de rating en datum terugschrijft.
Houd de key in de credential store van het platform, niet in de workflow tekst. Workflows worden gedeeld, gekopieerd en geplakt op forums, en een key die meegeplakt wordt is uitgegeven geld.
No-code of een script: welke vorm past bij je team
Beide routes maken dezelfde call. Het verschil is wie de flow over een jaar moet onderhouden, en hoe makkelijk het is om het aan die persoon uit te leggen.
Kies de vorm die je nog kunt lezen na een pauze van enkele maanden. Een slimme flow die niemand begrijpt is slechter dan een simpele script die iedereen kan volgen.
Een flow die je aan de volgende editor kunt uitleggen
Een korte n8n flow met vier gelabelde nodes is makkelijk over te dragen: trigger, read, batch, write back. Geef elke node een naam gebaseerd op wat hij doet, niet op het standaard label.
Vermijd het stapelen van veel branches voor edge cases. Elke branch is één plek meer waar een domein de verkeerde score kan krijgen.
Wanneer een script zijn plaats verdient
Een script heeft zin als de input een map met CSV-bestanden is, of als de taak logica nodig heeft die een flow lastig afhandelt. De schets hierboven past bij dat geval.
Zet het script in versiebeheer en houd de key in een environment variable. Een script dat zijn key leest uit een bestand in dezelfde map is een lek dat wacht op een shared drive.
Tutorials die het moeilijke deel overslaan
Veel video's tonen een flow die in één keer werkt met drie rijen. Echte listings hebben blanks, duplicates en vreemde domeinen, en daar heeft de flow aandacht voor nodig.
Bouw de flow eerst op je eigen vijf testrijen. Als een tutorial die niet kan overleven, was de tutorial nooit de hele taak.
Als je de flow aan iemand anders overdraagt, voeg dan de vijf testrijen toe als voorbeeld. De volgende persoon kan zien hoe een goede run eruitziet voordat hij live data aanraakt.
Wat de fouten betekenen
| Signaal | Betekenis | Wat de taak doet |
|---|---|---|
| HTTP 401 | Ontbrekende of foute key | Stop, alerteer een mens |
| HTTP 402 | Credits zijn op | Stop, houd oude scores aan, vul bij |
ok is false | De call is niet geslaagd | Log de body, retry volgende run |
| Leeg resultaat voor een domein | Niet in de index | Laat de cel leeg |

Houd de sheet schoon tussen runs
Een sync-taak is alleen zo goed als de sheet waar hij naar schrijft. Een paar gewoontes stoppen de langzame schade die opbouwt tussen de ene run en de volgende.
De meeste problemen beginnen met een onschuldige edit: een kolom ingevoegd boven de score, of een gekopieerde rij die stil een domein verandert.
Houd raw responses in hun eigen tab
Sla elke raw response op in een eigen tab, of als JSON Lines met één response per regel. Die kopie stelt je in staat de zichtbare kolommen opnieuw te bouwen zonder een tweede betaalde call.
Een raw tab beantwoordt ook de vraag die een editor zes maanden later stelt: wat returneerde de API op die datum.
Noem elke raw tab met de batch datum, zodat de kopies in volgorde sorteren als je terugscrollt.
Vries de header rij in
Bevries de header rij en voeg nooit een kolom in boven de score. Een mapping die naar kolom F wijst, leest de verkeerde data na een insert, en doet dit zonder foutmelding.
Noem de kolommen in de mapping bij naam, niet op positie. Een naam overleeft een herschikking, een positie niet.
Tel de rijen voor en na
Schrijf het aantal rijen in de log voor de run en opnieuw erna. De twee getallen mogen alleen verschillen door de rijen die je bewust wilde toevoegen, en een gat vertelt je dat er iets misging.
Sorteer de sheet één keer per maand op de score kolom en kijk naar de bovenste en onderste rijen. Vreemde waarden daar wijzen meestal op een domein die aan de verkeerde listing was gekoppeld.
Test eerst op een kopie
Dupliceer de sheet en voer de flow uit tegen de kopie voordat je de echte aanraakt. Een kopie kost niets om te maken.
Een slechte mapping die over live scores heen schrijft, is moeilijk ongedaan te maken, omdat de oude waarden weg zijn. Houd de kopie aan tot de eerste eerlijke run matcht met wat je verwachtte.
Verwijder de kopie pas nadat de tweede geplande run ermee heeft gematcht. Twee schone runs achter elkaar zijn een beter signaal dan één.
Voor de eerste live run
- De key zit in de credential store van het platform of een environment variable, niet in de workflow tekst.
- Een gratis
overviewcall was handmatig gecontroleerd tegen een listing die je kent. - De run was getest op een kopie van de sheet, en de kopie matchte wat je verwachtte.
- De taak schrijft de datum naast elke score die hij aanraakt.
- Status 401 en 402 stoppen de taak en sturen een bericht naar een persoon.
Sync vragen
Hoe betaal ik niet twee keer als de taak halverwege crasht?
Schrijf de datum naast elke score terwijl je gaat, en laat de volgende run rijen overslaan die deze maand al gestempeld zijn. Chunks van 2.000 betekenen dat een crash maximaal één credit kost, dus het risico is klein, maar de gewoonte houdt de sheet netjes.
Kan een niet-programmeur dit opzetten?
Grotendeels ja. Een HTTP Request node in n8n of Make vereist alleen een URL, een key en een lijst. Het lastige deel is het omzetten van de response naar kolommen, dus doe één test call en kijk naar de JSON voordat je de mapping bouwt.