Board Game Geek API

June 7, 2022

I recently updated the script that populates my board game collection on and I ran into a few tricky parts of the Board Game Geek API and thought I’d share.

The Board Game Geek (BGG) API is split across (at least) three major versions. The v1 and v2 XML HTTP APIs and the modern JSON based HTTP API.

I wanted to pull collection information (which is public) including private information about the acquisition date for each item in my collection. To do so you need to send a GET request to the XML V2 API with the &showprivate=1 parameter and be authenticated as the same account you’re requesting the collection of. An example curl request is curl --request GET --url ''.

However, the documentation on how to authenticate is non-existent. By observing the web requests in the frontend of BGG you can see it making a request to the JSON API with the username and password as a JSON body. An example curl of this is below.

curl --request POST \
  --url \
  --header 'Content-Type: application/json' \
  --data '{"credentials":{"username": "arranf" ,"password": "mypassword"}}'

This request returns multiple Set-Cookie headers for cookies named cc_cookie (not needed for our purposes), SessionID, bgg_password (which is poorly named and contains a hashed value rather than a password), and bgg_username. Confusingly, the bgg_username and bgg_password cookies will be set multiple times. Once with the correct and useful values with an expiry date set in the future, and once with the values set as deleted with a value set to 1 second past the Unix Epoch.

You need to pass the correct cookies back to the BGG XML API to get private collection information back, which will be included in a <privateinfo> field on the items object. If you’re using a tool like Insomnia or curl to test out these requests it’s likely the deleted value cookies will conflict with the correctly populated cookies and will need to be manually handled. Using a library like Python requests seemed to successfully manage the cookies, but you’ll want to confirm the library you use does so as well.

See Also

Last Updated: 2022-06-07 12:16