# G2G Price Monitor: Undercut & Price Drop Alerts (`fayoussef/g2g-offer-scraper`) Actor

Monitor G2G.com prices and get alerted when a seller undercuts you, a price drops or a new offer appears. Also scrapes every offer, seller and stock level from any category.

- **URL**: https://apify.com/fayoussef/g2g-offer-scraper.md
- **Developed by:** [Youssef Farhan](https://apify.com/fayoussef) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 37 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### What does G2G Price Monitor do?

**G2G Price Monitor watches the cheapest offers in any G2G market and tells you the moment something changes: a price drop, a new offer, or a seller who undercuts you.** Schedule it hourly or daily and it reports only what is different since the last run, so you stop refreshing g2g.com by hand.

It is built for people who sell gaming currency, items, accounts or top-ups on [G2G.com](https://www.g2g.com) and need to hold their price against competitors:

- **Undercut alerts.** Enter your G2G username. For every market you sell in, the Actor tracks your price, your rank and how many sellers sit below you, and flags any seller who moves below your price.
- **Price drops and rises** on the cheapest offers, with the old price, the new price and the percentage change. Small moves under a threshold you choose stay quiet.
- **New offers** that appear in a market you already watch.
- **Alerts where you work.** Send one message per run to Discord, Slack, Telegram, or any webhook (Make, Zapier, n8n) on a paid plan.
- **A price history for free.** Every run saves the floor price, the top-10 median and your rank per market, so you can chart how a market moves.

Prefer the raw data? Leave **Monitor mode** off and the Actor works as a full [G2G.com](https://www.g2g.com) scraper, described below.

#### How the monitor works

1. Paste the G2G page of the server or item you sell on. For undercut alerts use the **offer-group page** (open the product on G2G, apply its filters, copy the URL), so you are compared only with sellers of the same product.
2. Turn on **Monitor mode**, enter **My G2G username**, and optionally add a Discord or Slack webhook or a Telegram bot.
3. Run it once. The first run saves a **baseline** of the cheapest offers. It reports nothing as a change.
4. Put it on an [Apify schedule](https://docs.apify.com/platform/schedules). Every later run compares against the saved snapshot and outputs one row per change.

The snapshot lives in a key-value store in your own Apify account, named after your URLs, so the same URLs always continue the same watchlist and a schedule needs no extra setup.

#### What a change row looks like

```json
{
  "change_type": "undercut",
  "market": "Nazgrim [US] - Alliance",
  "seller_username": "GamerNPC",
  "price": 0.070318,
  "previous_price": 0.09,
  "price_change_percent": -21.87,
  "my_price": 0.0704,
  "gap_to_my_price": -0.000082,
  "my_rank": 3,
  "min_order_total": 3.30,
  "available_qty": 835,
  "offer_url": "https://www.g2g.com/offer/G1761277199743XF",
  "detected_at": "2026-10-20T15:05:12+00:00"
}
```

`change_type` is one of `undercut`, `price_drop`, `new_offer`, `price_rise` or `baseline` (first run only). When a run finds more changes than **Max items**, undercuts come first and the rest are kept and reported on the next run, so nothing is lost. A run with no changes outputs no rows and says so in its status message.

Each run also writes a **MONITOR_SUMMARY** record with the floor price, top-10 median, your price and rank, and the number of sellers below you, per market. The price history accumulates in the watchlist's key-value store under `PRICE_HISTORY`.

#### Monitor settings

| Field | Default | What it does |
|---|---|---|
| `monitorMode` | off | Report only changes since the last run |
| `watchWindow` | `100` | How many of the cheapest offers to track per URL (5 to 500) |
| `minChangePercent` | `2` | Price moves smaller than this stay quiet. Undercuts and new offers are always reported |
| `reportNewOffers` | on | Report new offers in a market you already watch |
| `mySeller` | empty | Your G2G username (or several, comma separated) for undercut alerts |
| `watchlistName` | empty | Optional name for the saved snapshot. Empty means it is derived from your URLs |
| `alertWebhookUrl` | empty | Discord, Slack or any https JSON webhook. Paid plans. Kept secret |
| `alertTelegramBotToken`, `alertTelegramChatId` | empty | Optional Telegram alerts. Paid plans. The token is kept secret |

Free plans can run the monitor on one URL with 20 watched offers and see every change in the dataset. Alerts to your webhook or Telegram, and more than one URL, need a [paid Apify plan](https://apify.com/pricing?fpr=youssef).

### What does G2G Scraper do?

**G2G Scraper extracts live prices, sellers, stock and delivery data from [G2G.com](https://www.g2g.com), the world's largest gaming marketplace.** Paste any G2G category, offer group or Trending URL and the Actor returns **78 clean, structured fields for every seller's listing**: unit price, currency, minimum order quantity, available stock, delivery speed, seller name, level, rating and completed orders. Download it as JSON, CSV, Excel or HTML, or pull it straight from the Apify API.

It works on every corner of the marketplace: **game coins and currency** (WoW gold, Dofus kamas, Path of Exile currency, FC 26 coins), **game accounts**, **in-game items and skins**, **top up and gift cards**, and **boosting services**. It returns **every competing seller**, not just the cheapest one the website shows on a product tile, so you can see the whole price ladder for a server or item in one dataset. Because it runs on Apify you get scheduled runs, proxy rotation, run monitoring, webhooks and one-click integrations with Google Sheets, Make, Zapier and Slack, with no G2G login, API key or cookies to maintain.

### Why scrape G2G.com?

G2G is where gaming currency and account prices are actually set, and those prices move hourly. A G2G price scraper turns that live market into a dataset you can act on.

| Use case | What the G2G data gives you |
|---|---|
| **Price monitoring** | Track the cheapest offer per server, game or item over time and spot every price move |
| **Repricing and arbitrage** | See the full price ladder, every seller on a server, before you set your own listing price |
| **Market research** | Measure supply, stock depth, delivery speeds and seller concentration per category |
| **Competitor tracking** | Follow named sellers: their prices, stock, delivery speed, rating and completed orders |
| **Price history datasets** | Schedule hourly or daily runs and build a G2G price history nobody else has |
| **AI agents and dashboards** | Feed live marketplace data into agents, BI tools, sheets or alerting |

### How to use G2G Scraper

1. Open the page you want on **G2G.com**, for example a category like `https://www.g2g.com/categories/wow-classic-gold`.
2. Copy the URL straight from your browser's address bar and paste it into the **G2G URLs** field. Add as many as you like.
3. Set **Max items** to cap how many offers the run collects.
4. Click **Start**. Results stream into the dataset while the run is going, ready to export or send onward.

That is the whole setup. There is nothing to authenticate, no token to paste, and no selector to configure.

### Which G2G URLs work?

| URL you paste | What you get back |
|---|---|
| `g2g.com/categories/wow-classic-gold` | every seller's listing in that category |
| `g2g.com/categories/rbl-item/offer/group?fa=...&region_id=...` | every seller competing on exactly that filtered item, with its filters and region applied |
| `g2g.com/trending/game-coins` | every category the Trending hub lists, scraped in order |
| `wow-classic-gold` | a bare G2G search term, if you already know it |

Locale prefixes such as `/uk/` or `/de/` are fine. If a URL is not a G2G category, the run says so within seconds and names the bad input instead of quietly returning nothing.

### Input (scraper mode)

Two fields are all scraper mode needs. The monitor settings are in the table above. See the **Input** tab for the form.

| Field | Type | Default | Description |
|---|---|---|---|
| `urls` | array **(required)** | - | One or more G2G category, offer-group or Trending URLs |
| `maxItems` | integer | `1000` | How many offers to collect in total across every URL. The run stops as soon as it has this many, so this is your single dial for run length and cost |

```json
{
  "urls": [
    "https://www.g2g.com/categories/wow-classic-gold",
    "https://www.g2g.com/categories/the-last-of-us-part-ii-account"
  ],
  "maxItems": 500
}
```

Everything else is pinned so the form stays simple: prices are quoted in **USD** for the **US** storefront, offers come back **cheapest first**, and pages are fetched 48 at a time until a category runs out or `maxItems` is reached.

### Output

Each seller's listing is one dataset row. Download the dataset as **JSON, CSV, Excel or HTML**, or fetch it through the Apify API. In the Console the table comes with two ready-made views: **Overview** for the columns you scan first (offer, brand, price, minimum order, stock, seller, rating) and **Full details** for all 78 fields with readable labels.

A real row from `https://www.g2g.com/categories/wow-classic-gold`, one seller's own listing:

```json
{
  "title": "Everlook [DE] - Horde",
  "offer_id": "G1767175472140JK",
  "offer_url": "https://www.g2g.com/offer/G1767175472140JK",
  "price": 0.134711,
  "price_scope": "offer",
  "currency": "USD",
  "display_price": "0.134711",
  "unit_name": "K Gold",
  "min_qty": 30,
  "min_order_total": 4.04133,
  "available_qty": 300,
  "delivery_speed": "manual",
  "delivery_time_minutes": 720,
  "seller_username": "GoldGAME",
  "seller_level": 116,
  "verified_seller": "verified",
  "satisfaction_rate": 1,
  "total_rating": 2,
  "total_success_order": 5,
  "brand_name": "WOW Mists of Pandaria Classic",
  "seo_term": "wow-classic-gold",
  "created_at_iso": "2025-12-31T10:04:32.159000+00:00"
}
```

#### Data fields

**78 fields per listing**, everything G2G's own offer page knows:

| Group | Fields |
|---|---|
| **Identity** | `title`, `offer_id`, `offer_url` |
| **Price (buyer-facing)** | `price`, `price_scope`, `currency`, `display_price`, `price_in_usd`, `unit_name`, `qty_metric`, `min_qty`, `min_order_total` |
| **Price (seller's listing)** | `seller_list_price`, `seller_list_currency`, `seller_list_price_usd`, `formatted_unit_price`, `decimal_places` |
| **Bulk and bundles** | `has_wholesale_pricing`, `wholesale_tiers`, `other_pricing`, `pricing_packages`, `is_bundle`, `bundle_qty`, `bundle_available_qty` |
| **Stock** | `available_qty`, `reserved_qty`, `total_offer` |
| **Delivery** | `delivery_speed`, `delivery_time_minutes`, `delivery_tiers`, `delivery_mode`, `delivery_method_ids` |
| **Seller** | `seller_username`, `seller_id`, `seller_level`, `seller_ranking`, `verified_seller`, `satisfaction_rate`, `total_rating`, `total_completed_orders`, `total_success_order`, `is_official`, `seller_online_hours`, `seller_offline_hours`, `seller_updated_at`, `seller_avatar`, `social_profiles` |
| **Product and grouping** | `brand_name`, `brand_id`, `region_id`, `cat_id`, `ancestor_id`, `service_id`, `relation_id`, `lgc_products_id`, `offer_group`, `is_group_display`, `is_unique`, `offer_attributes`, `filter_attributes`, `offer_title_collection_tree` |
| **Availability** | `status`, `supported_countries`, `sales_territory_settings` |
| **Description and media** | `description`, `description_images`, `offer_media_files` |
| **Timestamps** | `created_at`, `created_at_iso`, `updated_at`, `updated_at_iso`, `expired_at`, `expired_at_iso` |
| **Source** | `seo_term`, `filter_attr`, `filter_region_id`, `source_url`, `page` |

### How to read G2G prices correctly

G2G reports two different prices per offer, and mixing them up is the most common mistake when working with this data.

- **`price`** is the buyer-facing unit price in USD, the exact figure g2g.com shows on the page. This is the one to use for price monitoring. `display_price` is the same value as the string G2G renders.
- **`min_order_total`** is `price x min_qty`, the smallest amount a buyer can actually spend. On per-unit listings this is the number that matters: a `min_qty` of 100 turns a $0.13 unit price into a $13.32 purchase.
- **`price_scope`** tells you whose price it is. Every row the Actor returns is `offer`, meaning one named seller's own listing: `price x min_qty = min_order_total` is a real payable total and the seller columns describe that seller. G2G's own pages collapse each product down to its cheapest seller, so a product listing 30 sellers shows one "From" price; this Actor returns all 30 rows instead. Group by `offer_group` or `title` if you want the collapsed view back, and `min()` the price to reproduce the site's "From" figure.
- **`seller_list_price`** and **`seller_list_currency`** are the seller's own listing in the seller's own currency, such as 7500 IDR. Useful for spotting who prices in which market, but it is not what a buyer pays.

### How much does it cost to scrape G2G?

Runs are fast and light: the Actor talks to G2G's public offer-search endpoint rather than rendering pages in a browser, so a few hundred offers cost a fraction of a compute unit. `maxItems` is your cost ceiling, since the run stops the moment it is reached.

**Free plan users are limited to 20 offers per run.** Upgrading removes the cap entirely, across every URL, page and category.

🔓 **[Subscribe to a paid Apify plan](https://apify.com/pricing?fpr=youssef)** to unlock the full Actor.

### Tips for faster, cheaper G2G scraping

- Point at the **narrowest URL that answers your question**. One category URL costs far less than a Trending hub that expands into 20 of them.
- Use `maxItems` as a budget. On a Trending hub the categories are drained in the order the hub lists them, so a small cap samples the first games deeply rather than every game shallowly.
- For **price history**, schedule a small run often rather than a huge run rarely. Ten offers per hour beats a thousand offers once a week.
- Group-page URLs already carry their filters in the query string. Copy the URL after you have applied the filters on G2G and the Actor reproduces exactly that view.

### Use G2G Scraper with AI agents via MCP

This Actor is **MCP-ready**, so you can call it from Claude, ChatGPT or any agent framework through the Apify MCP server and get live marketplace data on demand. Typical agent questions it answers: *"What is the cheapest WoW Classic gold per 1k right now?"*, *"Which sellers deliver Dofus kamas in under 10 minutes?"*, *"Has the floor price for FC 26 coins moved since yesterday?"*

### Automate it

Use **[Apify Schedules](https://docs.apify.com/platform/schedules)** to run this G2G scraper hourly or daily and build a price-history dataset automatically. Wire the output into Google Sheets, a webhook, Make or Zapier to get alerted the moment a price drops below your threshold.

### Reliability

- **Migration-safe:** progress is checkpointed continuously, so if the platform moves your run to another server it resumes exactly where it stopped, with no duplicate rows.
- **No credentials to expire:** the endpoint is public, so nothing breaks when a token or cookie would have gone stale.
- **Loud failures:** a bad URL is rejected in seconds with a message naming it, and a category that stops responding is logged rather than silently skipped.

### FAQ

**Do I need a G2G account, API key or cookies?**
No. The Actor uses G2G's public offer-search endpoint, so there is nothing to log into and nothing to maintain.

**Is there a G2G API?**
G2G does not publish a documented public API for buyers. This Actor is the practical G2G API alternative: you get the same listing data as clean JSON, on a schedule, through the Apify API.

**Can I scrape several games or categories in one run?**
Yes. Add as many URLs as you want to the `urls` field, and they share the `maxItems` budget.

**What currency are the prices in?**
USD, quoted for the US storefront, so every row is directly comparable. G2G prices shift slightly by storefront country, and pinning one keeps the dataset consistent.

**Do I get every seller, or only the cheapest?**
Every seller. G2G's category pages show one "From" price per product, but the Actor returns each seller's own listing as its own row, with that seller's price, minimum quantity, stock and rating.

**How many results do I get on the free plan?**
20 per run. A [paid Apify plan](https://apify.com/pricing?fpr=youssef) removes the cap.

**Is scraping G2G legal?**
This Actor collects only publicly available listing data, the same information any visitor sees. You are responsible for complying with G2G's terms of service and the laws that apply to you. Do not use it for personal data or anything behind a login.

**Something is broken or missing.**
Report it on the **Issues** tab and it gets looked at. Need a tailored version or a different marketplace? [Contact me through my Apify profile](https://apify.com/fayoussef).

### Related keywords

g2g price monitor, g2g price alert, g2g undercut alert, g2g seller price tracker, g2g competitor price monitor, wow gold price alert, g2g scraper, g2g.com scraper, scrape g2g, g2g price tracker, g2g api, g2g api alternative, wow gold price scraper, game currency price monitoring, game account price scraper, gaming marketplace scraper, g2g offers, g2g sellers, in-game item price data, g2g data extractor, game coin price history.

# Actor input Schema

## `urls` (type: `array`):

One or more G2G URLs. Three kinds work: a category page (https://www.g2g.com/categories/wow-classic-gold), an offer-group page with filters applied (https://www.g2g.com/categories/rbl-item/offer/group?fa=...\&region_id=..., which returns only the offers that page shows), and a Trending hub (https://www.g2g.com/trending/game-coins, expanded into every category it lists). A raw seo_term (wow-classic-gold) works too, and locale prefixes like /uk/ are fine. For undercut alerts, paste the offer-group URL of the server or item you sell on, so you are compared only with sellers of the same product. Prices come back in USD, cheapest first.

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

In scraper mode: how many offers to scrape in total across every URL; the run stops as soon as it has this many. In monitor mode: the most change rows one run reports (the rest are kept and reported next run). Free plans are capped at 20 regardless.

## `monitorMode` (type: `boolean`):

Report only changes since the last run instead of scraping everything. The snapshot is saved in a key-value store in your own account, named after your URLs, so a schedule needs no extra setup.

## `watchWindow` (type: `integer`):

How many of the cheapest offers to track per URL. Undercuts happen at the bottom of the price ladder, so 100 covers it for most markets. Free plans watch 20.

## `minChangePercent` (type: `number`):

A price move smaller than this is not reported, which keeps noisy markets quiet. Undercuts and new offers are always reported. Use 0 to see every move.

## `reportNewOffers` (type: `boolean`):

Report offers that appeared in a market you already watch since the last run. Turn it off if you only care about price moves and undercuts.

## `mySeller` (type: `string`):

Your seller name on G2G, or several separated by commas. Your own offers are never reported as changes. The Actor tracks your price, your rank and who sits below you in each market, and flags any seller who moves below your price as an undercut.

## `watchlistName` (type: `string`):

Names the saved snapshot. Leave empty and it is derived from your URLs, so the same URLs always continue the same watchlist. Set it when you want two schedules on the same URLs to keep separate histories.

## `alertWebhookUrl` (type: `string`):

A Discord, Slack or generic https webhook URL. Kept secret. Do not put it in a public task.

## `alertTelegramBotToken` (type: `string`):

Optional. Create a bot with @BotFather on Telegram and paste its token here. Kept secret.

## `alertTelegramChatId` (type: `string`):

Optional. The chat the bot should message: your own chat ID, or a group or channel the bot was added to.

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

Optional. Leave empty to use Apify Proxy (datacenter), the default. Switch to residential if G2G starts refusing the requests.

## Actor input object example

```json
{
  "urls": [
    "https://www.g2g.com/categories/wow-classic-gold"
  ],
  "maxItems": 1000,
  "monitorMode": false,
  "watchWindow": 100,
  "minChangePercent": 2,
  "reportNewOffers": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `offers` (type: `string`):

All scraped offers (price, stock, delivery, seller). Use the table view selector to switch between the 'Overview' and 'Full details' views.

## `monitorSummary` (type: `string`):

Monitor mode only: floor price, your rank and the changes found, per market.

# 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 = {
    "urls": [
        "https://www.g2g.com/categories/wow-classic-gold"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fayoussef/g2g-offer-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 = { "urls": ["https://www.g2g.com/categories/wow-classic-gold"] }

# Run the Actor and wait for it to finish
run = client.actor("fayoussef/g2g-offer-scraper").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 '{
  "urls": [
    "https://www.g2g.com/categories/wow-classic-gold"
  ]
}' |
apify call fayoussef/g2g-offer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fayoussef/g2g-offer-scraper"
        }
    }
}
```

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/peXN8637i0xTBIsmB/builds/i8mblHtq6NokFpAzx/openapi.json
