Alles wat je nodig hebt om de feed op te halen en te verwerken.
De specificatie is Engels, net als de feed zelf.
Status: in use since step 3 · Last update: 2026-09-05 (fully English feed)
Verhuren.nl delivers listings as JSON. You fetch the feed with a token in an HTTP header; our endpoint redirects you to a static file on our CDN, so fetching is fast and we can still count how often it happens.
The feed is regenerated every five minutes.
This specification is English only. The feed itself — paths, file names, keys, values and error messages — is English as well, so a developer connecting to us never has to read Dutch. The rest of the product (the website, the provider's own screens) is in Dutch.
GET https://verhuren.nl/feed/v1/<platform-slug>/all
Authorization: Bearer <your feed token>
curl -sL -H "Authorization: Bearer $VERHUREN_FEED_TOKEN" \
https://verhuren.nl/feed/v1/kamer-nl/all | jq .
-L matters: on success you get a 302 to the file on the CDN. If the file does
not exist yet — right after you have been approved, for instance — you get a 200
with the same JSON instead, freshly generated. So you never have to handle a 404.
Your token is in the platform portal at https://verhuren.nl/platform/feeds. You
can replace it there too; the old token stops working immediately.
A feed is always for one platform. If you run several platforms, you fetch a feed per platform; a listing only appears in the feed of the platforms the provider ticked for it.
| Variant | URL | Contents |
|---|---|---|
| Providers | /feed/v1/<platform-slug>/providers |
Every provider with at least one listing for this platform |
| All | /feed/v1/<platform-slug>/all |
Every listing for this platform |
| One provider | /feed/v1/<platform-slug>/provider/<organisation_id> |
Every listing of that provider for this platform |
The providers feed carries the URL of each provider's listings feed
(properties_url), so you never have to assemble URLs yourself.
| Code | Meaning |
|---|---|
302 |
All good; follow the Location to the file on the CDN |
200 |
All good; the file did not exist yet and the feed is in the body |
401 |
No token, or an unknown one |
403 |
Token does not belong to this platform, or your platform account has not been approved |
404 |
Unknown platform or unknown provider |
Errors are JSON: {"error": "..."}, in English.
Every feed, whatever the variant, has the same outside:
{
"feed_version": 1,
"platform": "kamer-nl",
"generated_at": "2026-09-05T10:35:00.123456+00:00",
"count": 2,
"items": [ ... ]
}
| Field | Type | Meaning |
|---|---|---|
feed_version |
int | Always 1 in this version |
platform |
string | The slug of the platform this feed is for |
generated_at |
string | ISO 8601, moment of generation (UTC) |
count |
int | Number of elements in items |
items |
array | The providers or the listings, see below |
providers)A provider is an organisation: an agency, a student house or a private
landlord. An agency can have several people logging in and posting listings;
to the outside world that is one provider with one id and one reply address.
{
"id": 12,
"name": "Makelaardij Jansen",
"account_type": "agency",
"website": "https://jansen.nl",
"logo_url": "https://media-cdn.inversive.nl/media/abc123.png",
"reply_email": "[email protected]",
"property_count": 7,
"properties_url": "https://verhuren.nl/feed/v1/kamer-nl/provider/12"
}
| Field | Type | Meaning |
|---|---|---|
id |
int | Stable id of the provider (the organisation); use this as your key |
name |
string | Display name: company name, else house name, else person's name |
account_type |
string | private, agency or student_house |
website |
string | May be empty |
logo_url |
string | May be empty |
reply_email |
string | Address of this provider for replies without a listing, see Replies |
property_count |
int | Number of listings of this provider for this platform |
properties_url |
string | This provider's listings feed |
all and provider/<organisation_id>)A listing record is the approved snapshot of the property, plus four fields. The snapshot is what our editors checked: if a provider edits their listing, the old version stays in the feed until the change has been approved. So you never receive unchecked content.
{
"snapshot_version": 1,
"taken_at": "2026-09-04T15:30:00+00:00",
"id": 812,
"organisation_id": 12,
"user_id": 34,
"type": "apartment",
"street": "Peizerweg",
"house_number": "97",
"house_number_addition": "A",
"postal_code": "9727AH",
"address_line": "Peizerweg 97-A",
"place": "Groningen",
"place_id": 41,
"municipality": "Groningen",
"rental_price": "1250.00",
"surface": "62.00",
"rooms": 3,
"descriptions": {"nl": "Licht appartement ...", "en": "Bright apartment ..."},
"descriptions_html": {"nl": "<p><strong>Licht appartement</strong> ...</p>"},
"gps": {"latitude": "53.2091234", "longitude": "6.5498765"},
"images": [
{"id": 8, "url": "https://media-cdn.inversive.nl/media/a.jpg", "number": 1},
{"id": 9, "url": "https://media-cdn.inversive.nl/media/b.jpg", "number": 2}
],
"created": "2026-09-01T09:00:00+00:00",
"updated": "2026-09-04T15:30:00+00:00",
"reply_email": "[email protected]",
"platforms": ["kamer-nl", "huizenvinder-nl", "rent-nl"],
"detail_url": "https://verhuren.nl/mijn-omgeving/objecten/812"
}
| Field | Type | Meaning |
|---|---|---|
snapshot_version |
int | Version of the snapshot format, currently 1 |
taken_at |
string | When the snapshot was taken (= moment of approval) |
id |
int | Stable id of the listing; use this as your key |
organisation_id |
int/null | Id of the provider, matches id in the providers feed |
user_id |
int/null | Deprecated. Id of the person who entered the listing. Use organisation_id as the key to the provider |
type |
string | room, studio, apartment, house or anti_squat; empty string if we do not have a type |
street, house_number, house_number_addition, postal_code |
string | Address parts; the addition may be empty |
address_line |
string | The address as one line, the way we show it |
place |
string | Town or city name |
place_id |
int/null | Our id for the place, stable |
municipality |
string/null | Municipality, null if the place has none |
rental_price |
string/null | Monthly rent, two decimals as a string (exact decimal) |
surface |
string/null | Surface in m², two decimals as a string |
rooms |
int/null | Number of rooms; null for a single room |
descriptions |
object | Description per language code (nl, en, ...) as plain text; may be empty |
descriptions_html |
object | The same descriptions as safe HTML, same language codes; may be empty |
gps |
object/null | latitude and longitude as strings, or null |
images |
array | Photos in display order; the first one is the main photo |
images[].id |
int | Stable id of the photo |
images[].url |
string | Direct URL to the image |
images[].number |
int | Sequence number within this listing |
created, updated |
string | ISO 8601 |
reply_email |
string | Address of this listing for replies; use this one, see Replies |
platforms |
array | Slugs of every platform this listing appears on |
detail_url |
string | Listing page on verhuren.nl |
detail_url is provisional. It points at the listing detail inside the
provider's own environment, which requires a login; a public listing page on
verhuren.nl does not exist yet. Do not link to it from your site for now. As soon
as the public page exists, the same field will point there — the field will not
disappear or be renamed.
Prices and surfaces are strings, not numbers: that keeps the decimal value exact and loses nothing to a float.
descriptions is keyed by language code. The description text itself is whatever
the provider wrote, usually Dutch; en is present when an English translation
exists.
Providers may apply light formatting to a description: bold and italic, and
paragraphs. Nothing else — no links, no headings, no HTML. We store what they
type as plain text with markers (**bold**, _italic_) and hand you both forms,
keyed by the same language codes:
descriptions is the plain text with the markers removed, line breaks kept.
Use it if you render the description in your own template or need it for
search, and you will never see a stray asterisk on your page.descriptions_html is the same text as HTML, containing only <p>, <strong>,
<em> and <br>. Everything the provider typed is HTML-escaped before the
formatting is applied, so this value is safe to insert into your page as-is.
Use it if you want to keep the formatting.Both keys are always present. descriptions_html was added in a minor update to
version 1; per the versioning policy below, adding a field is not a breaking
change.
reply_email is the address replies from candidates may go to. Send a reply to
that address and the provider sees it in their inbox on Verhuren.nl.
The address differs per record type, and that is deliberate:
| Record | reply_email |
Where the reply lands |
|---|---|---|
| Listing | [email protected] |
With this listing in the provider's inbox |
| Provider | [email protected] |
In the provider's inbox, without a listing |
The listing address is a slug of street and house number with four hex characters
appended, so two listings at the same address do not collide. Listings created
before September 2026 had the form [email protected]; those addresses keep
working, so a stored feed does not need refreshing. A listing's address never
changes, not even when the provider corrects the address of the property.
Use the address from the listing record. That is the whole point: every listing has its own address, so a reply reaches the right listing without you having to pass a listing number. The provider address is meant for questions that are not about one listing.
In practice:
To; we read the sender of the mail as the candidate. If
your platform sends on behalf of the candidate (the sender is your own domain),
put the candidate's address in Reply-To — we look there too.Automatic replies (out-of-office notices, bounces) are ignored when they carry
Auto-Submitted or Precedence: bulk headers, so do send those headers if you
mail automatically yourself.
The feed contains only listings that:
If a provider edits a listing that is already live, it simply stays in your feed with the last approved content, including while the change is with our editors. You see the new content as soon as it is approved; the listing does not blink out of the feed in the meantime.
So a listing that disappears from your feed has been withdrawn, set to inactive, or the provider unticked your platform. Treat disappearing as "take offline".
The same holds for a provider: if they have nothing left for your platform, they
are no longer in the providers feed and their listings feed disappears. That URL
then returns an empty feed. So always walk the providers feed rather than working
through stored properties_url addresses.
There is no separate "deleted" list; the feed is a complete snapshot of what
should be live right now.
The version number is in the URL (/feed/v1/...) and in the envelope
(feed_version).
Within v1 this may happen, without announcement:
So build your integration to ignore unknown fields and not to crash on an unknown
type.
This never happens within v1:
That would be v2, on a new URL (/feed/v2/...). v1 keeps existing and working
in that case; we tell you well in advance for how long. You can migrate at your
own pace.
The feed used to have Dutch paths, file names and values. It is now English throughout:
| Was | Is now |
|---|---|
/feed/v1/<platform>/aanbieders |
/feed/v1/<platform>/providers |
/feed/v1/<platform>/alles |
/feed/v1/<platform>/all |
/feed/v1/<platform>/aanbieder/<id> |
/feed/v1/<platform>/provider/<id> |
type: kamer, studio, appartement, huurwoning, antikraak |
room, studio, apartment, house, anti_squat |
account_type: particulier, makelaar, studentenhuis |
private, agency, student_house |
The old paths are gone and return 404; the old files have been removed from the
CDN. Field names did not change. This was possible without a v2 because no
external platform was live on v1 yet.
A provider used to be one user account. Now that an agency can work with several people in one account, the provider is the organisation. For your integration that means:
id in the providers feed and <id> in /feed/v1/<platform>/provider/<id> are
the id of the organisation.organisation_id. Key on that to find the
provider.user_id in a listing record still exists but points at the person who entered
the listing. That may be an employee, so it is not a provider key any more. Do
not use it to link records.id; a provider's reply_email did not change
and can help you recognise them.all for a full synchronisation and the provider feeds
if you prefer to work per provider. If all gets too big for you, let us know
and we will split it.Alles geregeld vanuit één platform