Aan de slag
Van niets naar een WOZ-waarde in je eigen code. Reken op een paar minuten, waarvan het meeste het aanmaken van een account is.
1. Een sleutel aanmaken
Maak een gratis account op woz-api.nl en genereer een sleutel onder API sleutels. Je krijgt 10 credits, genoeg om de integratie af te maken voordat je iets betaalt.
Wil je eerst zien wat je terugkrijgt zonder account, dan staat er een live demo met een echte respons op de homepage, en de volledige OpenAPI-definitie in Swagger.
2. De eerste call
De sleutel gaat mee als header. Twee vormen werken:
| Header | Waarde |
|---|---|
X-Api-Key | {jouw sleutel} |
Authorization | ApiKey {jouw sleutel} |
curl "https://woz-api.nl/Api/Adres?adres=Spuistraat%2036C,%201012TT%20Amsterdam" \
-H "X-Api-Key: JOUW_API_KEY"
3. De respons lezen
De waarden staan in de reeks woz, met per element een peildatum en
een vastgesteldeWaarde. Een adres heeft doorgaans meerdere peildata. Wil je de
meest recente waarde, sorteer dan op peildatum in plaats van blind het eerste element te
pakken: de volgorde is geen contract.
import json, urllib.parse, urllib.request
url = "https://woz-api.nl/Api/Adres?" + urllib.parse.urlencode(
{"adres": "Spuistraat 36C, 1012TT Amsterdam"})
verzoek = urllib.request.Request(url, headers={"X-Api-Key": "JOUW_API_KEY"})
with urllib.request.urlopen(verzoek) as antwoord:
data = json.load(antwoord)
if data["wozStatus"] != "gevonden":
print("Geen openbare WOZ-waarde:", data["wozStatus"])
else:
recentste = max(data["woz"], key=lambda w: w["peildatum"])
print(recentste["peildatum"], recentste["vastgesteldeWaarde"])
Niet elk adres heeft een openbare WOZ-waarde: alleen van woningen is die openbaar. Bij een
kantoor, kerk of hotel krijg je een 200 met een lege woz en
huidigeWaarde: null, en zegt wozStatus waarom: geen_woning
als het pand volgens de BAG geen woonfunctie heeft, anders geen_waarde. Dat is een
antwoord en geen storing. Probeer het niet opnieuw, het blijft hetzelfde, en het kost geen
credit.
Voor Python, Node.js en .NET staat er een client die dit voor je doet, zie Clients.
4. Een lijst adressen
Een Excel of CSV met adressen vul je zonder code aan op WOZ-waarden bij een lijst adressen in Excel: een gratis proef met 5 adressen, de prijs vooraf, en hetzelfde bestand terug. Met code, ook als een AI-assistent het script schrijft, doe je per adres een aanroep. Een adres zonder WOZ-waarde kost geen credit, en een fout ook niet.
# pip install requests openpyxl
import time
import openpyxl
import requests
API = "https://woz-api.nl/Api/Adres"
SLEUTEL = "woz_..." # je API-sleutel; altijd in de header, nooit in een URL
BESTAND = "adressen.xlsx" # kolom A: straat en huisnummer, B: postcode, C: plaats
wb = openpyxl.load_workbook(BESTAND)
ws = wb.active
ws.cell(row=1, column=4, value="WOZ-waarde")
ws.cell(row=1, column=5, value="Peildatum")
ws.cell(row=1, column=6, value="Status")
s = requests.Session()
s.headers["X-Api-Key"] = SLEUTEL
def vraag(params):
# Bij een storing (502, 503) of te snel (429) zegt Retry-After hoe lang je wacht. Sla het
# adres niet over: een storing duurt meestal minuten, en opnieuw proberen kost niets.
for poging in range(6):
r = s.get(API, params=params, timeout=30)
if r.status_code not in (429, 502, 503):
return r
time.sleep(int(r.headers.get("Retry-After", 10 * (poging + 1))))
return r
for rij in range(2, ws.max_row + 1):
straat, postcode, plaats = (ws.cell(rij, k).value for k in (1, 2, 3))
if not straat or not (postcode or plaats):
ws.cell(rij, 6, "overgeslagen: geen adres of geen postcode en plaats")
continue
adres = f"{straat}, {postcode or ''} {plaats or ''}".strip()
r = vraag({"adres": adres})
if r.status_code == 200:
d = r.json()
huidig = d.get("huidigeWaarde")
if huidig:
ws.cell(rij, 4, huidig["vastgesteldeWaarde"])
ws.cell(rij, 5, huidig["peildatum"])
ws.cell(rij, 6, d.get("wozStatus")) # gevonden, geen_woning of geen_waarde
elif r.status_code == 402:
print("Saldo op. Opwaarderen:", r.json().get("detail", {}).get("opwaarderen"))
break
else:
ws.cell(rij, 6, r.json().get("code", str(r.status_code))) # AddressNotFound, of na een lange storing UpstreamUnavailable: draai die rijen later opnieuw
time.sleep(0.2)
wb.save("adressen-met-woz.xlsx")
Elke rij heeft straat en huisnummer samen in een cel nodig, plus een postcode of een plaats; zonder die twee nemen we de eerste treffer in het land. Hetzelfde recept staat in de handleiding op woz-api.nl.
Wat er mis kan gaan
| Status | Betekenis | Wat te doen |
|---|---|---|
400 | Adres onleesbaar of parameter ontbreekt | Controleer de url-encoding en of adres is meegestuurd |
401 | Sleutel ontbreekt of is ongeldig | Header X-Api-Key controleren; een ingetrokken sleutel geeft ook 401 |
402 | Credits op (code InsufficientCredits) | Opwaarderen; detail.opwaarderen geeft de link. Vang dit apart af, anders valt een batch halverwege om |
401 SleutelOntbreekt | Geen sleutel meegestuurd | Vraag een gratis proefsleutel aan met POST /Api/Proef, of maak een account aan |
402 ProefVerbruikt | De gratis proef is op | Geef het e-mailadres van de gebruiker (POST /Api/Proef/Email) of ga verder met credits |
404 | Adres niet gevonden (AddressNotFound) | Controleer huisnummer, toevoeging en postcode of plaats |
200, lege woz | Het adres bestaat, maar heeft geen openbare WOZ-waarde (wozStatus is geen_woning of geen_waarde) | Niet opnieuw proberen; kost geen credit |
502 503 | Een bron achter ons hapert (PdokLookupFailed, UpstreamUnavailable) | Opnieuw proberen met een oplopende wachttijd; dit kost geen credit |
Een fout heeft altijd dezelfde vorm, zodat je er één handler voor kunt schrijven:
{
"fout": "korte omschrijving",
"code": "machineleesbare code",
"status": 400,
"detail": "wat er precies misging",
"traceId": "id voor support"
}
Dat geldt ook voor een 400 door modelvalidatie; detail bevat dan per veld de
meldingen. Match in code op code, niet op de tekst in fout: die tekst kan
wijzigen, de codes niet. Alle codes staan in de referentie.
Credits en herhaalverkeer
1 credit is 1 uniek adres. Hetzelfde adres binnen 7 dagen opnieuw opvragen kost geen extra
credit; dat is een kortingsregel en geen cache, de request wordt echt uitgevoerd. Een opvraging
die op een fout eindigt kost niets, en een antwoord zonder WOZ-waarden (een lege woz)
ook niet. Je saldo staat in de responseheader X-Credits-Remaining en is
ook op te vragen via GET /Api/Credits.
Volgende stap
De referentie heeft alle endpoints en velden. Werk je liever zonder code, dan vult de Excel-wizard een bestand met adressen in één keer aan.