Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Boekwinkeltjes API page →
E-commerce & Marketplaces

Boekwinkeltjes API & Scraper

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 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.

The thing that makes this source different is what one row means: a row is ONE physical copy from ONE seller at ONE price, not a catalogue title. Measured on a single live result page, book 219742668 and book 244766468 both carry ISBN 9789027401700 — the same edition of the same book — at EUR 27.50 from one shop and EUR 5.30 from another. So a title query hands you the whole price spread across the shelves of 11,264 independent sellers instead of one averaged number. search takes a title, an author, a publisher or an ISBN and narrows by second-hand or new, the language of the book across 56 codes, the country the seller ships from (Netherlands, Belgium, France, United Kingdom or rest of world), a minimum and maximum price in euros, a Dutch or Belgian postcode plus a radius, listings that have a photo, listings that charge shipping, and copies added in the last week, sorted by title, author, publisher, particulars text, price, shop name, most recently listed or most recently changed. Each row carries the copy's own id and URL, title, author, publisher, the seller's free-text particulars, the price both as a number and as the string the site itself printed, shipping, the shop name, a photo and whether the row is marketplace stock or partner stock. book adds the ISBN exactly as the seller printed it — ISBN-10 and ISBN-13 are kept apart and neither is ever converted into the other — plus the language, the source's own new-or-used flag, the currency, every photo, the full description, and the SELLER: shop name, town, business or private, its slug, its own website, how many working days it takes to get back to you, and its delivery terms. seller opens one shop's own page: its profile, the total number of books it publishes about itself, and a page of its stock in the same shape as search. Verified on 2026-10-01: 40 of 40 live checks behaved as expected, all 11 exposed filters measurably narrowed the catalogue in the same run, and on 12 books the price we return matched the book page's own printed price AND the page's own structured data 12 times out of 12, with zero mismatches. No Boekwinkeltjes account and no API key on their side — one ReefAPI key and the standard { ok, data, meta, error } envelope.

Reference

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.

fieldon a search rowon a book pagewhat it is
ISBN0 of 250 — not published11 of 12The 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.
price250 of 25012 of 12Both the parsed euro amount and the exact string the site printed, side by side, so you can see the number we read.
title250 of 25012 of 12The seller's own title line.
author234 of 25012 of 12Some copies list no author; those come back null, not an empty string.
publisher238 of 25012 of 12Often carries the year too, because sellers type it there.
particulars194 of 25011 of 12The seller's free text: year, edition, binding, page count, defects. Boekwinkeltjes has no separate fields for any of those.
shop name165 of 208 marketplace rows12 of 12On partner rows the shop cell is a button rather than a name, so the row returns null and book returns the real seller.
shipping148 of 2509 of 12Printed only when the seller set one. 'Gratis' comes back as 0, not as null.
photo129 of 2506 of 12The site's own placeholder image is returned as null rather than as a URL.
condition (new / used)not on the row12 of 12The book page publishes its own new-or-used flag. The row does not, so it is null there.
condition text, binding34 and 26 of 250only where labelledFilled only where the seller literally wrote 'Conditie:' or 'Bindwijze:'. Never inferred from prose.
languagenot on the row7 of 12Both the site's own label and a language code, on the book page only.
seller town, business-or-private, delivery termsnot on the row11, 12 and 8 of 12The 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.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/boekwinkeltjes/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "tolkien"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "boekwinkeltjes",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1183.8,
    "record_count": 50,
    "bytes": 111315,
    "cache_hit": false,
    "stop_reason": "more_pages",
    "upstream_requests": 1,
    "partner_rows": 9,
    "rows_without_id": 0,
    "charged_credits": 1,
    "version": "1.0.0",
    "request_id": "96eeca561e774e8c"
  },
  "data": {
    "query": "tolkien",
    "page": 1,
    "rows_per_page": 50,
    "returned": 50,
    "pages_estimate": 49,
    "page_ceiling": 200,
    "total_estimate": null,
    "filters_applied": {},
    "books": [
      {
        "book_id": "244885503",
        "url": "https://www.boekwinkeltjes.nl/b/244885503/2-De-twee-torens-filmeditie/",
        "title": "2 De twee torens filmeditie 3",
        "author": "Tolkien, J.R.R.",
        "publisher": "Mynx",
        "particulars": null,
        "condition": null,
        "binding": null,
        "price_display": "€ 13,00",
        "price_eur": 13,
        "shipping_display": "€ 2,99",
        "shipping_eur": 2.99,
        "seller_name": "Kaatjes Boeken",
        "image_url": null,
        "isbn": null,
        "listing_channel": "marketplace"
      },
      {
        "book_id": "236069652",
        "url": "https://www.boekwinkeltjes.nl/b/236069652/2-De-twee-torens-TTfilmed/",
        "title": "2 De twee torens TT-filmed",
        "author": "Tolkien, J.R.R.",
        "publisher": "Mynx",
        "particulars": "Goed",
        "condition": null,
        "binding": null,
        "price_display": "€ 5,49",
        "price_eur": 5.49,
        "shipping_display": null,
        "shipping_eur": null,
        "seller_name": "bookshop boekerietje",
        "image_url": null,
        "isbn": null,
        "listing_channel": "marketplace"
      },
      {
        "book_id": "219742475",
        "url": "https://www.boekwinkeltjes.nl/b/219742475/2-In-de-ban-van/",
        "title": "2 In de ban van de ring",
        "author": "Tolkien, J.R.R.",
        "publisher": "Spectrum, Uitgeverij Het",
        "particulars": "Let op: Deel 1, 2 3 in 1 koop, resp. 22e druk 1979/25e herziene druk 1981/25e herziene druk 1981 Pr...",
        "condition": null,
        "binding": null,
        "price_display": "€ 27,50",
        "price_eur": 27.5,
        "shipping_display": null,
        "shipping_eur": null,
        "seller_name": "Lanceval",
        "image_url": null,
        "isbn": null,
        "listing_channel": "marketplace"
      }
    ]
  }
}
Actions

What the Boekwinkeltjes API does

ActionDescriptionConcrete use caseKey params
searchSearch every copy on offer across 11,264 Dutch and Belgian second-hand and antiquarian bookshops and private sellers. ONE ROW IS ONE COPY from ONE seller at ONE price, not a catalogue title: the same ISBN appears once per shelf it sits on, which is what makes the price spread visible. `query` takes a title, an author, a publisher or an ISBN. 🔴 Search rows do NOT carry an ISBN — the source's result table has no ISBN column; call `book` with the row's `book_id` for ISBN, language, condition and the full seller block. 50 copies per page (measured constant on 12 sampled pages); the site's own ceiling is page 200, i.e. at most 10,000 copies per query.Pricing teams call search to search every copy on offer across 11,264 Dutch and Belgian second-hand and antiquarian booksh….query, page, sort, order, condition, ...
bookOne copy in full: ISBN exactly as the seller printed it (ISBN-10 and ISBN-13 kept apart, never converted into each other), title, author, publisher, language, the seller's own free-text `particulars` (year / edition / binding / defects all live there), price with the source's own printed string beside it, shipping, photos, and the SELLER — shop name, town, business-or-private, slug, website, handling time and delivery terms. Accepts a book URL instead of an id. A dead id returns NOT_FOUND.Marketplace operators call book to get one copy in full.book_id
sellerOne shop's own stock page: its profile (name, town, business or private, logo, website, delivery terms) together with the TOTAL NUMBER OF BOOKS it publishes about itself — the only count this source prints anywhere — and a page of its copies in the same shape as `search`. `query` searches inside that one shop. A dead slug returns NOT_FOUND.Catalog enrichment teams call seller to get one shop's own stock page.seller, page, query, sort
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/boekwinkeltjes/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"tolkien"}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.boekwinkeltjes.search with {"query":"tolkien"}.
Use cases

Who uses this API and why

  • 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.
  • Map the Dutch and Belgian antiquarian trade: walk sellers from the copies you find, open each shop with the seller action, and read its published stock count, town, business-or-private classification and delivery terms.
FAQ

Questions developers ask before integrating

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.

docs / boekwinkeltjes

Boekwinkeltjes

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.

base /boekwinkeltjes/v13 endpoints
post/boekwinkeltjes/v1/book1 credit

One copy in full: ISBN exactly as the seller printed it (ISBN-10 and ISBN-13 kept apart, never converted into each other), title, author, publisher, language, the seller's own free-text `particulars` (year / edition / binding / defects all live there), price with the source's own printed string beside it, shipping, photos, and the SELLER — shop name, town, business-or-private, slug, website, handling time and delivery terms. Accepts a book URL instead of an id. A dead id returns NOT_FOUND.

ParameterAllowed / rangeDescription
book_idrequired—Numeric id from a book URL (https://www.boekwinkeltjes.nl/b/244885503/… → 244885503), or the whole URL.
Try in playground →
post/boekwinkeltjes/v1/seller2 credits

One shop's own stock page: its profile (name, town, business or private, logo, website, delivery terms) together with the TOTAL NUMBER OF BOOKS it publishes about itself — the only count this source prints anywhere — and a page of its copies in the same shape as `search`. `query` searches inside that one shop. A dead slug returns NOT_FOUND.

ParameterAllowed / rangeDescription
sellerrequired—Shop slug from a shop URL (https://www.boekwinkeltjes.nl/v/kaatjesboeken/ → kaatjesboeken), or the whole URL. `book` returns it as `seller.slug`.
page = 1optional1–20001-based page of that shop's stock.
queryoptional—Search inside this shop only.
sortoptionaltitle · author · publisher · particulars · price · shop · newest · updatedSort key, same set as `search`.
Try in playground →
Built for volume
5M+ requests a day

Measured at 60 requests a second across the fleet, with no central bottleneck. Volume pricing is on request, and per-key limits are raised for high-volume accounts.

Missing a source?
We build it

Tell us a site we do not cover yet and it becomes an engine. A customer asked for bestprice.gr on a Sunday and it was in the catalog the next day.

Support
2 minute median reply

Median time from a question in the live chat to the first answer, measured across every answered conversation. Setup help included, no support tier to buy.

One key, one balance
Every API included

No per-site plans and no separate subscriptions. One key and one credit pool across the whole catalog, so adding a source costs nothing up front.

Planning something large? Tell us the volume and the sources and we will come back with what it costs and what we would have to build.