Every parcel to the right door.
RightDoor checks Dutch and Belgian shipping addresses against the official registers. It fixes small mistakes, tells you exactly what's wrong, and never blocks a real customer.
View API response
POST /v1/validate
{
"countryCode": "NL",
"address1": "binenhof 1a",
"zip": "2513aa",
"city": "amsterdam"
}
{
"status": "corrected",
"normalized": {
"address1": "Binnenhof 1 A",
"address2": null,
"zip": "2513 AA",
"city": "'s-Gravenhage",
"countryCode": "NL"
},
"formatted": [
"Binnenhof 1 A",
"2513 AA 's-Gravenhage"
],
"match": {
"street": "Binnenhof",
"houseNumber": 1,
"houseNumberSuffix": "A",
"unit": null,
"unitType": null,
"locality": "'s-Gravenhage",
"postcode": "2513AA"
},
"suggestions": [],
"confidence": "medium",
"blocking": false,
"issues": [
{
"code": "STREET_MISMATCH",
"severity": "warning",
"field": "address1",
"message": "The street name doesn't match this postcode. Did you mean Binnenhof?"
},
{
"code": "CITY_MISMATCH",
"severity": "warning",
"field": "city",
"message": "The city doesn't match this postcode. Did you mean 's-Gravenhage?"
}
],
"carrier": {
"street": "Binnenhof",
"postcode": "2513 AA",
"city": "'s-Gravenhage",
"countryCode": "NL",
"houseNumber": "1",
"houseNumberAddition": "A",
"warnings": []
},
"nextStep": "The address was corrected. Show the corrected address to the customer and use it if they agree.",
"meta": {
"datasetVersion": "nl-bag:2026-10-01+nl-lvbag:2026-09-08",
"source": "Kadaster BAG",
"attribution": null,
"language": "en"
}
}GET /v1/nl/lookup?postcode=2513AA&number=1
{
"addresses": [
{
"street": "Binnenhof",
"houseNumber": 1,
"houseNumberSuffix": null,
"addition": null,
"postcode": "2513 AA",
"locality": "'s-Gravenhage",
"formatted": [
"Binnenhof 1",
"2513 AA 's-Gravenhage"
]
},
{
"street": "Binnenhof",
"houseNumber": 1,
"houseNumberSuffix": "A",
"addition": "A",
"postcode": "2513 AA",
"locality": "'s-Gravenhage",
"formatted": [
"Binnenhof 1 A",
"2513 AA 's-Gravenhage"
]
},
{
"street": "Binnenhof",
"houseNumber": 1,
"houseNumberSuffix": "B",
"addition": "B",
"postcode": "2513 AA",
"locality": "'s-Gravenhage",
"formatted": [
"Binnenhof 1 B",
"2513 AA 's-Gravenhage"
]
},
{
"street": "Binnenhof",
"houseNumber": 1,
"houseNumberSuffix": "D",
"addition": "D",
"postcode": "2513 AA",
"locality": "'s-Gravenhage",
"formatted": [
"Binnenhof 1 D",
"2513 AA 's-Gravenhage"
]
}
],
"additions": [
null,
"A",
"B",
"D"
],
"issues": [],
"nextStep": "This number has several addresses (A, B, D). Ask the customer which one, then validate again.",
"meta": {
"datasetVersion": "nl-bag:2026-10-01+nl-lvbag:2026-09-08",
"source": "Kadaster BAG",
"attribution": null,
"language": "en"
}
}POST /v1/validate
{
"countryCode": "BE",
"address1": "rue de la loi 16",
"zip": "1000",
"city": "bruxelles"
}
{
"status": "valid",
"normalized": {
"address1": "Rue de la Loi 16",
"address2": null,
"zip": "1000",
"city": "Bruxelles",
"countryCode": "BE"
},
"formatted": [
"Rue de la Loi 16",
"1000 Bruxelles"
],
"match": {
"street": "Rue de la Loi",
"houseNumber": 16,
"houseNumberSuffix": null,
"unit": null,
"unitType": null,
"locality": "Bruxelles",
"postcode": "1000"
},
"suggestions": [],
"confidence": "high",
"blocking": false,
"issues": [],
"carrier": {
"street": "Rue de la Loi",
"postcode": "1000",
"city": "Bruxelles",
"countryCode": "BE",
"houseNumber": "16",
"houseNumberAddition": null,
"warnings": []
},
"nextStep": "Address is valid. Use the normalized address.",
"meta": {
"datasetVersion": "be-best-bru:2026-10-07+be-best-vlg:2026-10-07+be-best-wal:2026-10-07",
"source": "BeST Address (FPS BOSA)",
"attribution": "BeST Address – FPS BOSA, CC BY 4.0",
"language": "en"
}
}POST /v1/validate
{
"countryCode": "NL",
"address1": "Postbus 20018",
"zip": "2500 EA",
"city": "Den Haag"
}
{
"status": "invalid",
"normalized": null,
"formatted": null,
"match": null,
"suggestions": [],
"confidence": "low",
"blocking": true,
"issues": [
{
"code": "PO_BOX_NOT_ALLOWED",
"severity": "error",
"field": "address1",
"message": "We can't deliver to a PO box. Please enter a street address."
}
],
"carrier": null,
"nextStep": "PO boxes aren't accepted. Ask the customer for a street address.",
"meta": {
"datasetVersion": "nl-bag:2026-10-01+nl-lvbag:2026-09-08",
"source": "Kadaster BAG",
"attribution": null,
"language": "en"
}
}Scripted sample using public buildings. The live API returns the same shape.
Try it with your own addresses, free →Two countries. A hundred ways to miss the door.
Generic address checks don't know these. RightDoor does, by their real names.
One building, many additions
Letters, numbers, floors, hs for ground floor. A wrong toevoeging sends the parcel to the neighbour or back to the depot.
Brussels says it twice
Both names are official. RightDoor matches Dutch, French and German street names, and keeps the one the customer typed.
The box behind the number
Written bus 3, boîte 3 or 16/3. Without it, the courier can't find the letterbox.
The house that isn't registered yet
New builds count as valid. People order before the register catches up, and rejecting them loses the sale.
Never blocks a real customer.
A validation tool that rejects real people costs you sales. RightDoor gives advice. You decide what to do with it, and if RightDoor is ever slow, your client accepts the address and carries on.
Drop it into your checkout.
One script tag and one element. Your form gets the address as the register writes it, split the way carriers want it, with a verdict your server can verify.
Try 2513 AA and number 1, the Binnenhof in The Hague. Or switch to Belgium, enter 1000 and start typing Wetstraat.
The live form appears here when JavaScript is on.
HTML
<script src="https://js.rightdoor.eu/v1/address.js" async></script>
<rightdoor-address key="rd_pk_live_…" countries="NL,BE"></rightdoor-address>- Postcode first
- Postcode and number fill in the street and city. The shopper picks the toevoeging from the ones that exist.
- Belgium too
- Street suggestions in the shopper's language, Brussels in French and Dutch, then the bus.
- Your form, your fields
- No iframe: the browser's saved addresses fill it, and it submits with your form. Or attach it to the inputs you have.
- Fails open
- No answer within 1.5 seconds? It becomes an ordinary form. Nothing ever blocks the submit.
- Safe in a web page
- A publishable key that only works on your sites, with a daily cap you set. A signed receipt your server can check.
- Nothing extra
- No cookies, no tracking, under 9 kB. Included in every plan.
One call. A response you can act on.
Sign up with email or GitHub, turn on two-factor authentication, rotate keys without downtime. Answers come back in milliseconds, already split the way carriers want them.
curl
curl https://api.rightdoor.eu/v1/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"address1": "Binenhof 1A",
"zip": "2513AA",
"city": "Amsterdam",
"countryCode": "NL"
}'JavaScript
const res = await fetch("https://api.rightdoor.eu/v1/validate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RIGHTDOOR_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(address),
});
const result = await res.json();
if (result.blocking) askShopperToCheck(result);
else accept(result.normalized ?? address);| Valid | The address exists. New builds count here too. |
| Corrected | A small mistake was fixed. Show the corrected address. |
| Ambiguous | The number has units A, B and C. Let the shopper pick. |
| Invalid | Not deliverable as written. Blocking is advice only. |
Street, house number and addition, checked against the field limits of PostNL, bpost, DHL and Sendcloud, with official abbreviations when a line is too long. Messages come in Dutch, French, German and English.
Bring it to where you sell.
Two more ways to use RightDoor without writing the integration yourself. Register your interest when you sign up.
Shopify app
Check addresses in checkout and flag risky orders, for Shopify merchants in the Netherlands and Belgium.
MCP server for AI agents
Let agents verify an address before they ship, book or invoice, including addresses written as one free-form line.
Starting with two countries. Built for many.
Every country has its own address quirks. We learn them one official register at a time. The Netherlands and Belgium are live, and more EU countries are planned.
Official registers
The address registers of the Dutch and Belgian governments, published as open data and credited in the footer.
Versioned
Every response names the dataset version it was checked against.
Compared and forgotten
Addresses are never stored and never logged. Hosted in the EU, in Frankfurt. A data processing agreement is available.
Pay for verifications. Every country included.
Prices in euros, excluding VAT, billed monthly. The Netherlands and Belgium are in every plan.
Costs above the included amount assume you opted in to pay-as-you-go. Without it, a paid plan stops at the limit.
Developer
- 2,500 verifications
- Stops at the limit
- 60 requests / min
Starter
- 15,000 verifications
- €1.00 per 1,000 over
- 300 requests / min
Growth
- 100,000 verifications
- €0.60 per 1,000 over
- 1,200 requests / min
Scale
- 500,000 verifications
- €0.35 per 1,000 over
- 3,000 requests / min
Enterprise
- Custom verifications
- Custom contract
- 6,000 requests / min
What counts as a verification
One lookup or one validation, whether the address turns out valid or not. Suggestions during one typing session plus the validation that ends it count as one. Errors, rate-limited requests and test keys never count.
No surprise bills
Paid plans stop at the included amount by default. Opt in to pay-as-you-go above it, per 1,000 as listed.
Free test keys
100 calls a day on every plan, for building and testing an integration.
Changing plans
Upgrades apply at once, prorated. Downgrades and cancellations take effect at the end of the billing period.
Payment
Card, Apple Pay, Google Pay and Link. Invoices include VAT; EU businesses with a VAT ID are reverse-charged.
Questions developers ask.
Which countries do you cover?
The Netherlands and Belgium today. More EU countries are planned.
Where does the data come from?
From the official Dutch and Belgian government address registers, which are open data. Each response includes the dataset version it was checked against, and the sources are credited in the footer.
Do you store the addresses I send?
No. Addresses are compared and forgotten, never stored and never logged. RightDoor is hosted in the EU, in Frankfurt, and a data processing agreement is available.
What happens if RightDoor is down?
RightDoor is built to fail open. If it is ever slow or unavailable, your client should accept the address and let the order through. The status page shows current availability.
What counts as a verification?
One address being checked. Send the same sessionId with the lookups, suggestions and validation of one address and they count as one verification together; the address form does this for you. Errors, rate-limited requests and test keys never count.
Are suggestions billed per keystroke?
No. A typing session and the validation that follows count as one verification together.
Can I put a key in my web page?
Yes, a publishable key: it only works from the sites you list, only for address lookups, and has a daily cap you set. Your secret keys stay on your server.
Can I cancel any time?
Yes. Cancellations and downgrades take effect at the end of the billing period.