{"openapi":"3.1.0","info":{"title":"Boekenbase API","version":"1.8.0","description":"Read-only toegang tot de boekenbase: de catalogus van de Nederlandse\nboekenmarkt (titels, auteurs, NUR, flapteksten, recensies, covers,\nprijzen en beschikbaarheid), dagelijks bijgewerkt.\n\nAlle responses zijn **self-contained**: gecodeerde velden dragen een\n`*_name`-veld met de betekenis, en assets zijn directe publieke URL's —\nje hoeft nooit een tweede call te doen om een antwoord te begrijpen.\n\nAuthenticatie: `Authorization: Bearer bbk_…` of `X-API-Key: bbk_…`.","contact":{"name":"Oncore","url":"https://oncore.ai"}},"servers":[{"url":"https://nhjisqchpvhuelilkoen.supabase.co/functions/v1/api"}],"security":[{"bearer":[]},{"apiKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"API-key als Bearer-token (bbk_live_… / bbk_test_…)"},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"Book":{"type":"object","description":"Volledig boekrecord. Gecodeerde velden hebben een *_name-tegenhanger; contributors/texts/related_products/editions/assets zitten ingesloten.","properties":{"isbn13":{"type":"string","examples":["9789025778750"]},"title":{"type":"string"},"subtitle":{"type":["string","null"]},"series_title":{"type":["string","null"]},"series_number":{"type":["string","null"]},"publisher_name":{"type":["string","null"]},"imprint_name":{"type":["string","null"]},"pub_date":{"type":["string","null"],"format":"date"},"product_form":{"type":["string","null"]},"product_form_name":{"type":["string","null"],"examples":["Hardback"]},"language_code":{"type":["string","null"]},"language_name":{"type":["string","null"]},"nur_main":{"type":["string","null"]},"nur_main_name":{"type":["string","null"],"examples":["Prentenboeken (<6 jaar)"]},"price_eur":{"type":["number","null"],"description":"Adviesprijs incl. btw"},"availability":{"type":["string","null"]},"availability_name":{"type":["string","null"]},"nur_codes":{"type":["array","null"],"items":{"type":"string"},"description":"Nevencodes"},"keywords":{"type":["array","null"],"items":{"type":"string"}},"work_id_nstc":{"type":["string","null"],"description":"Werk-identifier (NSTC): edities van hetzelfde werk delen deze"},"source":{"type":"string","examples":["cb"],"description":"Herkomst van het record. 'cb' = Nederlandse handelscatalogus (met prijs, beschikbaarheid en NUR); andere waarden zijn internationale bronnen waarvoor die velden ontbreken."},"thema_main":{"type":["string","null"],"description":"Thema-hoofdcode (EDItEUR v1.6), waar de bron die levert"},"thema_codes":{"type":["array","null"],"items":{"type":"string"},"description":"Overige Thema-codes"},"updated_at":{"type":"string","format":"date-time","description":"Laatste wijziging van dit record. Bumpt bij elke CB-levering die het productrecord of meegeleverde blokken (contributors, teksten, relaties) raakt; wijzigingen aan alléén assets (bv. een nieuwe cover) bumpen niet."},"contributors":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"role":{"type":"string","examples":["A01"]},"role_name":{"type":["string","null"],"examples":["Auteur"]},"name":{"type":["string","null"]},"key_names":{"type":["string","null"],"description":"Achternaam/sorteersleutel"},"names_before_key":{"type":["string","null"],"description":"Voornamen"},"prefix_to_key":{"type":["string","null"],"description":"Tussenvoegsel"},"corporate_name":{"type":["string","null"]}}}},"texts":{"type":"array","description":"Flapteksten, recensies e.d.","items":{"type":"object","properties":{"seq":{"type":"integer"},"text_type":{"type":"string"},"text_type_name":{"type":["string","null"],"examples":["Flaptekst"]},"text":{"type":"string","description":"Kan HTML bevatten"},"text_author":{"type":["string","null"]},"text_source":{"type":["string","null"]},"content_date":{"type":["string","null"],"format":"date"}}}},"related_products":{"type":"array","items":{"type":"object","properties":{"related_isbn13":{"type":"string"},"relation_code":{"type":"string","description":"ONIX-relatiecode; '05-reverse' = dit boek is de vervanger van related_isbn13"},"relation_name":{"type":["string","null"],"examples":["Vervangt"]}}}},"editions":{"type":"array","description":"Andere edities van hetzelfde werk (NSTC)","items":{"type":"object","properties":{"isbn13":{"type":"string"},"product_form":{"type":["string","null"]},"product_form_name":{"type":["string","null"]},"pub_date":{"type":["string","null"],"format":"date"},"cover_url":{"type":"string"},"cover_urls":{"type":["object","null"],"description":"Front cover in several sizes. `original` is the publisher-supplied JPEG and is always present when the book has a cover; `w176` and `w352` are WebP thumbnails (352 for retina). A handful of source images are corrupt and have no thumbnails — fall back to `original` on a 404.","properties":{"original":{"type":"string"},"w176":{"type":"string"},"w352":{"type":"string"}}}}}},"assets":{"type":"array","description":"Cover/achterkant/inkijk met publieke url","items":{"type":"object","properties":{"kind":{"type":"string","enum":["vrk","atk","dvb"]},"type":{"type":"string","examples":["Cover"]},"url":{"type":"string"},"content_type":{"type":"string"},"bytes":{"type":["integer","null"]}}}}},"additionalProperties":true},"SearchResult":{"type":"object","properties":{"isbn13":{"type":"string"},"title":{"type":"string"},"subtitle":{"type":["string","null"]},"author":{"type":["string","null"]},"series_title":{"type":["string","null"]},"product_form_name":{"type":["string","null"]},"language_name":{"type":["string","null"]},"nur_main_name":{"type":["string","null"]},"pub_date":{"type":["string","null"]},"price_eur":{"type":["number","null"]},"score":{"type":"number","description":"RRF-relevantiescore"},"cover_url":{"type":["string","null"]},"cover_urls":{"type":["object","null"],"description":"Front cover in several sizes. `original` is the publisher-supplied JPEG and is always present when the book has a cover; `w176` and `w352` are WebP thumbnails (352 for retina). A handful of source images are corrupt and have no thumbnails — fall back to `original` on a 404.","properties":{"original":{"type":"string"},"w176":{"type":"string"},"w352":{"type":"string"}}},"detail_url":{"type":"string","description":"Volledig API-record","examples":["https://nhjisqchpvhuelilkoen.supabase.co/functions/v1/api/v1/books/9789025778750"]},"web_url":{"type":"string","description":"Publiekspagina op boekenbase.nl","examples":["https://boekenbase.nl/boek/beloofd-is-beloofd-kleine-panda-s-rachel-bright-9789025778750"]}}}}},"paths":{"/v1/health":{"get":{"summary":"Status","security":[],"responses":{"200":{"description":"API en database bereikbaar"}}}},"/v1/books/{isbn13}":{"get":{"summary":"Eén boek, volledig","parameters":[{"name":"isbn13","in":"path","required":true,"schema":{"type":"string","pattern":"^97[89]\\d{10}$"}}],"responses":{"200":{"description":"Volledig record","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Book"}}}}}},"404":{"description":"Niet in de catalogus (`error.code` = `not_found`). We tellen welke ontbrekende ISBN's worden opgevraagd, maar halen ze niet elders op.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/books":{"get":{"summary":"Batch op ISBN (max 200), optioneel als delta-sync","description":"Zonder `updated_after`: alle gevonden records. Mét `updated_after`: alleen records met `updated_at` **strikt groter dan** de opgegeven timestamp — gebruik `MAX(updated_at)` uit je vorige sync als watermark. Bestaande maar ongewijzigde records tellen in `meta.unchanged`; `meta.missing` betekent onveranderd: niet (meer) in de catalogus. Een verwijderd boek verschijnt dus als `missing`, niet als delete-event. Batchrecords zijn volledig: dezelfde vorm als `/v1/books/{isbn13}`, inclusief contributors, texts, related_products, editions en assets. Met `include=basis` krijg je alleen de boekvelden — sneller en lichter als je alleen prijzen of beschikbaarheid synchroniseert.","parameters":[{"name":"isbns","in":"query","required":true,"schema":{"type":"string"},"description":"Kommagescheiden ISBN-13's","example":"9789025755348,9789025766146"},{"name":"updated_after","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-05T00:00:00Z","description":"ISO 8601-timestamp met timezone. Alleen records met updated_at > deze waarde (strikt groter, ms-precisie). Onparseerbaar → 400."}],"responses":{"200":{"description":"Gevonden records + meta; met updated_after ook meta.unchanged en echo van de parameter","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Book"}},"meta":{"type":"object","properties":{"requested":{"type":"integer"},"found":{"type":"integer","description":"Aantal records in data"},"unchanged":{"type":"integer","description":"Alleen bij updated_after: bestaat, maar niet gewijzigd sinds de timestamp"},"missing":{"type":"array","items":{"type":"string"},"description":"Niet in de catalogus"},"queued":{"type":"array","items":{"type":"string"},"deprecated":true,"description":"Vervallen: altijd leeg. Ontbrekende ISBN's worden niet meer elders opgehaald."},"updated_after":{"type":"string","description":"Alleen bij updated_after: echo van de parameter"}}}}}}}},"400":{"description":"Ontbrekende/ongeldige isbns of onparseerbare updated_after","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/search":{"get":{"summary":"Hybride zoeken (tekst + semantisch)","description":"Zoek met trefwoorden, een auteursnaam, een ISBN of een omschrijving in gewone taal (\"een boek over een uil voor kinderen\"). Combineert full-text, semantische vector-search en auteursmatch via reciprocal rank fusion.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"example":"een boek over een uil voor een 6-jarige"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":50}},{"name":"taal","in":"query","schema":{"type":"string"},"description":"ONIX-taalcode, bv. dut"},{"name":"vorm","in":"query","schema":{"type":"string"},"description":"ONIX-productvorm, bv. BB (hardback), ED (e-book), AJ (audio)"},{"name":"nur","in":"query","schema":{"type":"string"},"description":"NUR-code (hoofd of nevencode)"}],"responses":{"200":{"description":"Resultaten gesorteerd op relevantie; meta.semantic geeft aan of het vector-been meedeed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}},"meta":{"type":"object"}}}}}}}}},"/v1/changes":{"get":{"summary":"Catalogus-brede delta: alles gewijzigd sinds een timestamp","description":"Keyset-gepagineerde lijst van gewijzigde records, gesorteerd op (updated_at, isbn13). Eerste pagina: `?since=<ISO 8601>` (strikt groter, zelfde semantiek als `updated_after` op /v1/books). Vervolgpagina's: `?cursor=<meta.next_cursor>` — de cursor is exact, pagina's geven nooit gaten of dubbelingen. `next_cursor: null` betekent: bij. Records bevatten alleen de verwijzing (isbn13 + changed_at + detail_url); haal de inhoud op via /v1/books (batch). `change_type` is nu altijd `upsert`; verwijderingen volgen later als `delete` — de responsvorm is daarop voorbereid.","parameters":[{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"example":"2026-08-05T00:00:00Z","description":"ISO 8601 met timezone; verplicht op de eerste pagina (tenzij cursor)"},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"meta.next_cursor van de vorige pagina; vervangt since"},{"name":"limit","in":"query","schema":{"type":"integer","default":500,"maximum":2000}}],"responses":{"200":{"description":"Eén pagina wijzigingen + meta.next_cursor (null = bij)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"isbn13":{"type":"string"},"change_type":{"type":"string","enum":["upsert","delete"],"description":"Nu altijd upsert; delete volgt later"},"changed_at":{"type":"string","format":"date-time"},"detail_url":{"type":"string"}}}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"since":{"type":"string","description":"Echo, alleen op de eerste pagina"},"next_cursor":{"type":["string","null"]}}}}}}}},"400":{"description":"Ontbrekende/ongeldige since of cursor","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/reference/nur":{"get":{"summary":"Volledige NUR-tabel (682 rubrieken)","responses":{"200":{"description":"code + name per rubriek"}}}},"/v1/assets/{isbn13}/{kind}":{"get":{"summary":"302-redirect naar cover (vrk), achterkant (atk) of inkijkexemplaar (dvb)","parameters":[{"name":"isbn13","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string","enum":["vrk","atk","dvb"]}}],"responses":{"302":{"description":"Redirect naar de publieke asset-URL"}}}}}}