Every second-hand copy in the Low Countries, as one JSON API
The Boekwinkeltjes API returns the Dutch and Belgian second-hand and antiquarian book market as clean JSON, in three actions: search, book and seller.
3 active endpoints, on 1 and 2 credit tiers.
- POST/boekwinkeltjes/v1/search
- POST/boekwinkeltjes/v1/book
- POST/boekwinkeltjes/v1/seller
What Boekwinkeltjes endpoints does ReefAPI ship?
3 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Boekwinkeltjes API
3 of 3 endpoints, ready to run
Every copy on offer for a title, an author, a publisher or an ISBN: copy id and URL, title, author, publisher, the seller's own particulars text, price as a number and as the site printed it, shipping and the shop name.
// Press "Try it" and this pane shows exactly what the // live site returned this second — including an empty // result, if that is the truth. No key, no account.
How the Boekwinkeltjes API works
Boekwinkeltjes is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 438 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
ISBN to every copy, cheapest first, then the shop behind it
The step people get wrong is expecting an ISBN on a search row. There is none — the source's result table has no ISBN column. Search BY the ISBN instead, then resolve the copies you care about.
{"query": "9789027401700", "sort": "price", "order": "asc", "with_total": true}Every copy of that exact edition on offer, cheapest first, with the total. Two copies of this one sat at EUR 5.30 and EUR 27.50 on the same page — same ISBN, different shops.
{"book_id": "244766468"}The cheap copy in full: ISBN 9789027401700, the seller's particulars text, the price with the string the site printed, shipping, the photos, and the shop with its town and delivery terms.
{"seller": "kaatjesboeken"}That shop's own page: its published stock total — 9,798 books — its town, whether it is a business or a private seller, and 50 of its copies in the same schema as search.
{"query": "tolkien", "zip": "1012", "distance_km": "10", "with_total": true}Or go local instead: only sellers within 10 km of Amsterdam 1012 — 72 copies against 2,429 nationally, so you can see the filter bite.
An exact edition, every copy of it on the market with its real price spread, one copy in full, and the shop you would be buying from — four calls against one schema.
curl -X POST https://api.reefapi.com/boekwinkeltjes/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"tolkien"}'{
"ok": true,
"data": { … },
"meta": {
"api": "boekwinkeltjes",
"endpoint": "search",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}Where the fields live — search row versus book page, measured 2026-10-01
Boekwinkeltjes is a marketplace of independent sellers, so a field is filled when the seller filled it. These are counts over 250 distinct copies drawn from three different queries plus one shop page, and 12 book pages. The ISBN line is the one to read first.
| field | on a search row | on a book page | what it is |
|---|---|---|---|
| ISBN | 0 of 250 — not published | 11 of 12 | The source's result table has no ISBN column at all. Searching BY an ISBN works; reading one OFF a row does not. Call book for it. |
| price | 250 of 250 | 12 of 12 | Both the parsed euro amount and the exact string the site printed, side by side, so you can see the number we read. |
| title | 250 of 250 | 12 of 12 | The seller's own title line. |
| author | 234 of 250 | 12 of 12 | Some copies list no author; those come back null, not an empty string. |
| publisher | 238 of 250 | 12 of 12 | Often carries the year too, because sellers type it there. |
| particulars | 194 of 250 | 11 of 12 | The seller's free text: year, edition, binding, page count, defects. Boekwinkeltjes has no separate fields for any of those. |
| shop name | 165 of 208 marketplace rows | 12 of 12 | On partner rows the shop cell is a button rather than a name, so the row returns null and book returns the real seller. |
| shipping | 148 of 250 | 9 of 12 | Printed only when the seller set one. 'Gratis' comes back as 0, not as null. |
| photo | 129 of 250 | 6 of 12 | The site's own placeholder image is returned as null rather than as a URL. |
| condition (new / used) | not on the row | 12 of 12 | The book page publishes its own new-or-used flag. The row does not, so it is null there. |
| condition text, binding | 34 and 26 of 250 | only where labelled | Filled only where the seller literally wrote 'Conditie:' or 'Bindwijze:'. Never inferred from prose. |
| language | not on the row | 7 of 12 | Both the site's own label and a language code, on the book page only. |
| seller town, business-or-private, delivery terms | not on the row | 11, 12 and 8 of 12 | The shop block: name, town, business or private, slug, website, handling days, terms. |
Paging is 50 copies per page and that was constant on all 12 pages sampled. The source's own ceiling is page 200, so at most 10,000 copies are reachable per query however many exist — past that it answers 404 and the API tells you so instead of looping. Boekwinkeltjes publishes no result count anywhere, so total_estimate is opt-in and computed from its own last-page link plus the rows on that page; q=tolkien measured 2,429 copies. There are no seller ratings, no review counts and no sales counts on these pages, and no stock quantity, because one listing is one copy.
What Boekwinkeltjes publishes, what it does not, and what we measured
Measured on 2026-10-01 against the live site: 40 of 40 checks behaved as expected, all 11 exposed filters narrowed the catalogue in the same run, field fill was counted over 250 distinct copies drawn from three queries plus a shop page, and 12 books were compared against their own pages twice over. Six of these lines go against us.
Boekwinkeltjes indexes the stock of 11,264 independent Dutch and Belgian bookshops and private sellers, and every result row is one physical copy from one seller at one price. On a single live page, book 219742668 and book 244766468 both carried ISBN 9789027401700 — the same edition — at EUR 27.50 and EUR 5.30 from two different shops. A query for q=tolkien reached 2,429 copies. If you want an averaged catalogue price this is the wrong source; if you want the real spread across the shelves, this is the only one that has it.
The result table has seven columns — image, author, title, publisher, particulars, price, shop — and no ISBN cell, so isbn comes back null on all 250 rows we counted. On book pages it was present on 11 of 12. Searching by an ISBN does work: 9789022537510 returned 7 copies. ISBN-10 and ISBN-13 are kept in separate fields by the length the source printed and neither is ever derived from the other; on the books we sampled only ISBN-13 forms were published, so isbn10 was null on all 12.
The book page prints its price in its own table and again in its own structured data. Both were compared against the search row's printed price on 12 books, on two separate runs: 12 of 12 agreed, 0 disagreed. We return the site's own string beside the parsed number — '€ 27,50 (Excl. verzendkosten)' next to 27.5 — and if the two witnesses ever diverge the response flags it instead of choosing silently. The currency comes from the page's own structured data (EUR) and is never inferred from the country.
Boekwinkeltjes has no structured year, edition, page-count or binding field. Sellers type all of it into one field we return verbatim as particulars — '2024 256pp Gebonden', 'paperback, 1975, eerste druk, 201p., 20,5 x 13,5 cm' — present on 194 of 250 rows and 11 of 12 book pages. condition and binding are filled only where the seller literally wrote 'Conditie:' or 'Bindwijze:', which was 34 and 26 of 250 rows. Nothing is parsed out of prose and presented as a field. The book page does publish its own new-or-used flag, and that was present on 12 of 12.
On a book page: shop name, town, business or private as Boekwinkeltjes itself classifies it, slug, its own website where it has one, logo, the working days it states for getting back to you, and its delivery terms in its own words. Counted over 12 books: name 12 of 12, business-or-private 12 of 12, slug 12 of 12, handling days 12 of 12, town 11 of 12, logo 9 of 12, terms 8 of 12. On search rows the shop name is on 165 of the 208 marketplace rows. There are no seller ratings, review counts or sales totals anywhere on these pages, so those are absent rather than empty, and there is no stock quantity because one listing is one copy.
Boekwinkeltjes mixes stock from a commercial partner into the result grid, at the top of the page. We measured 42 of 250 rows, about one in six. Those rows carry a button image instead of a shop name, so seller_name is null on them and listing_channel reads partner_boekenbalie; every search reports how many of your rows were partner rows. They are kept, not dropped: their ids resolve to a full record where the seller IS published. A row that carries no resolvable copy id at all is dropped and counted — zero of 250 on this sample.
50 copies per page, constant on all 12 pages sampled across two queries. Page 200 returns 50 copies; page 201 returns nothing, which is the source's own ceiling. So at most 10,000 copies are reachable per query however large the total. A page above 200 is rejected with the reason rather than left for you to discover, and the response says when you have reached the wall. Split by language, seller country, price band or postcode radius to go deeper.
The site prints page links and never a result count. total_estimate is therefore derived the only honest way — from the source's own last page plus the rows on that page — and only when you ask for it, because it costs an extra read. q=tolkien measured 2,429 copies that way. Every filtered total in this page's numbers was measured against that same 2,429 in the same run.
We checked: an invented query parameter returned HTTP 200 and all 2,429 unfiltered copies, and an unknown sort value returned 200 with a silently different order. So every enum is validated on our side — language, seller country, condition, sort, direction and the distance steps — and a value the source does not have comes back as a parameter error with the allowed list, never as a filter that quietly did nothing.
A query that genuinely matches nothing returns ok with zero copies and a stop reason of 'empty', because an empty answer is an answer. A dead copy id and a shop slug that does not exist both return NOT_FOUND, non-retryable, and are not retried. A page past the ceiling is a parameter error. Across 320 live calls in eight consecutive runs the source never refused us once, and the only failures were 4 transport timeouts on our side, which are reported as retryable rather than blamed on the site.
What people build with Boekwinkeltjes
The jobs this data is most often used for.
endpoints
credits per call
Price a second-hand book properly: search its ISBN, get every copy currently on offer across 11,264 Dutch and Belgian sellers, and read the real spread — in one measured case the same edition sat at EUR 27.50 and EUR 5.30 on the same result page.
Feed a book-finding or wishlist service: run saved title and author queries with added_last_week, and surface the copies that appeared in the last seven days — 103 of 2,429 on the day this was measured.
Source stock for a reseller or a dealer: filter by price band, by book language across 56 codes, by seller country, or within a radius of a postcode, then pull each copy in full with its condition text and the shop's delivery terms before you buy.
Build a local-pickup search: pass a Dutch or Belgian postcode with a radius and get only sellers in range — 72 copies within 10 km of Amsterdam 1012 against 2,429 nationally — with each shop's town on the record.
What Boekwinkeltjes data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 438 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/boekwinkeltjes/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"tolkien"}'import requests
r = requests.post(
"https://api.reefapi.com/boekwinkeltjes/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "tolkien"
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Boekwinkeltjes.
Get a free key →Do I get the ISBN?▾
On the book page, yes, and exactly as the seller printed it: 11 of the 12 books we audited carried one. On a search row, no — and we would rather say so than invent it. Boekwinkeltjes' result table has seven columns (image, author, title, publisher, particulars, price, shop) and no ISBN cell, so isbn is null on all 250 rows we counted. The useful direction still works: pass an ISBN as query and the site matches on it — 9789022537510 returned 7 copies — then call book on the ids you care about. ISBN-10 and ISBN-13 are returned in separate fields by the length the source printed, and neither is ever converted into the other, because a computed check digit would be our number and not the seller's.
Is one row a book, or a copy?▾
A copy. That is the whole point of this source. Every row is one physical copy, in one shop, at one price. In a single live result page, book 219742668 and book 244766468 both carry ISBN 9789027401700 — the same edition — at EUR 27.50 and EUR 5.30 from two different sellers. So a title query returns as many rows as there are copies on shelves across the market, and total_estimate counts copies. If you want the cheapest copy of an edition, search its ISBN and sort by price.
Where do the publication year, the edition and the binding live?▾
In one free-text field the site calls Bijzonderheden, which we return verbatim as particulars — for example '2024 256pp Gebonden' or 'paperback, 1975, eerste druk, 201p., 20,5 x 13,5 cm'. Boekwinkeltjes has no structured year, edition, page-count or binding field, so we do not pretend to have one: condition and binding are filled only on rows where the seller literally wrote 'Conditie:' or 'Bindwijze:', which was 34 and 26 of 250 rows. Everything else stays in the text, where you can read it, rather than being guessed out of prose and shipped as if it were a field.
Can I trust the price?▾
It is checked against the source twice. The book page prints its price in its own detail table and again in its own structured data, and we compare both against the price on the search row. On 12 books that was 12 out of 12 agreement with zero mismatches, on two separate runs. We also return the site's own printed string next to the parsed number — '€ 27,50 (Excl. verzendkosten)' beside 27.5 — so you can always see what we read, and if the two witnesses ever disagree the response says so instead of silently picking one. Dutch notation is handled explicitly, which matters: a comma is the decimal separator here, so a careless reader turns 627,30 into 627300.
Do I get the seller?▾
Yes, and in full on the book page: shop name, the town it sits in, whether Boekwinkeltjes classes it as a business or a private seller, its slug, its own website where it has one, its logo, how many working days it says it needs to get back to you, and its delivery terms in its own words. On the 12 books we audited, name and business-or-private were present 12 of 12, town 11 of 12, terms 8 of 12. On search rows the shop name is there on 165 of the 208 marketplace rows. There are no seller ratings, review counts or sales totals on this marketplace — not hidden, simply not published — so those fields do not exist rather than coming back empty.
What are the partner rows and why do you keep them?▾
Boekwinkeltjes mixes in stock from a commercial partner, and those rows sit at the top of result pages. We measured 42 of 250 rows, about one in six. Their shop cell is a button image instead of a shop name, so seller_name comes back null on them and listing_channel says partner_boekenbalie, and every search reports how many of your rows were partner rows. We keep them because they are real books with real ids that resolve to a full record — where the seller IS published — and dropping a sixth of the market without telling you would be worse than labelling it.
How do I know a filter actually did something?▾
Ask for total_estimate and compare. We did, in a single run against an unfiltered 2,429 copies for q=tolkien: second-hand only 1,983, new only 446 (and 1,983 + 446 is exactly 2,429, so those are the two complete halves), books in English 801, in German 61, sellers in Belgium 470, sellers in the Netherlands 2,393, at least EUR 50 gives 183, at most EUR 5 gives 376, only with a photo 1,652, only listings that charge shipping 1,606, added in the last week 103, and within 10 km of postcode 1012 just 72 — against 1,673 within 150 km. All 11 exposed filters narrowed the set. This matters more than usual here, because the site itself accepts a parameter it has never heard of and returns the full unfiltered result with a 200: we checked, and an invented filter left all 2,429 in place. So every value you pass is validated on our side and a typo is rejected with the allowed list, rather than quietly doing nothing.
Is 'only with shipping costs' the same as free shipping?▾
No, and it is the opposite, which is why we renamed it. The site's own switch reads 'show only listings with shipping costs', so our parameter is shipping_cost_listed: it keeps the copies that DO charge for postage. On q=tolkien that is 1,606 of 2,429. If you want the free ones, read shipping_eur on the rows: 'Gratis' is returned as 0, a real amount as that amount, and a copy where the seller printed nothing as null.
How deep can I page?▾
50 copies per page, and that was constant on every one of the 12 pages we sampled. The site's own ceiling is page 200 — page 200 returns 50 copies, page 201 returns nothing at all — so a query can reach 10,000 copies at most, whatever its total is. The API rejects a page above 200 with the reason instead of letting you discover it, and tells you in the response when you have hit the wall. To go deeper than 10,000, split the query: by language, by seller country, by price band or by postcode radius, all of which are filters here.
What happens if nothing matches, or if a copy has been sold?▾
A query that matches nothing is an answer, not an error: you get ok with zero books and a stop reason of 'empty'. A copy that no longer exists is different — a dead book id returns NOT_FOUND, non-retryable, as does a shop slug that does not exist. Those are real answers from the source, so the API hands them back as such rather than as a vague failure you have to interpret, and never retries them.
Can I list one bookshop's whole stock?▾
Yes, that is the seller action. Take seller.slug from any book response, pass it in, and you get the shop's profile plus a page of its copies in the same shape as search — and, uniquely on this source, the shop's own published stock total: Kaatjes Boeken states 9,798 books. You can also pass query to search inside that one shop only, and sort by the same keys as search. It is the only count Boekwinkeltjes prints anywhere.
What is the Boekwinkeltjes API?▾
Boekwinkeltjes API is a ReefAPI endpoint group for the dutch and belgian second-hand and antiquarian book market as json: every copy on offer across 11,264 bookshops and private sellers, with isbn, condition text, shipping and the shop behind it. It returns live JSON through POST requests under /boekwinkeltjes/v1.
Is the Boekwinkeltjes API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Boekwinkeltjes calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Boekwinkeltjes login or account?▾
No login to Boekwinkeltjes is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
191 E-commerce & Marketplaces APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Boekwinkeltjes, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 437 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-10-01.