# Gumroad Product Scraper - Prices, Ratings, Tags (`midnight_static/gumroad-product-scraper`) Actor

Digital product data from Gumroad Discover categories and search: name, price, currency, pay-what-you-want, subscription recurrence, product type, seller and verified flag, rating average and count, stock left, category totals, top tags and file types. 31 fields for creator marketplace research.

- **URL**: https://apify.com/midnight\_static/gumroad-product-scraper.md
- **Developed by:** [Midnight Static](https://apify.com/midnight_static) (community)
- **Categories:** For creators, E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 products

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

## Gumroad Product Scraper

Point it at Gumroad Discover categories or search terms. Get back every product with its price, seller, rating, product type and subscription terms, plus the size and shape of the category it sits in. **31 fields per product**, as JSON, CSV or Excel.

### Four things that are different here

**1. You pay only for records that contain data, and never twice for the same product.**
Gumroad shows the same product across several category and search pages. Other scrapers write it again each time, and you pay again each time. This one keeps a seen-set for the whole run: a product is written once, charged once. Pages that produce nothing go to a free skipped-pages list with a reason code.

**2. No start fee.**
The three Gumroad scrapers on this Store with more than ten monthly users all charge a per-run fee on top of their per-record price. This one does not. The number on this page is the whole bill.

**3. You get the category, not just the products.**
Every record carries how many products the whole category holds, its top tags with document counts, and its top file types with counts. So you do not only learn that a Figma plugin costs $19 — you learn that the Design category holds 61,268 products, that 5,640 of them are tagged "mockup", and that 30,245 ship as a zip. That is market structure, and no other scraper here exposes it.

**4. It reads the data the page already carries.**
Not a rendered browser, not a private endpoint. Gumroad ships the product payload inside the page it serves you. One request returns 36 products with full detail, which is why this is fast and cheap to run.

### What you get

**Product**
Product id, permalink, name, URL, product type (digital product, membership, course, bundle), thumbnail.

**Price and terms**
Price in currency units and in cents, currency code, whether it is pay-what-you-want, subscription recurrence, and subscription duration when there is one.

**Seller**
Seller id, name, profile URL, avatar, and whether Gumroad has verified them.

**Reputation**
Rating average and rating count, so you can tell a 5.0 from six buyers apart from a 4.6 from nine hundred.

**Availability**
Quantity remaining and whether the listing is sales-limited, for scarcity and launch tracking.

**Category context**
Category slug and URL, total products in that category, top tags with counts, top file types with counts, and the position the product held in the listing.

**Provenance**
`sourceUrl`, `fetchedAt`, `httpStatus` and `filledFieldCount` travel with every record.

### Typical uses

Finding which niches on Gumroad are crowded and which are thin, using category totals and tag counts. Tracking a competitor's catalogue, prices and ratings over time. Sizing a market before building a digital product. Finding top-rated sellers in a category. Watching launch prices and scarcity tactics.

### Example record (trimmed)

```json
{
  "name": "Email Love Figma Plugin → HTML Email Builder",
  "productType": "membership",
  "price": 19,
  "currency": "usd",
  "recurrence": "monthly",
  "isPayWhatYouWant": false,
  "sellerName": "Email Love",
  "sellerIsVerified": false,
  "ratingAverage": 5,
  "ratingCount": 6,
  "listPosition": 1,
  "categorySlug": "design",
  "categoryTotalProducts": 61268,
  "categoryTopTags": [{ "tag": "mockup", "count": 5640 }, { "tag": "free", "count": 3112 }],
  "categoryTopFileTypes": [{ "fileType": "zip", "count": 30245 }, { "fileType": "pdf", "count": 9049 }],
  "filledFieldCount": 27,
  "httpStatus": 200,
  "fetchedAt": "2026-09-17T12:04:18.221Z",
  "sourceUrl": "https://discover.gumroad.com/design"
}
```

### Input

Give it category URLs, plain search keywords, or neither. With an empty input it starts from Discover and finds categories itself.

`maxItems` caps how many products are written so a long run cannot produce an unexpected charge. `maxPages` caps how many pages are fetched. `followCategories` turns discovery off when you want only what you listed.

### Failures are loud

The run fails with an explanation rather than finishing quietly with less data than you expected. If the page structure changes, you get a parse error naming the affected pages, not an empty dataset. Counters are reconciled at the end of every run: pages fetched, products written, unique products, robots-blocked, HTTP failures, parse failures, empty pages, duplicates. The full breakdown is written to the `RUN_STATS` key and every skipped page to `SKIPPED`.

Transient gateway errors are retried up to three times before a page is given up on.

### Limits and compliance

`robots.txt` is checked before every request and a disallowed path is never fetched. If `robots.txt` itself cannot be read, the run stops before making a single data request rather than guessing.

No buyer data is collected. Sellers appear in their commercial capacity: storefront name, public profile URL and Gumroad's own verification flag. The output is built from an explicit list of known fields, so nothing outside that list can reach your dataset.

Prices and ratings change. Every record carries `fetchedAt` so you always know when the figure was true.

### Pricing

**$2.00 per 1,000 products, everything included.** No start fee, no minimum charge per run, and no separate platform usage line on your bill.

Paid Apify plans pay less, automatically — there is nothing to apply for: Bronze $1.80, Silver $1.60, Gold and above $1.40 per 1,000 products. The Free plan price is unchanged at $2.00.

Measured across all 27 Gumroad scrapers on this Store on 17 September 2026: prices run from $1.50 to $50.00 per 1,000, median $2.99, and 23 of the 27 add a per-run fee. The three with more than ten monthly users charge $4.30 to $5.00 per 1,000 and all three add a run fee. This one is a single number, and duplicates are free.

### Measured performance

Measured on 17 September 2026 from Apify's own network, no proxy:

| | |
|---|---|
| Products per page request | 36 |
| Fields populated per product | 27 of 31 (median) |
| Pages returning content | 3 of 3 |
| Average page size | 146 KB |

# Actor input Schema

## `categoryUrls` (type: `array`):

Gumroad Discover category pages to scrape, one per line. Leave empty to start from Discover and find categories automatically.

## `searchTerms` (type: `array`):

Plain keywords to search, one per line. Gumroad applies a query only inside a category, so each term is crossed with the categories you listed, or with all 18 top-level categories when you list none.

## `followCategories` (type: `boolean`):

Walk the full Gumroad category tree (18 top-level plus 341 subcategories) found in the page itself. Turn this off to scrape only what you listed.

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

Hard cap on how many product records are written, so a long run cannot produce an unexpected charge.

## `maxPages` (type: `integer`):

Hard cap on how many pages are fetched.

## `concurrency` (type: `integer`):

How many pages are fetched in parallel.

## Actor input object example

```json
{
  "categoryUrls": [
    "https://discover.gumroad.com/design",
    "https://discover.gumroad.com/software-development"
  ],
  "followCategories": true,
  "maxItems": 1000,
  "maxPages": 200,
  "concurrency": 4
}
```

# Actor output Schema

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

One record per product: price, seller, rating, type and the category it ranked in.

## `runStats` (type: `string`):

Counters: pages fetched, products written, robots-blocked, HTTP failures, parse failures, duplicates.

## `skipped` (type: `string`):

Every page that produced no record, with the reason. Free, never charged.

# 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 = {
    "categoryUrls": [
        "https://discover.gumroad.com/design",
        "https://discover.gumroad.com/software-development"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("midnight_static/gumroad-product-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 = { "categoryUrls": [
        "https://discover.gumroad.com/design",
        "https://discover.gumroad.com/software-development",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("midnight_static/gumroad-product-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 '{
  "categoryUrls": [
    "https://discover.gumroad.com/design",
    "https://discover.gumroad.com/software-development"
  ]
}' |
apify call midnight_static/gumroad-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,midnight_static/gumroad-product-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/OzYODkejgTVfRSLcr/builds/ks8PJLvo0ju46fyDN/openapi.json
