GoGeek is a Go client for the BoardGameGeek API (XML API2). It handles the HTTP requests, authentication, rate limiting, and XML parsing so you can work with plain Go structs.
Install with go get:
go get github.com/kkjdaniel/gogeek/v3Create a client, then use it to make API requests:
package main
import (
"context"
"fmt"
"log"
"github.com/kkjdaniel/gogeek/v3"
"github.com/kkjdaniel/gogeek/v3/thing"
)
func main() {
// Create a client (all BGG endpoints require authentication,
// see the Authentication section below)
client := gogeek.NewClient(gogeek.APIKey("your-api-key"))
// Query board games by BGG ID
games, err := thing.Query(context.Background(), client, []int{13, 12, 3})
if err != nil {
log.Fatal(err)
}
for _, game := range games.Items {
fmt.Printf("Name: %s\nYear Published: %d\n", game.Name[0].Value, game.YearPublished.Value)
}
}Name: CATAN
Year Published: 1995
Name: Ra
Year Published: 1999
Name: Samurai
Year Published: 1998
All BGG endpoints require authorisation. Anonymous access is no longer supported by the API, so every client is constructed with credentials.
API key (recommended):
client := gogeek.NewClient(gogeek.APIKey("your-api-key"))
collection, err := collection.Query(ctx, client, "username")You can request an API key via BGG's application form.
Cookie:
cookie := "bggusername=user; bggpassword=pass; SessionID=xyz"
client := gogeek.NewClient(gogeek.Cookie(cookie))
user, err := user.Query(ctx, client, "username")By default, every client:
- Limits requests to 2 per second, in line with BoardGameGeek's API guidelines
- Times out requests after 30 seconds
- Retries queued (202) and throttled (429/503) responses with exponential backoff
Each of these can be changed with client options:
client := gogeek.NewClient(
gogeek.APIKey("your-api-key"),
gogeek.WithRateLimit(1),
gogeek.WithRetry(3, time.Second),
gogeek.WithHTTPClient(custom),
)- Every query takes a
context.Context, so requests can be cancelled or given deadlines - The
thingquery accepts any number of IDs; batches of more than 20 are split into multiple rate-limited requests automatically - Query filters use per-package options (e.g.
plays.WithPage(2),collection.WithOwned(true)); invalid option values return an error wrappinggogeek.ErrInvalidOptionbefore any request is made - Some options request extra data, such as
thing.WithVideos(), which populates each item'sVideosfield with its community-submitted videos
Every endpoint in the BGG XML API2 is supported, along with all of its working parameters.
| API endpoint | Package | Supported |
|---|---|---|
/thing |
thing |
✅ |
/family |
family |
✅ |
/forumlist |
forumlist |
✅ |
/forum |
forum |
✅ |
/thread |
thread |
✅ |
/user |
user |
✅ |
/guild |
guild |
✅ |
/plays |
plays |
✅ |
/collection |
collection |
✅ |
/hot |
hot |
✅ |
/search |
search |
✅ |
Parameters the API itself no longer supports (historical, from, and to on /thing; username on /thread) are omitted, and geeklists are excluded because they were never added to XML API2.
Full documentation is on pkg.go.dev. Each package documents its query function and the structs it returns.
Contributions are welcome. Open an issue or submit a pull request on GitHub to help improve GoGeek.
