EasyCB_API

Easy CB API - a easy and free way to query “centraal boekhuis” (TitelBank) ISBN information.



Introduction

This HTTP Key => Value API was set up to provide a sane way to access (meta) data of books in print in the Netherlands in a simple machine programmable way.

It was created to address our own frustrations, but is provided as a free service for anybody to use. The usage will always be free, but we can not guarantee that this service will be around forever. If at any time in the future CB / TitelBank provides a service that adresses the fundamental needs that any online bookshop runs into, this service will be fased out.

The 3 problems adressed are:

NB: a valid contact email-address has to be provided in every API call if you use it more then incidentally. This provides us a way of contacting you in case of any detected problems.

Failure to provide a valid contact address in the header will lead to blocking of your IP/CIDR in case of incorrect or unreasonable usage


How to use the easycbapi API

It’s quite simple to use. Simply HTTP GET:

https://easycbapi.nl/isbn/the-isbn-nummer

And it will output any information it has about this ISBN in a simple key:value format

Example: https://easycbapi.nl/isbn/9789083316642

Example using curl:


    
    shell> curl -s -H "contact: developer_to_contact@example.org" https://easycbapi.nl/isbn/9789002219788

    isbn:9789002219788
    title:Het generatiepact
    author:B. Huygebaert
    mutationlog:
    ProductSupply.SupplyDetail.Price.CurrencyCode:EUR
    ProductSupply.SupplyDetail.Price.PriceAmount:9.95
    ProductSupply.SupplyDetail.Price.PriceType:02
    ProductSupply.SupplyDetail.ProductAvailability:99
    CollateralDetail.TextContent.TextType:05
    DescriptiveDetail.Contributor.ContributorRole:A01
    DescriptiveDetail.Contributor.KeyNames:Huygebaert
    DescriptiveDetail.Contributor.NamesBeforeKey:B.
    DescriptiveDetail.Contributor.PersonName:B.  Huygebaert
    DescriptiveDetail.Contributor.SequenceNumber:1
    DescriptiveDetail.EditionNumber:1
    DescriptiveDetail.Extent.ExtentType:00
    DescriptiveDetail.Extent.ExtentUnit:03
    DescriptiveDetail.Extent.ExtentValue:168
    DescriptiveDetail.Illustrated:01
    DescriptiveDetail.Language.LanguageCode:dut
    DescriptiveDetail.Language.LanguageRole:01
    DescriptiveDetail.NoCollection: 
    DescriptiveDetail.ProductComposition:00
    DescriptiveDetail.ProductForm:BC
    etc.
    

To receive a list of all ISBN’s that have been changed since date X, use :

https://easycbapi.nl/isbn-since/20241201

The date has to be provided in the UNIX POSIX format ‘%Y%m%d’, meaning: full-year, the number of the month and the number of the day.

Example of a valid date: 20241130

It can be generated with the Unix command:


    shell> date '+%Y%m%d'    

    20241130

Or more likely with a strftime function or its derivatives:


    strftime("%Y%m%d", timestamp )   

So a call to the /isbn-since/ API in curl can be :


    shell> curl -s -H "contact: developer_to_contact@example.org" https://easycbapi.nl/isbn-since/20241030 | head   

    9789000035588
    9789000035960
    9789000301096
    9789000301355
    9789000305155
    9789000309757
    9789000314720
    9789000321834
    9789000330409
    9789000330416

A note of warning: If for whatever reason we are out of sync with Centraal Boekhuis, and forced to do a completely new import, it will list ALL ISBN’s as modified!

To get a list of all ISBN’s published use:


    shell> curl -s -H "contact: developer_to_contact@example.org" https://easycbapi.nl/isbn-since/all | wc -l    
    1950906

A simple, crude and inefficient way to use the API call’s combined would be :


    #!/bin/sh 

    # What date was the update last run? 
    DATE = `cat last_run_date.state`

    # fetch updated ISBN's since this date, and runs update_isbn with each changed ISBN

    curl -s -H "contact: developer_to_contact@example.org" https://easycbapi.nl/isbn-since/$DATE | xargs -r -i sh -c 'curl -s -H "contact: developer_to_contact@example.org" https://easycbapi.nl/isbn/{} | ./update_isbn {} '

    # ./update_isbn takes the first command-line arg as the name of the ISBN, and reads key:values from its STDIN.
    # how it updates the data in a database is implementation dependent and beyond this example

    # update the last_run_date.state state file
    date '+%Y%m%d' > last_run_date.state

    

This of course has no error checking, and is very inefficient, since it spawns a new process for every update. It also does not first filter the ISBN to check, but it shows how one could use the combined API’s, and is simple to read and understand.

Another example in which you update all of your book information:


    #!/bin/sh
    #
    # in this case you have a CSV file that lists all ISBN's your shop caries in the first field, and dump them to STDOUT with the cat books.csv  |awk -F, '{print $1}' 
        # the sed -e 's/"//' is there to strip away "" from "9789083117614" which some CSV exports put around any value.

    cat books.csv  |awk -F, '{print $1}' | sed -e 's/"//' | xargs -r -i sh -c 'curl -s -H "contact: developer_to_contact@example.org" https://easycbapi.nl/isbn/{} | ./update_isbn {}'

Resources

Resources of a ISBN such as book covers can also be fetched.

You can retrieve any cover / with the URL:
https://easycbapi.nl/resources/jpg/(resource)

For example the resource links from ISBN 9789046828540 are:


    shell> curl -s https://easycbapi.nl/isbn/9789046828540| grep 'ResourceLink'

    CollateralDetail.SupportingResource.1.ResourceVersion.ResourceLink:9789046828540_VRK.jpg   
    CollateralDetail.SupportingResource.2.ResourceVersion.ResourceLink:9789046828540_DVB.pdf   
    CollateralDetail.SupportingResource.0.ResourceVersion.ResourceLink:9789046828540_ATK.jpg   

And they can be fetched from :

https://easycbapi.nl/resources/jpg/9789046828540_VRK.jpg

https://easycbapi.nl/resources/jpg/9789046828540_ATK.jpg

https://easycbapi.nl/resources/pdf/9789046828540_DVB.pdf

To prevent hot-linking the referrer must either be empty, or the site itself.

In other words: if you simply fetch the resource everything should be ok, but hot-linking won’t work.


Logs

To see all the ONX historical info for a ISBN, simply append the isbn URL with .log to /isbnlog/ This will show when any ISBN was updated, and with what info.

For example:


    shell> curl -s https://easycbapi.nl/isbnlog/9789046828540.log

20230809    CollateralDetail.SupportingResource.ContentAudience:03
20230809    CollateralDetail.SupportingResource.ResourceContentType:15
20230809    CollateralDetail.SupportingResource.ResourceMode:03
20230809    CollateralDetail.SupportingResource.ResourceVersion.ResourceForm:01
20230809    CollateralDetail.SupportingResource.ResourceVersion.ResourceLink:9789046828540_DVB.pdf
20230809    CollateralDetail.TextContent.ContentAudience:03
20230809    CollateralDetail.TextContent.Text:Actiegerichte Amerikaanse doorlezer.
20230809    CollateralDetail.TextContent.TextSourceCorporate:volkskrant
20230809    CollateralDetail.TextContent.TextType:06
20230809    DescriptiveDetail.Contributor.ContributorRole:B06
20230809    DescriptiveDetail.Contributor.KeyNames:Noë
20230809    DescriptiveDetail.Contributor.NamesBeforeKey:Waldemar
20230809    DescriptiveDetail.Contributor.PersonName:Waldemar  Noë
20230809    DescriptiveDetail.Contributor.SequenceNumber:4

The format is:


  date tab key:value   

Sources & Correctness

A thing to note is that this service depends on the completeness and correctness of the Titelbank ONIX info. Unfortunately the Titelbank ONIX dumps are incomplete, missing updates and in general not in the best state.

A big part of the problem is that ONIX files don’t provide the correct data, but provides updates, on top of older data, encoded in XML. It’s like ONIX (AAP, EDItEUR, et al. ) took a old EDI standard and encoded it in XML.

Links

If you’re going to have to deal with the ONIX standard, you will need to read these links


Contact

Contact questions@easycbapi.nl if you have questions, experience problems, have remarks or because you feel like it.

Caveat: If you don’t understand the listed examples, this API is probably not for you.

end

NB: any page on this site can be accessed in the original markdown by replacing the .html with .md

a Tifkap Enterprises production