# Board Game Oracle Game Metadata Scraper (`thescrapelab/board-game-oracle-game-metadata-scraper`) Actor

Scrape structured board game metadata from Board Game Oracle by genre or game name. Extract the top N ranked games in a genre, or resolve a single game title, with prices, ratings, mechanics, publishers, images, and Wikidata-enriched fields in clean JSON output.

- **URL**: https://apify.com/thescrapelab/board-game-oracle-game-metadata-scraper.md
- **Developed by:** [Inus Grobler](https://apify.com/thescrapelab) (community)
- **Categories:** Other, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Board Game Oracle Game Metadata Scraper

Extract structured board game metadata from Board Game Oracle through a simple Apify Actor input.

The Actor supports two client-facing workflows:

- Enter a `genre` to scrape the top N most popular games from that Board Game Oracle genre.
- Leave `genre` blank and enter a `gameName` to resolve one game to its single best Board Game Oracle match.

Price fields are always included. Wikidata enrichment is always enabled for missing metadata when available. Proxy usage, request pacing, and concurrency are handled internally, so clients do not need to configure them.

### What This Actor Does

- Scrapes the top-ranked games from a Board Game Oracle genre
- Resolves a single board game name to its best Board Game Oracle match
- Returns flat, analysis-ready rows with metadata, ratings, categories, mechanics, publishers, images, and price fields
- Adds Wikidata fields when Board Game Oracle is missing them
- Writes structured `error` rows when a lookup fails
- Saves a `SUMMARY` record for run-level monitoring

### Input

The Actor accepts these fields:

- `genre`: Board Game Oracle genre or category name, such as `Fantasy`, `Card Game`, or `Science Fiction`. This is the primary input. If both `genre` and `gameName` are provided, `genre` takes priority.
- `gameName`: A single board game name. Used only when `genre` is blank.
- `maxGames`: Maximum number of games to scrape. When using `gameName`, the Actor still resolves at most one game.
- `debugMode`: Enables verbose logs for troubleshooting.

The Actor does not accept Board Game Oracle URLs as input.

### Example Input

#### Genre run

```json
{
  "genre": "Fantasy",
  "maxGames": 20,
  "debugMode": false
}
````

#### Single game-name run

```json
{
  "gameName": "Gloomhaven",
  "maxGames": 1,
  "debugMode": false
}
```

### Output

The Actor writes rows to the default dataset.

- `type = "game"` means the game was parsed successfully.
- `type = "error"` means the lookup failed, was blocked, or could not be parsed.

#### Example game row

```json
{
  "type": "game",
  "source": "boardgameoracle",
  "scrapedAt": "2026-05-10T20:00:00.000Z",
  "boardGameOracleId": "5c5c1177cb4c08209f09c53d",
  "boardGameOracleKey": "bHh_KByEbG",
  "bggId": 174430,
  "wikidataId": "Q36816341",
  "inputSource": "genre",
  "query": "Fantasy",
  "name": "Gloomhaven",
  "yearPublished": 2017,
  "minPlayers": 1,
  "maxPlayers": 4,
  "minPlayTime": 60,
  "maxPlayTime": 120,
  "minAge": 14,
  "ratingAverage": 8.54,
  "geekRating": 8.3,
  "weight": 3.9,
  "rankOverall": 4,
  "categories": ["Adventure", "Fantasy"],
  "mechanics": ["Cooperative Game"],
  "designers": ["Isaac Childres"],
  "artists": ["Alexandr Elichev"],
  "publishers": ["Cephalofair Games"],
  "officialWebsite": "https://cephalofair.com/products/gloomhaven",
  "wikipediaUrl": "https://en.wikipedia.org/wiki/Gloomhaven",
  "imageUrl": "https://cdn.boardgameoracle.com/images/example.jpg",
  "thumbnailUrl": "https://cdn.boardgameoracle.com/images/example-thumb.jpg",
  "description": "A tactical campaign board game set in a persistent fantasy world.",
  "url": "https://www.boardgameoracle.com/boardgame/price/bHh_KByEbG/gloomhaven",
  "lowestPrice": 199.99,
  "lowestPriceCurrency": "USD",
  "lowestPriceStore": "Cape Fear Games",
  "offerCount": 5,
  "retrievedVia": "http",
  "status": "ok",
  "errorMessage": null
}
```

#### Example error row

```json
{
  "type": "error",
  "source": "boardgameoracle",
  "scrapedAt": "2026-05-10T20:00:00.000Z",
  "url": null,
  "inputSource": "genre",
  "query": "Unknown Genre",
  "retrievedVia": null,
  "status": "failed",
  "errorCategory": "invalid_input",
  "blockedReason": null,
  "errorMessage": "Board Game Oracle genre \"Unknown Genre\" was not found.",
  "boardGameOracleKey": null,
  "bggId": null,
  "wikidataId": null
}
```

### Summary Record

The Actor also writes a `SUMMARY` record to the default key-value store. It includes:

- requested input mode and values
- effective internal run settings
- queued game count
- successful game row count
- error row count
- blocked row count
- Wikidata-enriched row count
- fatal error message if the run fails completely

### Run It From Apify

Open the Actor in Apify Console, fill in the Input tab, and run it. Results will appear in the default dataset, and the summary record will be available in the default key-value store.

For API users, the Actor ID is:

`thescrapelab/board-game-oracle-game-metadata-scraper`

### Python API Example

Install the official client:

```bash
pip install apify-client
```

Then run the Actor:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(token=os.environ["APIFY_TOKEN"])
actor_client = client.actor("thescrapelab/board-game-oracle-game-metadata-scraper")

run = actor_client.call(
    run_input={
        "genre": "Fantasy",
        "maxGames": 10,
        "debugMode": False,
    }
)

if run is None:
    raise RuntimeError("Actor run did not complete.")

dataset_id = run["defaultDatasetId"]
dataset_items = client.dataset(dataset_id).list_items().items

print("Rows returned:", len(dataset_items))
print(dataset_items[0] if dataset_items else None)
```

#### Alternate input for a single game

```python
run = actor_client.call(
    run_input={
        "gameName": "Spirit Island",
        "maxGames": 1,
        "debugMode": False,
    }
)
```

### Notes And Limitations

- Genre matching depends on public Board Game Oracle genre pages. Exact or clearly unique genre names work best.
- Genre runs follow Board Game Oracle's public popularity ordering for that genre.
- A `gameName` run resolves only the single best public match, not a list of candidates.
- Some fields may still be `null` if neither Board Game Oracle nor Wikidata exposes them publicly.
- This Actor only uses public web pages and public Wikidata endpoints.

# Actor input Schema

## `genre` (type: `string`):

Choose a suggested Board Game Oracle genre/category, or enter a custom one. Leave blank to use `gameName` instead.

## `gameName` (type: `string`):

Used only when `genre` is blank. The Actor resolves this game name to the single best Board Game Oracle match.

## `maxGames` (type: `integer`):

Maximum number of ranked genre results to scrape when `genre` is provided. For `gameName`, the Actor resolves only the best match.

## `debugMode` (type: `boolean`):

Enable verbose logging for troubleshooting.

## Actor input object example

```json
{
  "genre": "",
  "gameName": "Gloomhaven",
  "maxGames": 20,
  "debugMode": false
}
```

# Actor output Schema

## `results` (type: `string`):

Normalized dataset rows stored in the default dataset.

## `summary` (type: `string`):

A JSON summary record with input settings, counts, proxy strategy, and any fatal or blocked-run notes.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "gameName": "Gloomhaven"
};

// Run the Actor and wait for it to finish
const run = await client.actor("thescrapelab/board-game-oracle-game-metadata-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "gameName": "Gloomhaven" }

# Run the Actor and wait for it to finish
run = client.actor("thescrapelab/board-game-oracle-game-metadata-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "gameName": "Gloomhaven"
}' |
apify call thescrapelab/board-game-oracle-game-metadata-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=thescrapelab/board-game-oracle-game-metadata-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Board Game Oracle Game Metadata Scraper",
        "description": "Scrape structured board game metadata from Board Game Oracle by genre or game name. Extract the top N ranked games in a genre, or resolve a single game title, with prices, ratings, mechanics, publishers, images, and Wikidata-enriched fields in clean JSON output.",
        "version": "2.0",
        "x-build-id": "qv4EIPAaUXHpsdgLE"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/thescrapelab~board-game-oracle-game-metadata-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-thescrapelab-board-game-oracle-game-metadata-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/thescrapelab~board-game-oracle-game-metadata-scraper/runs": {
            "post": {
                "operationId": "runs-sync-thescrapelab-board-game-oracle-game-metadata-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/thescrapelab~board-game-oracle-game-metadata-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-thescrapelab-board-game-oracle-game-metadata-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "genre": {
                        "title": "Game genre",
                        "type": "string",
                        "description": "Choose a suggested Board Game Oracle genre/category, or enter a custom one. Leave blank to use `gameName` instead.",
                        "default": ""
                    },
                    "gameName": {
                        "title": "Game name",
                        "type": "string",
                        "description": "Used only when `genre` is blank. The Actor resolves this game name to the single best Board Game Oracle match.",
                        "default": ""
                    },
                    "maxGames": {
                        "title": "Top N games",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of ranked genre results to scrape when `genre` is provided. For `gameName`, the Actor resolves only the best match.",
                        "default": 20
                    },
                    "debugMode": {
                        "title": "Debug mode",
                        "type": "boolean",
                        "description": "Enable verbose logging for troubleshooting.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
