# Used GPU Price & Stock Monitor — GPUsed (`maydit/used-gpu-price-stock-monitor`) Actor

Track public GPUsed graphics-card asking prices, grades, VRAM and availability in GBP. Detect price and restock changes for resale research without login, keys or proxies.

- **URL**: https://apify.com/maydit/used-gpu-price-stock-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 saved observations

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

## Used GPU Price & Stock Monitor — GPUsed

Turn a bounded window of public GPUsed UK graphics-card listings into structured **GBP asking prices, seller grades, explicit VRAM and stock flags**, with optional comparisons against your last complete run.

Use this to maintain a sourcing sheet, spot a listed restock, or review a price reduction before buying inventory. It covers **GPUsed only**. It does not estimate resale value or promise a profit.

### Start in under a minute

Run with the prefilled input to receive five public GPU offers. Open **Dataset** for JSON/CSV exports or **Readable run report** for coverage and errors.

```json
{"collections":["graphics-cards"],"productsPerPage":5,"maxPagesPerCollection":1,"maxResults":10}
```

The source page is selected first; optional model, availability, VRAM and price filters apply inside that window. A filter can correctly return zero records. Increase the window deliberately rather than assuming the entire catalog was searched.

### Practical workflows

**Reseller sourcing:** match the exact model, memory amount, grade, condition and included items with your own sold-price evidence. Subtract purchase price, inbound and outbound shipping, selling fees, tax and refurbishment costs yourself. A current asking price is not proof of a completed sale or a buying recommendation.

**Restock watch:** use the same collection, filters and snapshot name across runs. A `restocked` value of `true` means a previously observed unavailable variant is now marked available. It does not reserve the card or reveal quantity.

**Inventory repricing:** compare your own inventory against source-dated offers. `comparisonKey` groups exact source model/grade/condition/memory strings, not independently verified equivalence between shops. `pricePerVramGb` is only a capacity ratio, never a performance/value score.

### Three ready-to-run recipes

#### 1. Recent offers

```json
{"collections":["graphics-cards"],"productsPerPage":5,"maxPagesPerCollection":1,"maxResults":10}
```

#### 2. NVIDIA listed-stock changes

```json
{"collections":["nvidia"],"productsPerPage":10,"maxPagesPerCollection":1,"inStockOnly":true,"maxResults":20,"comparePrevious":true,"snapshotName":"nvidia-stock"}
```

Keep `inStockOnly` false when detecting unavailable-to-available changes: an unavailable variant must have been observed previously to establish that transition. The stock-only recipe is for currently available offers and price changes, not a complete restock history.

#### 3. AMD offer research

```json
{"collections":["amd"],"productsPerPage":5,"maxPagesPerCollection":1,"maxResults":10}
```

### What each result means

| Fields | Meaning |
|---|---|
| `recordId`, `productId`, `variantId`, `sku` | Stable source identity; a missing SKU remains null. |
| `price`, `currency`, `compareAtPrice` | Source variant amounts; currency is independently checked against the public shop metadata and must be GBP. |
| `available`, `quantity` | Published availability flag; quantity is always unknown/null. |
| `model`, `series`, `grade`, `condition` | Explicit seller statements where present. No grade inferred from a title suffix. |
| `vramGb`, `memoryType`, `warnings` | Explicit source facts; conflicting capacities/types are withheld and explained. |
| `includedItems`, `warrantyStatement` | Bounded source statements where present, not independently verified guarantees. |
| `observedAt`, `sourceUrl`, `url` | Retrieval time, precise catalog source and variant listing. `productUpdatedAt` is source metadata, not proof of the last price change. |
| `comparisonStatus`, `changedFields`, `previous`, `priceChange`, `restocked` | Differences between observations under the same snapshot scope. First observations have no invented previous price. |

### Comparison and coverage

Enable `comparePrevious` to keep private history. `onlyChanges` also enables it and suppresses unchanged observations. History includes the collections, page window and filters, so changing them starts a separate comparison scope. A named snapshot supports independent workflows.

History advances only after a complete selected-window run. Source failures, time limits, spending caps or truncated output preserve the prior baseline. Concurrent writers are rejected rather than silently overwriting each other. Do not run overlapping jobs with the same snapshot. Missing products are never assumed sold, deleted or unavailable.

`SUMMARY` reports requested sources, pages, filtering, saved rows, errors, caps and history status. The selected window can be complete while the entire catalog remains unsearched. A nonempty partial dataset is not a full successful comparison.

### Pricing and limits

Base price: **$2 per 1,000 saved observations**, plus **$0.00005 per start** at this Actor's 256 MB setting. No separate fee for an unchanged row suppressed by `onlyChanges`. Platform usage and applicable tier discounts follow Apify's displayed pricing. Use Apify's maximum-charge control to bound spending.

Up to three fixed supported collections, four pages per collection, 50 products per page, 100 saved variants and 120 seconds. Public requests are bounded and spaced. Robots rules are honored; HTTP 401/403/429 stops further source access without a proxy, login or retry workaround. No purchase, account, cart or checkout operations occur.

### Source and limitations

Source: [GPUsed public shop](https://www.gpused.co.uk/collections/graphics-cards), [seller grading definitions](https://www.gpused.co.uk/pages/grading-system). This tool is independent of GPUsed. The data is public product facts, not product photographs or full marketing descriptions.

UK/GBP scope matters. Cross-border shipping eligibility, currency conversion, tax, fees, product authenticity, physical testing, compatibility and sold-market prices are not evaluated. Always review the actual listing before purchasing. No keys, cookies or proxies are required.

See [Mayd It data tools](https://mayd-it.com/data-tools/) for workflow guidance. Report a reproducible problem through this Actor's Issues tab with a run link and input, excluding credentials or private information.

# Actor input Schema

## `collections` (type: `array`):

Up to three supported GPUsed collection handles. Empty uses graphics-cards. Supported: graphics-cards, nvidia, amd, used-workstation-ai-graphics-cards, nvidia-30-series, nvidia-40-series, nvidia-50-series-gpus.

## `productsPerPage` (type: `integer`):

Bounded source window before GPU, availability and keyword filters. Not a whole-market search.

## `maxPagesPerCollection` (type: `integer`):

At most four sequential public catalog pages per collection.

## `inStockOnly` (type: `boolean`):

Exclude variants the shop marks unavailable. Availability does not disclose exact quantities or reserve stock.

## `modelKeywords` (type: `array`):

Optional literal phrases matched against the product title or explicit model field. Any phrase matches inside the selected source window.

## `minVramGb` (type: `integer`):

If above zero, rows without an explicit unambiguous VRAM amount are excluded. VRAM is not a performance score.

## `maxPriceGbp` (type: `number`):

Zero disables this filter. Shipping, fees and tax adjustments are not calculated.

## `maxResults` (type: `integer`):

Maximum saved billable observations across sources. Partial windows do not advance comparison history.

## `comparePrevious` (type: `boolean`):

Store source observations only after the entire selected window succeeds. New, changed and unchanged records include previous values. Missing records are never inferred closed or deleted.

## `onlyChanges` (type: `boolean`):

Enables comparison. Unchanged repeats can correctly save zero rows and incur no dataset-item charges.

## `snapshotName` (type: `string`):

1-80 letters, numbers, underscores or hyphens. Separate history for the source list, selected window and filters. Use a new name for an independent workflow.

## `maxRunSeconds` (type: `integer`):

Shared deadline with bounded public requests. Access refusals and rate limits stop further requests without a bypass.

## Actor input object example

```json
{
  "collections": [
    "graphics-cards"
  ],
  "productsPerPage": 5,
  "maxPagesPerCollection": 1,
  "inStockOnly": false,
  "modelKeywords": [],
  "minVramGb": 0,
  "maxPriceGbp": 0,
  "maxResults": 20,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "maxRunSeconds": 90
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

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

No description

## `report` (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 = {
    "collections": [
        "graphics-cards"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/used-gpu-price-stock-monitor").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 = { "collections": ["graphics-cards"] }

# Run the Actor and wait for it to finish
run = client.actor("maydit/used-gpu-price-stock-monitor").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 '{
  "collections": [
    "graphics-cards"
  ]
}' |
apify call maydit/used-gpu-price-stock-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/used-gpu-price-stock-monitor"
        }
    }
}
```

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/NImEfA9sk4aQ86rlc/builds/Y7GBdpdResm0dDHCZ/openapi.json
