# GOG Game Prices & Sale Alerts by Country (`superslowsloth/gog-products`) Actor

GOG.com game catalogue with the price, list price and discount in any country and currency, one flat row per game, DLC or pack: title, price, discount percent, release date, developer, genres, tags, rating, platforms, cover, URL. Sale-only filter, search and price/discount/new-release sorts.

- **URL**: https://apify.com/superslowsloth/gog-products.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 product scrapeds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GOG Game Prices & Sale Alerts by Country

Read the [GOG](https://www.gog.com) catalogue (the DRM-free PC game store) for
any country and currency and get one flat row per game, DLC, pack or extra:
title, current price, list price, discount percent and amount, release dates,
developers, publishers, genres, tags, user rating, platforms, cover art and the
store link. Turn on the sale-only switch and sort by biggest discount and a
scheduled run is a **GOG sale alert**; run the same query in several countries
and compare the prices for a **cross-country price check**.

No account, no API key, no login, no browser. One request returns 48 entries.

### Input

| Field | Notes |
|---|---|
| `countryCode` | Two-letter ISO country (default `US`). GOG sells different games at different prices per country. A code GOG does not know is answered with the US catalogue and no error, so check the spelling. |
| `currencyCode` | Three-letter ISO currency (default `USD`). It must be one GOG sells in for that country. See below. |
| `query` | Optional title search, as typed into the store's search box (`witcher`, `dark souls`). Empty reads the whole catalogue. |
| `onlyDiscounted` | Only entries GOG currently discounts. |
| `sort` | `trending` (default, GOG's own order), `bestselling`, `biggest-discount`, `price-asc`, `price-desc`, `new-on-gog` (newest on sale first), `newest-release` (release date, newest first; unreleased "coming soon" entries come first and carry no price), `rating`, `title-asc`. |
| `maxItems` | Entries to return (default 100, up to 10,000). |
| `proxyConfiguration` | Apify proxy by default. |

#### Country and currency

The pair has to be one GOG sells in. Measured on 2026-10-11 across 27 countries
and 23 currencies: USD works everywhere; EUR works in the euro countries and in
GB, CH, CZ, DK, HU, NO, PL, SE; GBP in GB; PLN in PL; BRL in BR; CAD in CA;
AUD in AU and NZ; THB in TH; and so on. JP, KR, IN, AR and UA are USD-only.
Two things GOG does silently, which the actor refuses to pass on as data:

- **A currency GOG does not know** (`XXX`, and also `INR`, `KRW`, `VND`,
  `ARS`) is answered in USD with HTTP 200. The run fails and says so, instead
  of handing you USD prices labelled for the currency you asked for.
- **A currency GOG knows but does not sell in that country** (EUR for the US,
  JPY for Japan) is answered with about 310 entries and not one price. The run
  fails with "GOG lists no prices for country X in Y" before charging for rows.

Both failures cost nothing beyond the start fee. A search term skips the second
check, because a search can legitimately match only unreleased titles.

### Output

| Field | Notes |
|---|---|
| `country_code` | The country the run asked for (GOG does not echo it). |
| `product_id`, `slug`, `title`, `url` | GOG's numeric id (a string; the same in every market, so it is the key to join countries on), URL slug, title and `https://www.gog.com/en/...` store page. |
| `product_type`, `product_state` | `game`, `dlc`, `pack` or `extras`; and `default`, `coming-soon` or `early-access`. |
| `price`, `base_price`, `currency` | Current price and list price as numbers, in the currency GOG answered. `base_price` equals `price` when not on sale. |
| `discount_percent`, `discount_amount`, `is_discounted` | The sale as a whole percent (`50` for "-50%"), as an amount in `currency`, and a flag. |
| `release_date`, `store_release_date` | ISO dates. GOG sends `1999.06.01`. The first is the game's release (future for coming-soon entries); the second is the day it went on sale on GOG. |
| `developers`, `publishers`, `genres`, `tags`, `features`, `operating_systems` | Lists, in GOG's order. Platforms are `windows`, `osx`, `linux`. |
| `rating`, `reviews_count` | The users' review score on a 0 to 5 scale and how many reviewed. |
| `age_rating_pegi`, `age_rating_esrb` | The age rating GOG shows for each board. |
| `cover_url`, `cover_vertical_url` | Horizontal and vertical cover art. Nothing is downloaded. |

#### Honest nulls

A field GOG did not send is `null`, never `0` or `""`:

- `price`, `base_price`, `currency`, `discount_amount` and `is_discounted` are
  null for an entry with no price in this market: every `coming-soon` entry,
  and any entry GOG does not sell in the country. `price` is `0.0` only when
  GOG states a zero price (a free game or a demo).
- `discount_percent` is null when the entry is not on sale; GOG states no
  discount there. `discount_amount` is `0.0` on those entries, which is what
  GOG sends.
- `rating` is null when nobody has reviewed the entry. GOG sends a score of 0
  there, and 0 stars is not "no reviews"; `reviews_count` is 0. `rating` is
  GOG's 0 to 50 score divided by 10 (48 becomes 4.8).
- `release_date` and `store_release_date` are null when GOG gives none (old
  imports have no store date; some bundles have no release date).
- `age_rating_pegi` and `age_rating_esrb` are null when GOG lists no rating for
  that board.

### Pricing

Pay per event:

- **$0.002** per run (`actor-start`), charged only after your input is
  validated, so a run that fails on bad input costs nothing.
- **$0.0007** per product row written (`product-scraped`), i.e. $0.70 per 1,000
  products.

### How it fetches

It calls the JSON API behind GOG's own store pages
(`catalog.gog.com/v1/catalog`), 48 rows per request, with no cookie or key.
Measured 2026-10-11: HTTP 200 from a plain connection and from an Apify
datacenter proxy, and about 700 requests in a few minutes with no rate limit. A
403, 429 or 5xx is treated as a refusal: the actor rotates to a fresh address
and retries.

Things worth knowing, all measured:

- **Result cap.** GOG serves at most 10,000 entries per search (209 pages of
  48\), however many it reports finding: 12,902 match the empty search in the US.
  The actor logs when a search was cut at the cap. Narrow it with a search term
  or the sale-only switch, or run it per country.
- **The size of the catalogue differs by country** (11,855 entries for RU,
  12,301 for DE, 12,902 for the US), so the same query is not the same set of
  games everywhere.
- **Sorts are checked by the actor.** GOG ignores an `order` it does not know
  and answers the default order with HTTP 200, so the actor only sends the nine
  listed above.
- **A page past the last one is HTTP 400.** The actor reads GOG's page count
  and stops on it.
- **Counts move.** GOG re-orders the trending list while a walk is in progress,
  so an entry can appear on two pages; it is returned and charged once.
- **Several words in a search.** GOG matches the words of `dark souls`
  separately (111 hits), not as a phrase.

# Actor input Schema

## `countryCode` (type: `string`):

The two-letter ISO country whose GOG store to read (US, GB, DE, FR, PL, BR, JP ...). GOG sells different games at different prices per country. A code GOG does not know is answered with the US catalogue, so check the spelling.

## `currencyCode` (type: `string`):

The three-letter ISO currency to price in. It must be one GOG sells in for that country: USD works everywhere, EUR in most of Europe, GBP in GB, PLN in PL, BRL in BR, JPY is not sold (use USD for JP). A currency GOG does not sell in that country makes the run fail with an explanation instead of returning rows with no price.

## `query` (type: `string`):

Only games whose title matches this text, as you would type it into the GOG store search box (for example witcher or dark souls). Leave empty to read the whole catalogue.

## `onlyDiscounted` (type: `boolean`):

Return only entries GOG currently discounts. Combine with the 'Biggest discount' sort for a sale alert. Off returns everything, discounted or not.

## `sort` (type: `string`):

The order GOG lists the results in. 'Trending' is GOG's own default. 'Biggest discount' is the one for sale alerts. 'New on GOG' orders by the day an entry went on sale, for new-arrival alerts. 'Release date, newest' lists unreleased 'coming soon' entries first, and those have no price. The price sorts use the price in the chosen currency.

## `maxItems` (type: `integer`):

Read at most this many entries, 48 per request. GOG serves at most 10,000 entries per search however many it reports finding, so values above 10000 are not accepted. A narrower search term or the sale-only switch reaches the rest.

## `proxyConfiguration` (type: `object`):

Apify proxy (automatic datacenter exits) is the default. GOG answered datacenter addresses in testing; a refused request (403, 429) is retried from a fresh address, which is what the proxy is for.

## Actor input object example

```json
{
  "countryCode": "US",
  "currencyCode": "USD",
  "onlyDiscounted": false,
  "sort": "trending",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# 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 = {
    "countryCode": "US",
    "currencyCode": "USD",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/gog-products").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 = {
    "countryCode": "US",
    "currencyCode": "USD",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/gog-products").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "countryCode": "US",
  "currencyCode": "USD",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/gog-products --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superslowsloth/gog-products"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CSGNpNi48I2XWqm1l/builds/YKpybdH8XlNcqxj9Y/openapi.json
