# Gumroad Scraper and API: Products, Prices, Sales & Reviews (`usefulapi/gumroad-discover`) Actor

Scrape Gumroad products by keyword, tag, category or store, past the 10,000-result limit: USD prices, ratings, sales count, reviews without names. From USD 1.50 per 1,000.

- **URL**: https://apify.com/usefulapi/gumroad-discover.md
- **Developed by:** [Useful API](https://apify.com/usefulapi) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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.

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 Scraper and API: products, prices, sales, reviews and stores

Scrape Gumroad products into a table, or call it as a Gumroad products API through Apify's API or MCP.

Turn Gumroad into a clean table: every product for a keyword, tag, category or store, with its price in the seller's
currency **and in US dollars**, ratings, product type and store. Add details for the creation date, the public sales
count, the 1 to 5 star breakdown and the price of every version; add reviews (without reviewer names). Each search also
gives a free niche report. Schedule it with a monitor name to get only new and changed products.

**Gets past Gumroad's 10,000-result limit.** Gumroad never shows more than 10,000 results for one search. When a search
holds more ("notion template": 19,713 on 17 Oct 2026), this scraper splits it into price bands by itself and reads each
one, so you get the whole niche. In our test it returned 19,713 of Gumroad's 19,713.

No API key, no login, no proxy, no personal data collected on purpose (store name and link only). From USD 1.50 per
1,000 products.

### Who it's for

- **Creators and indie hackers:** size a niche before you build: how many products, what they cost, how old they are,
  what sells, which tags and file types dominate.
- **Market researchers:** full category exports (Design, 3D, Software, Education...) for price and rating studies.
- **Competitor watchers:** a whole rival store, or a list of rival products, watched weekly: new launches, price changes,
  new ratings, sales count moves.
- **Product teams:** what buyers praise and complain about, from review text, without collecting who wrote it.
- **Developers and AI agents:** the same flat columns on every row, through the Apify API or MCP.

### Compared with other Gumroad scrapers on Apify (17 Oct 2026, from their own pages)

The three most used Gumroad scrapers on the Apify Store (22, 12 and 4 users in the last 30 days) as their own pages
describe them:

| | This scraper | The three most used |
|---|---|---|
| Price per 1,000 products | USD 1.50 | USD 2.00 to 10.00 (by plan tier); smaller tools from USD 0.72 |
| More than 10,000 products per search | Yes (price bands) | Not stated; one says 10,000 is its maximum |
| USD price for every product | Yes (Gumroad's own conversion) | One re-checks USD; others not stated |
| Stores, product links, categories, tags, keywords | All five | All five in one; the others two |
| Created date, sales count, star breakdown, version prices | Yes | Yes in one |
| Store rating and product count | Yes | Not stated |
| Reviews | Without reviewer names or photos | With reviewer names in one; none in the others |
| Niche report (Gumroad's totals, top tags, file types, price spread) | Free, in every run, no estimates | Estimated scores in one |
| Monitor new and changed products | Yes, with previous values | Yes in one |
| Contact emails or social handles of creators | Never | Sold as an extra in one |

### What you get for each product

| Group | Fields |
|---|---|
| **Product** | productId, permalink, name, url, productType (digital, course, ebook, membership, bundle, physical...), thumbnailUrl, descriptionSnippet (Gumroad's own short card text) |
| **Price** | price and currency (as the seller set it), **priceUsd** (Gumroad's own USD price), isPayWhatYouWant, recurrence, durationInMonths, quantityRemaining, isSalesLimited |
| **Ratings** | ratingCount, ratingAverage |
| **Store** | storeName, storeUrl, storeVerified; storeRatingAverage, storeRatingCount, storeProductCount (when the run read the store page: stores and product links) |
| **Where it was found** | searchType (query, tag, category, store, productUrl), search, sort, rank (Gumroad's position), priceBand (when a search was split; in the seller's currency, as Gumroad filters) |
| **Details** (option) | createdAt, updatedAt, salesCount (only when the seller shows it), rating1StarPercent to rating5StarPercent, summary, highlights, refundPolicy, refundPolicyDetails, suggestedPrice, variantCount, variants (name, price, priceUsd, quantityLeft, billing per period for tiered memberships), billingOptions, isRecurringBilling, isTieredMembership, isPhysical, hasFreeTrial, coverCount, detailsStatus |
| **Reviews** (option) | reviews (rating, text, date, sellerReply), reviewsStatus. Never the reviewer's name or photo |
| **Monitor** (option) | changeType (new, changed, unchanged), changedFields, previousPrice, previousRatingCount, previousRatingAverage, previousSalesCount |

#### Niche report (free, in the run's OUTPUT record)

For each search: Gumroad's own total number of products, the top tags and file types with their counts (as Gumroad
reports them), and the spread of the products collected: free products, lowest, median and highest USD price, median
paid price, products rated, total ratings, product types, and the total of the sales counts sellers show. For a store:
its rating, number of products and sections. No estimates: every number is Gumroad's or counted from the rows.

### Input

| Field | What it does |
|---|---|
| `searchQueries` | Keywords, one search each (`notion template`, `lightroom presets`) |
| `tags` | Gumroad tags, one search each (`procreate`, `vrchat`) |
| `categories` | Pick from Gumroad's 361 categories and sub-categories (`design`, `3d/vrchat`, `software-development`) |
| `storeUrls` | Stores (`https://<store>.gumroad.com` or the store name): every product on the store page |
| `productUrls` | Product links (`https://<store>.gumroad.com/l/<product>`), read in full with details |
| `sort` | featured, best_sellers (past year), most_reviewed, highest_rated, newest, hot_and_new (last 90 days), price_asc, price_desc |
| `maxResultsPerSearch` | Products per search (default 100, up to 100,000). Above 10,000 the search is split into price bands |
| `includeDetails` | Created and updated dates, sales count, star breakdown, version and billing prices, refund policy |
| `includeReviews`, `maxReviewsPerProduct` | Written reviews without names (default 10 per product, up to 100) |
| `minPrice`, `maxPrice`, `freeOnly` | Price range in USD. Gumroad filters on each seller's own currency; every row is re-checked on its USD price |
| `minRating`, `minReviews`, `fileTypes`, `staffPicksOnly` | Gumroad's own filters |
| `productTypes`, `payWhatYouWantOnly`, `verifiedStoresOnly` | Applied after each page is read: left-out products are not saved or billed |
| `monitorName`, `onlyNewOrChanged` | Watch a search over time; save only new and changed products (default on) |
| `dedupeAcrossSearches` | A product found by several searches is saved once (default on) |

#### Examples

The whole niche, past Gumroad's 10,000 limit:

```json
{ "searchQueries": ["notion template"], "maxResultsPerSearch": 100000 }
```

The 1,000 best sellers of a niche, with sales counts and creation dates:

```json
{ "searchQueries": ["notion template"], "sort": "best_sellers", "maxResultsPerSearch": 1000, "includeDetails": true }
```

A rival's whole store with its reviews:

```json
{ "storeUrls": ["productivesetups"], "includeDetails": true, "includeReviews": true, "maxReviewsPerProduct": 30 }
```

Weekly watch of new VRChat assets (schedule it):

```json
{ "categories": ["3d/vrchat"], "sort": "newest", "maxResultsPerSearch": 500, "monitorName": "vrchat-newest" }
```

Courses and bundles between USD 20 and 100:

```json
{ "searchQueries": ["notion template"], "productTypes": ["course", "bundle"], "minPrice": 20, "maxPrice": 100 }
```

### Sample row (with details)

```json
{
  "productId": "dvIiGQILR7jh2t4YAVxgPw==",
  "name": "Your ADHD Mynd - Notion Template (Recently Updated!)",
  "url": "https://notionforadhd.gumroad.com/l/youradhdmynd",
  "productType": "digital",
  "price": 45,
  "currency": "USD",
  "priceUsd": 45,
  "ratingCount": 9,
  "ratingAverage": 4.9,
  "storeName": "Braelyn | Mynd for ADHD",
  "storeUrl": "https://notionforadhd.gumroad.com",
  "createdAt": "2025-06-14T16:44:48Z",
  "salesCount": 648,
  "rating4StarPercent": 11,
  "rating5StarPercent": 89,
  "refundPolicy": "7-day money back guarantee",
  "detailsStatus": "ok"
}
```

### Pricing (pay per event)

| Event | Price |
|---|---|
| Product saved | USD 1.50 per 1,000 |
| Product details read (details option and product links) | USD 2.00 per 1,000 |
| Reviews page read (up to 10 reviews; empty pages free) | USD 0.001 each (USD 0.10 per 1,000 reviews) |
| Search page read (up to 100 products checked; also a store page or the category list) | USD 0.001 each (USD 0.01 per 1,000 products) |
| Run start | USD 0.005 |

1,000 products cost about USD 1.51; with details about USD 3.55 (with details the search reads pages of 20). Products a
filter leaves out are not billed; the pages read to find them are. A monitor run where nothing changed pays only its
search pages (and product details and review pages, if on). Set a maximum cost per run in Apify and the scraper stops before it, keeping
every row it saved.

### Good to know

- **Polite by design:** one request at a time, search pages at most one a second (100 products each), product data and
  reviews 2.5 seconds apart, Gumroad's robots.txt respected. Details and reviews are slower: about 3 seconds per product
  read (about 50 minutes per 1,000 products with details).
- **Past 10,000, order is by price band:** a search over 10,000 products is read band by band (cheapest first), with
  Gumroad's sort inside each band and `rank` empty. For the top N by a sort, keep `maxResultsPerSearch` at 10,000 or less.
- **Sales counts are public only when the seller shows them;** otherwise `salesCount` is empty. Nothing is estimated.
- **USD prices are Gumroad's own conversion** (the same as its currency picker), at its rate of the day. A few sellers
  keep their own currency on display; then `priceUsd` is empty (6 of 19,713 in the "notion template" test), never guessed.
  Version and billing prices in USD use the same rate as the product's main price.
- **Price bands can overlap:** a product with several prices (versions, pay what you want) can sit in two bands; it is
  saved once. If a single price point holds more than 10,000 products, the run reads the 10,000 Gumroad allows and says so.
- **Stores:** every product shown on the store page, section by section; a store can have products it does not show
  there (compare `storeProductCount`).
- **Reviews** come in Gumroad's own order (highest rated first). Star-only ratings have no text and are not returned.
  Review text and seller replies are kept as written (emails, phone numbers, @handles and links are removed); they can
  still contain personal details a buyer chose to write, so handle them as personal data.
- **Limits per run:** 50 searches (keywords, tags, categories and stores together), 5,000 product links, 100,000
  products per search, 100 reviews per product, 30 versions per product.
- **Monitor:** the first run of a name saves everything as `new`. Later runs compare price, currency, rating count,
  rating average, name and (with details on both runs) sales count. Up to 100,000 products are remembered per name.
- **No personal data collected on purpose:** store name and store link only. No emails, social handles, avatars, bios,
  reviewer names or photos, and no full product descriptions.

### FAQ

**Is there an official Gumroad API for this?** Gumroad's API covers your own seller account only, not other stores'
products. This scraper reads Gumroad's public Discover search, store pages, product data and review lists.

**Can I get every product in a category?** Yes, up to 100,000 per search: pick the category and set a high
`maxResultsPerSearch`; it is split into price bands automatically. The one exception: if a single price point (most
often free) holds more than 10,000 products, Gumroad shows only 10,000 of them, and the run report says so. On 17 Oct
2026 the named categories held up to about 62,000 products (Design 61,764, 3D 58,364, Music and Sound Design 55,510);
"Other" held 296,609, more than one search's 100,000 limit: split it with price ranges or several runs.

**Why does a row have no sales count?** The seller hides it. That is Gumroad's setting, not a scraping gap.

**Can it get creator emails or social profiles?** No, on purpose. It stays with product and store data.

### Disclaimer

Not affiliated with, endorsed by or sponsored by Gumroad, Inc. "Gumroad" is used only to describe what the tool reads.
It reads public pages only (no login, no checkout, no purchased content). You are responsible for how you use the data,
including Gumroad's terms and the laws that apply to you.

# Actor input Schema

## `searchQueries` (type: `array`):

Words to search on Gumroad Discover, one search each (for example: notion template, lightroom presets, procreate brushes).

## `tags` (type: `array`):

Gumroad tags, one search each (for example: notion, procreate, vrchat). Spaces and hyphens both work.

## `categories` (type: `array`):

Pick Gumroad categories (from gumroad.com/discover, 17 Oct 2026), one search each. A sub-category searches only that part (for example 3D > VRChat).

## `storeUrls` (type: `array`):

Gumroad stores (https://<store>.gumroad.com, or just the store name): every product shown on the store page, section by section. Store facts (rating, number of products) are added to each row.

## `productUrls` (type: `array`):

Gumroad product links (https://<store>.gumroad.com/l/<product>). Each one is read in full, with the detail fields.

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

Gumroad's own order for the search results.

## `maxResultsPerSearch` (type: `integer`):

How many products to collect for each keyword, tag or category (up to 100,000). Above 10,000 the run splits the search into price bands, because Gumroad itself never shows more than 10,000 results for one search; the bands are read cheapest first, so for the top N by a sort keep this at 10,000 or less.

## `includeDetails` (type: `boolean`):

Reads each product's public data for: created and updated dates, sales count (when the seller shows it), the 1 to 5 star breakdown, versions and billing options with prices, refund policy, highlights. Billed per product read. Slower than the search alone: about 3 s per product, one at a time (Gumroad limits the rate).

## `includeReviews` (type: `boolean`):

Adds each product's written reviews: star rating, text, date and the seller's public reply. Never the reviewer's name or photo. Billed per page of up to 10 reviews (pages with no written review are free).

## `maxReviewsPerProduct` (type: `integer`):

Gumroad lists reviews highest rated first, 10 per page.

## `minPrice` (type: `number`):

In US dollars. Gumroad filters on each seller's own currency; the run then re-checks every row on its USD price, so rows outside your range are skipped (not saved, not billed).

## `maxPrice` (type: `number`):

Use 0 for free products only.

## `minRating` (type: `integer`):

Only products rated at least this many stars on average.

## `minReviews` (type: `integer`):

Only products with at least this many ratings.

## `fileTypes` (type: `array`):

Only products that include these file types (for example: pdf, zip, mp4, psd, epub).

## `productTypes` (type: `array`):

Only these product types. Applied after reading each page (Gumroad's search has no such filter): left-out products are not saved or billed, but each page read is.

## `freeOnly` (type: `boolean`):

Same as Max price 0.

## `payWhatYouWantOnly` (type: `boolean`):

Only products where the buyer sets the price.

## `verifiedStoresOnly` (type: `boolean`):

Only products from stores Gumroad marks as verified.

## `staffPicksOnly` (type: `boolean`):

Only products Gumroad's staff picked (Gumroad's own filter).

## `monitorName` (type: `string`):

Give a name to watch a search over time (letters, digits, - and \_). Each row then says new, changed or unchanged since the last run with the same name, with the previous price, rating count and sales count. Schedule the same input daily or weekly.

## `onlyNewOrChanged` (type: `boolean`):

With a monitor name: skip unchanged products (they are checked but not saved or billed as rows). The first run of a name saves everything as new.

## `dedupeAcrossSearches` (type: `boolean`):

A product found by several of your searches is saved once (under the first search).

## Actor input object example

```json
{
  "searchQueries": [
    "notion template"
  ],
  "sort": "featured",
  "maxResultsPerSearch": 100,
  "includeDetails": false,
  "includeReviews": false,
  "maxReviewsPerProduct": 10,
  "freeOnly": false,
  "payWhatYouWantOnly": false,
  "verifiedStoresOnly": false,
  "staffPicksOnly": false,
  "onlyNewOrChanged": true,
  "dedupeAcrossSearches": true
}
```

# Actor output Schema

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

One row per product, same columns on every row. Download as CSV, Excel or JSON.

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

Per search: Gumroad's total, top tags and file types with counts, price and rating spread, price bands used, why the run stopped early (if it did).

# 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 = {
    "searchQueries": [
        "notion template"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("usefulapi/gumroad-discover").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 = { "searchQueries": ["notion template"] }

# Run the Actor and wait for it to finish
run = client.actor("usefulapi/gumroad-discover").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 '{
  "searchQueries": [
    "notion template"
  ]
}' |
apify call usefulapi/gumroad-discover --silent --output-dataset

```

## MCP server setup

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

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/lyC17KF5zO4tmHGTB/builds/o2moXLY3NPViphI4r/openapi.json
