2dehands API: zoekertjes van 2dehands.be met prijs en prijstype in JSON
Wie de zoekertjes van 2dehands.be in een eigen toepassing wil gebruiken, vindt bij 2dehands zelf geen API om ze uit te lezen. Deze API geeft je wat een bezoeker zonder account te zien krijgt: titel, prijs en het soort prijs, gemeente, ophalen of verzenden, beschrijving en foto's, als JSON. Er wordt niets geplaatst, verlengd of bovenaan gezet: wie als particulier of handelaar zijn eigen zoekertjes wil beheren, zit hier verkeerd. Standaard lees je de Nederlandstalige site (`"site": "be_nl"`); met `"site": "be_fr"` krijg je dezelfde Belgische markt via 2ememain.be, in het Frans.
Endpoints
| endpoint | Wat je terugkrijgt | Verplicht |
|---|---|---|
| search | Zoekertjes op trefwoord: titel, begin van de beschrijving, prijs in euro met `price_type`, gemeente met coördinaten, de datum zoals de site hem toont, ophalen of verzenden en de kenmerken uit het zoekresultaat (staat, elektrisch…). 30 per pagina; alleen pagina 1 en 2 zijn opvraagbaar. | query |
| listing | Het volledige zoekertje op `item_id` uit search (gewone m-nummers en a-nummers van gepromote zoekertjes) of op de publieke URL: volledige beschrijving, alle foto's, categorie, verkopersnaam en -type zoals publiek getoond, aantal keer bekeken en bewaard, en sinds wanneer het zoekertje online staat. | allemaal optioneel |
Elke aanroep kost credits. Mislukte en geblokkeerde aanroepen zijn gratis.
Werkend voorbeeld
Bij een bakfiets is het bedrag vaak geen vraagprijs. Van de 30 zoekertjes voor 'bakfiets' hadden er 13 `MIN_BID`: het bedrag is de prijs vanaf waar de verkoper biedingen aanvaardt. Bij 5 stond `FAST_BID` (bieden, zonder bedrag) en is `price` null, één was gratis (`FREE`, prijs 0). Van de 11 met een vaste prijs waren er 6 a-nummers, gepromote zoekertjes tussen 4.000 en 6.500 euro. Een gemiddelde over alle 30 rijen gooit dus vraagprijzen, startbedragen voor biedingen en prijzen van handelaars op één hoop.
curl -X POST https://api.reefapi.com/2dehands/v1/search \
-H "x-api-key: JOUW_SLEUTEL" \
-H "content-type: application/json" \
-d '{"query": "bakfiets", "site": "be_nl"}'{
"ok": true,
"data": {
"listings": [
...
{
"item_id": "m2455428526",
"site": "be_nl",
"title": "Gazelle Makki Load 500wH",
"description": "4 jaar oud met slechts 2610 km op de teller! Deze luxe gazelle makki load in de kleur matt black is voorzien van: enviolo cargo manual traploos versnellingssysteem lederen handvatten walk assist funct",
"url": "https://www.2dehands.be/v/fietsen-en-brommers/fietsen-bakfietsen/m2455428526-gazelle-makki-load-500wh",
"category_id": 446,
"attributes": [{ "key": "condition", "value": "Gebruikt" }, { "key": "delivery", "value": "Ophalen" }],
"location": { "city": "Wachtebeke", "country": "België", "country_code": null, "latitude": 51.180404528678, "longitude": 3.8732699309019 },
"date": "Vandaag",
"reserved": false,
"seller": { ... },
"gtin": null,
"price": 3550.0,
"price_cents": 355000,
"price_type": "MIN_BID",
"currency": "EUR"
},
...
{
"item_id": "a167965763",
"title": "Urban Arrow Familynext 545 Wh",
"attributes": [{ "key": "condition", "value": "Zo goed als nieuw" }],
"location": { "city": "Hasselt", "country": null, "country_code": "", "latitude": 50.92703628540039, "longitude": 5.3438310623168945 },
"date": "15 sep 26",
"price": 4000.0,
"price_type": "FIXED",
"currency": "EUR"
},
{
"item_id": "m2440285877",
"title": "Urban arrow bakfiets",
"location": { "city": "Hoeilaart", "country": "België", ... },
"date": "11 sep 26",
"price": null,
"price_cents": null,
"price_type": "FAST_BID",
"currency": "EUR"
},
...
{
"item_id": "m2457856500",
"title": "stecco mee, oud model. voor in bakfiets gebruik",
"location": { "city": "Antwerpen", "country": "België", ... },
"date": "Vandaag",
"price": 0.0,
"price_type": "FREE",
"currency": "EUR"
},
...
],
"total": 1294,
"site": "be_nl",
"offset": 0,
"limit": 30,
"page": 1,
"has_more": true,
"next_offset": 30,
"source_has_more": true,
"paging_limit_reached": false,
"source_page_records": 30
},
"meta": { "record_count": 30, "upstream_requests": 1, "cache_hit": false, "mode": "live" }
}Zelf een 2dehands-scraper bouwen: let op deze velden
De beschrijving in de gestructureerde data van de pagina (JSON-LD) is ingekort. Wie die overneemt, mist het einde van elk langer zoekertje. De volledige tekst staat alleen in het zichtbare blok op de detailpagina, en daar haalt listing hem vandaan: bij de Gazelle-bakfiets uit Wachtebeke 995 tekens, tegenover 200 in de zoekresultaten.
Diezelfde gestructureerde data vermeldt bij Belgische zoekertjes NL als leveringsland. Een parser die het land daaruit haalt, zet Belgische fietsen in Nederland. De gemeente komt hier uit de gegevens van het zoekertje en de verkoper zelf.
Gepromote zoekertjes hebben een a-nummer in plaats van een m-nummer, en het opzoeken op nummer bij 2dehands vindt ze niet. In een testronde tijdens de bouw van de engine lukte daardoor maar 3 van de 6 detailopvragingen; een deel van die a-nummers verwees bovendien door via een categorie die niet meer bestaat. Beide fouten zijn verholpen, en in de eindmeting gaven 12 van de 12 opvragingen het juiste zoekertje.
Neem tot slot de datum uit de zoekresultaten niet over als plaatsingsdatum. Bij de bakfiets uit Wachtebeke stond in de resultaten 'Vandaag', terwijl het zoekertje volgens de detailpagina sinds 19 oktober online stond; bij een gepromoot zoekertje toonden de resultaten '15 sep 26' en de detailpagina 22 oktober. Zet je eigen tijdstempel bij elke meting.
Grenzen en eerlijke kanttekeningen
- Geen officiële 2dehands-koppeling: 2dehands heeft er niet aan meegewerkt, en er bestaat tussen ons geen partnerschap.
- Alleen de eerste twee pagina's (60 zoekertjes) zijn opvraagbaar; `page: 3` geeft INVALID_PARAM. Voor 'bakfiets' meldde 2dehands op 25 oktober 1.294 resultaten, de rest bereik je dus alleen met een specifiekere zoekterm.
- Filters op prijs, categorie, gemeente of sortering zijn er niet: je zoekt enkel op trefwoord. Ook het aanbod van één verkoper opvragen kan niet.
- `date` in search is tekst zoals de site hem toont ('Vandaag', 'Eergisteren', '20 okt 26'), geen tijdstempel. `stats.since` in listing is wel een tijdstempel, maar viel bij geen van onze twee gecontroleerde zoekertjes samen met de datum in de zoekresultaten.
- Coördinaten zijn niet altijd bruikbaar: 2 van de 30 rijen hadden latitude en longitude 0, één daarvan zonder gemeente. Bij de gepromote a-zoekertjes is `country` leeg.
- Een EAN of GTIN publiceert 2dehands in de praktijk niet: `gtin` was null in alle 30 zoekresultaten.
- 'Gezocht'-zoekertjes, van iemand die iets zoekt, staan gewoon tussen het aanbod. Bij 'bakfiets' was er één, met `FAST_BID` en zonder prijs.
- Verkopersnaam en profiel komen terug zoals ze publiek op het zoekertje staan, ook bij particulieren; contactgegevens achter een login niet. In het voorbeeld hebben we de verkopersgegevens weggelaten.