# Fourthwall Scraper \[$2.80/1K💰] | Creator Storefronts (`ahmed_jasarevic/fourthwall-scraper`) Actor

Extract Fourthwall creator storefronts — profile, bio, socials, membership tiers, contact email and full product catalog. Discover creator shops automatically. Pay per storefront or product.

- **URL**: https://apify.com/ahmed_jasarevic/fourthwall-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 storefronts

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

## Fourthwall Scraper — Creator Storefront Profiles, Products and Contact Data

Extract **Fourthwall creator storefront data** — profile, bio, social links, membership tiers, members-only video catalog, publicly listed contact email, and a flat row for every product the shop sells.

Point it at creator URLs, or let it **discover storefronts from Fourthwall's public showcase pages**. Built for agencies running influencer-outreach campaigns, creator-economy researchers, merch sourcing teams, and anyone who needs to **qualify a creator's business before reaching out**.

***

### Why use this Actor instead of the Fourthwall Storefront API?

**Because the Storefront API cannot be used against someone else's shop.** Fourthwall's Storefront API (`storefront-api.fourthwall.com`) requires a per-shop `storefront_token`, which is only visible to the shop's own owner under Settings → For Developers. It is **not exposed in the served HTML or JavaScript**, and calling it without one returns `HTTP 401 {"code":"NotAuthorizedError"}`.

So if you want a competitor's catalog — for pricing research, merch arbitrage, or catalog monitoring — the public API is a dead end. This Actor reads the storefront's **own server-rendered HTML** instead, which carries the same data without any token.

This is the gap the other Fourthwall scrapers leave open: they return **products only**. This Actor returns the **storefront itself** — handle, display name, bio, avatar, social links, membership tiers with prices and member counts, posts, videos, and the contact email the creator published on their own store.

### Main use cases

- **Influencer outreach and lead qualification** — membership tier count, member counts, catalog size and a public contact email are strong signals of a creator's commercial scale
- **Creator-economy market mapping** — discover Fourthwall storefronts from the showcase pages and profile them at scale
- **Merch price monitoring** — product price, compare-at price and availability across a roster of creator stores
- **Catalog and assortment tracking** — which SKUs a creator lists, at what price, with what variants
- **Membership-program research** — tier names, prices, billing periods, feature lists and member counts
- **Sponsorship and brand-safety checks** — social links, external links and public contact details before you pitch

***

### Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `startUrls` | array | no | 2 example storefronts | Fourthwall storefront URLs. Full URLs (`https://disguisedtoast.shop`) or bare domains (`disguisedtoast.shop`). One Storefronts row each. |
| `discoverStorefronts` | boolean | no | `true` | Crawls Fourthwall's public showcase pages and mines real creator storefront URLs to add to the queue. Set `false` to use only your own list. |
| `discoveryUrls` | array | no | `fourthwall.com/get-inspired`, `fourthwall.com/creators` | Custom pages to mine for storefront links. Only used when discovery is on. |
| `maxStorefronts` | integer | no | `20` | Maximum storefronts fully profiled in one run (1–200). |
| `maxProductsPerStorefront` | integer | no | `0` | `0` = cheapest (name/price/URL/image/availability from one collection page). Values `> 0` open that many product pages to add descriptions, SKUs, brands and variant pricing. |
| `includeProducts` | boolean | no | `true` | Scrape the product catalog into the Products dataset. Off = cheapest run, full profile still returned. |
| `includeMembersOnlyContent` | boolean | no | `true` | For shops that sell tiers, also scrape supporter posts and the members-only video catalog. Costs 2 extra requests, and only for shops that actually have tiers. |
| `maxRequestsPerCrawl` | integer | no | `400` | Hard HTTP request cap (10–2000). Storefronts cut off by this cap are still pushed, flagged `partial: true`. |
| `proxy` | object | no | `useApifyProxy: false` | Standard Apify proxy picker. Not needed for normal runs — storefront pages carry no anti-bot challenge. |

#### Examples

```json
{
  "startUrls": [
    { "url": "https://disguisedtoast.shop" },
    { "url": "https://asmrxbabee.com" }
  ],
  "discoverStorefronts": false,
  "maxStorefronts": 2,
  "includeProducts": true,
  "maxProductsPerStorefront": 0
}
```

Cheapest possible prospecting run — profiles and contact emails only:

```json
{
  "startUrls": [{ "url": "https://disguisedtoast.shop" }],
  "includeProducts": false,
  "discoverStorefronts": false
}
```

Deep catalog + membership research:

```json
{
  "startUrls": [{ "url": "https://disguisedtoast.shop" }],
  "maxProductsPerStorefront": 25,
  "includeMembersOnlyContent": true,
  "maxRequestsPerCrawl": 800
}
```

Discover 50 creator stores from Fourthwall's showcase pages:

```json
{
  "startUrls": [],
  "discoverStorefronts": true,
  "maxStorefronts": 50,
  "includeProducts": false
}
```

***

### Output

Two datasets, both switchable in the **Output** tab.

#### Storefronts

| Field | Description |
|---|---|
| `handle` | Storefront domain / handle |
| `shopId` | Fourthwall internal shop id — **the join key to Products** |
| `displayName` | Creator or brand name (JSON-LD `Organization.name`) |
| `bio` | Store description |
| `avatar` / `logo` | Profile image URLs |
| `storefrontUrl` | Canonical storefront URL |
| `contactEmail` | Publicly listed contact email, or `null` |
| `socialLinks` | All `sameAs` / footer social URLs |
| `socialHandles` | Map of network → handle |
| `externalLinks` | Non-social outbound links |
| `currency` | Storefront currency, or `null` when only a symbol is printed |
| `memberships[]` | `name`, `price`, `currency`, `billingPeriod`, `membersCount`, `features`, `checkoutUrl` |
| `membershipsCount` / `hasMemberships` | Tier count and flag |
| `posts[]` / `postsCount` | Supporter posts (title, thumbnail, access tier, publish time) |
| `videos[]` / `videosCount` | Video catalog (title, thumbnail, duration, access) |
| `productsCount` | Products found — the row count for that shop in the Products dataset |
| `collections` / `pages` | Full inventory from `sitemap.xml` |
| `partial` | `true` when the row may be incomplete (page cut off by the request cap, request failed, or run aborted mid-storefront) |
| `scrapedAt` | ISO timestamp |

#### Products

| Field | Description |
|---|---|
| `shopId` / `handle` / `displayName` / `storefrontUrl` | Denormalized storefront keys, so the dataset stands alone or joins back |
| `name` / `slug` / `url` | Product identity and canonical URL |
| `price` / `compareAtPrice` | Current price and struck-through price when on sale |
| `currency` | ISO 4217 code, or `null` when the store prints a symbol only |
| `available` | In-stock flag, `null` when the storefront does not say |
| `image` | Primary product image |
| `sku` / `brand` | Only populated when `maxProductsPerStorefront > 0` |
| `description` / `variants[]` | Only populated when `maxProductsPerStorefront > 0` |

#### Why `partial` matters

A storefront row is pushed as soon as its own pages finish, then the profile is dropped from memory — that keeps memory flat on long runs. The trade-off is that an aborted run never loses what it already collected, but anything still in flight lands with `partial: true` rather than being silently dropped. Filter on `partial == false` when you need rows guaranteed complete. Compare `productsCount` against the Products dataset to judge a store's worth before trusting its catalog.

***

### Example output

Storefronts row:

```json
{
  "platform": "fourthwall",
  "handle": "disguisedtoast.shop",
  "shopId": "sh_8b0b2562-9c11-4357-a37e-4e28c7d93601",
  "displayName": "Disguised Toast",
  "bio": "The official store of Disguised Toast",
  "avatar": "https://imgproxy.fourthwall.dev/...",
  "storefrontUrl": "https://disguisedtoast.shop",
  "contactEmail": "store@offlinetv.com",
  "socialLinks": [
    "https://youtube.com/channel/UCUT8RoNBTJvwW1iErP6-b-A",
    "https://twitch.tv/disguisedtoast",
    "https://instagram.com/disguisedtoast"
  ],
  "hasMemberships": false,
  "membershipsCount": 0,
  "memberships": [],
  "productsCount": 6,
  "postsCount": 0,
  "videosCount": 0,
  "collections": ["all", "hoodie", "jacket"],
  "partial": false,
  "scrapedAt": "2026-09-29T10:00:00.000Z"
}
```

Products row:

```json
{
  "shopId": "sh_8b0b2562-9c11-4357-a37e-4e28c7d93601",
  "handle": "disguisedtoast.shop",
  "displayName": "Disguised Toast",
  "storefrontUrl": "https://disguisedtoast.shop",
  "name": "Signature Hoodie",
  "slug": "signature-hoodie",
  "url": "https://disguisedtoast.shop/products/signature-hoodie",
  "price": 125,
  "compareAtPrice": null,
  "currency": null,
  "available": null,
  "image": "https://imgproxy.fourthwall.dev/...",
  "sku": null,
  "variants": []
}
```

***

### Track creator merch pricing and storefront changes on a schedule

Every Apify Actor is callable over HTTP, so the useful pattern is a recurring run over the same storefront list:

- **Weekly** — same storefronts; diff `price` and `compareAtPrice` to catch creator merch markdowns and drops
- **Monthly** — same roster; diff `memberships[]` and `productsCount` to spot new tiers and assortment changes
- **Quarterly** — refresh outreach lists; `contactEmail` and `socialLinks` change when creators rebrand
- **Wire into your stack** — Apify webhooks, Zapier, Make, Google Sheets and 100+ integrations fire on run completion; both datasets export as JSON, CSV, Excel, XML, HTML or RSS

Set `includeProducts: false` on the outreach schedule and `true` on the pricing schedule — they're cheap to split.

***

### Related Actors

- [Stan.store Scraper](https://apify.com/ahmed_jasarevic/stan-store-creator-scraper) (`ahmed_jasarevic/stan-store-creator-scraper`) — the closest sibling: creator storefront profiles and product data on a different creator-commerce platform
- [Gumroad Scraper](https://apify.com/ahmed_jasarevic/gumroad-scraper) (`ahmed_jasarevic/gumroad-scraper`) — creator digital product catalogs, sales and pricing
- [Fourthwall Creator Shop Scraper](https://apify.com/vsekar91/fourthwall-creator-scraper) (`vsekar91/fourthwall-creator-scraper`) — product-level extraction with size/colour variants, no storefront profile
- [Fourthwall Shop Scraper](https://apify.com/scrapersdelight/fourthwall-shop-scraper) (`scrapersdelight/fourthwall-shop-scraper`) — products, prices and stock alerts only
- [Shopify Product Scraper](https://apify.com/ahmed_jasarevic/shopify-product-scraper) (`ahmed_jasarevic/shopify-product-scraper`) — the same storefront data model on self-hosted Shopify

***

### FAQ

#### Why not just use the Fourthwall API?

You can — but only for **your own shop**. The Storefront API authorises every request with a `storefront_token` that only the shop owner can see. For your own store you should absolutely use the official API. To read a **competitor's or another creator's** storefront, there is no token and no public API path, so this Actor reads the server-rendered HTML instead.

#### What are the alternatives to this Actor?

- **The official Storefront API** — best choice for your own shop; returns nothing for anyone else's.
- **Product-only Fourthwall scrapers** — cheaper per row and good for price tracking, but they give you no profile, no tiers, no social links and no contact email, which is exactly what you need for outreach.
- **Manual copying** — fine for 5 shops, unusable at 200.

#### How do I join the two datasets?

On **`shopId`**. It is Fourthwall's internal shop identifier and stays stable even if the creator changes their domain, which makes it a better key than `handle`.

#### Why is `contactEmail` null for so many creators?

Because they never published one. This Actor returns only addresses the creator has put on their own storefront — contact page, privacy policy or terms page — and applies junk filtering to strip CDN and error-reporting addresses. It never guesses or infers an address.

#### Why is `currency` null?

Most storefronts print a symbol (`$`, `£`) rather than an ISO code. The Actor reports `null` rather than guessing the country, so you don't silently mis-assign USD to a GBP store.

#### Does it need a browser or a proxy?

Neither. Fourthwall storefronts are server-rendered, so there is no JavaScript execution required and no Cloudflare or other bot challenge on storefront pages. The default run uses no proxy and 512 MB; the standard proxy input is exposed for high-volume runs.

#### Can I abort a long run safely?

Yes. On a graceful abort the Actor stops crawling, pushes everything it has and exits. Storefronts still in flight land with `partial: true`, so nothing is silently lost, and rows pushed before the abort are untouched.

***

### For AI Agents & LLM Apps

Callable via the Apify MCP server and the Apify API. Returns creator storefront profiles in the default dataset and products in the `products` dataset, joined on `shopId`.

**Minimal valid input** — two storefronts, profile + cheap catalog:

```json
{ "startUrls": [{ "url": "https://disguisedtoast.shop" }], "discoverStorefronts": false }
```

**Cheapest prospecting run** — profile, tiers and contact email, no product rows:

```json
{
  "startUrls": [{ "url": "https://disguisedtoast.shop" }],
  "includeProducts": false,
  "discoverStorefronts": false
}
```

**Discovery mode** — mine Fourthwall's showcase pages for real creator storefronts:

```json
{ "startUrls": [], "discoverStorefronts": true, "maxStorefronts": 50, "includeProducts": false }
```

**Output fields** — storefronts: `handle`, `shopId`, `displayName`, `bio`, `avatar`, `logo`, `storefrontUrl`, `contactEmail`, `socialLinks`, `socialHandles`, `externalLinks`, `currency`, `memberships`, `membershipsCount`, `hasMemberships`, `posts`, `postsCount`, `videos`, `videosCount`, `productsCount`, `collections`, `pages`, `partial`, `scrapedAt`, `platform`. Products: `shopId`, `handle`, `displayName`, `storefrontUrl`, `name`, `slug`, `url`, `price`, `compareAtPrice`, `currency`, `available`, `image`, `sku`, `brand`, `description`, `variants`.

**Behaviors an agent should know**

- **`discoverStorefronts` defaults to `true`.** If you supply your own `startUrls` and do not want the showcase crawl adding other shops, set it to `false` explicitly.
- **`maxProductsPerStorefront` defaults to `0`**, which means "all products from the collection page" — not "no products". A value `> 0` is what switches on per-product-page enrichment (descriptions, SKUs, brand, variant pricing).
- **Two separate billing events.** `includeProducts: false` removes the `product` event but keeps the `storefront` event. `includeMembersOnlyContent: false` removes the `members-only-content` event.
- **`sku`, `brand`, `description` and `variants` are only populated when `maxProductsPerStorefront > 0`.** Do not assume they exist on a default run.
- **`shopId` is the join key**, not `handle` — the handle changes if the domain does, the shopId does not.
- **`partial: true` means the row may be incomplete**, not that the scrape failed. Filter `partial == false` for guaranteed-complete rows.
- **Three separate datasets/views exist** — Storefronts and Products are separate storages; each exposes `overview` and `pricing` views.

**Billing model** — pay per event: `storefront` ($0.0028–$0.003 per profile), `product` ($0.0009–$0.001 per product row), and `members-only-content` ($0.005 **once per storefront** that has posts or videos, not per item), plus a per-run Actor Start event scaled by memory.

***

### Legal & Compliance Disclaimer

This Actor is an independent third-party tool. It is not affiliated with, endorsed by, sponsored by, or connected with Fourthwall, Inc.

It reads **only publicly accessible storefront pages** — the shop root, `/collections/all`, individual product pages, `sitemap.xml`, `/supporters`, `/supporters/videos`, and public contact/terms/privacy pages. It does not log in, does not bypass authentication, does not use the Fourthwall Storefront API or any `storefront_token`, does not solve CAPTCHAs, and does not use proxies by default.

Output includes **publicly published contact email addresses and social links** for creators. That is business contact information the creator chose to publish on their own storefront, but you remain responsible for your own lawful basis for processing it and for complying with Fourthwall's Terms of Service and applicable law — including GDPR, UK GDPR, CCPA, and unsolicited-outreach rules such as CAN-SPAM and TCPA. Do not use harvested contact details for cold outreach without checking your legal basis.

Product and brand data scraped from a retailer may also be subject to contractual or rights restrictions even when publicly viewable — check Fourthwall's Terms of Service before large-scale collection, redistribution or resale.

This Actor is a data-collection tool; it does not provide legal advice and makes no claim that any particular use is permitted.

***

### SEO Keywords

fourthwall scraper, creator storefront data, influencer outreach data, creator economy analytics, merch store scraping, fourthwall api alternative, creator shop data, membership tier data, merch price monitoring, influencer lead generation, youtube merch scraper, twitch creator store, creator catalog data, storefront contact email, influencer qualification, creator sponsorship research, ecommerce catalog scraping, print on demand data, creator brand research, merch assortment tracking, shopify competitor data, creator storefront discovery

# Actor input Schema

## `startUrls` (type: `array`):

Fourthwall creator storefronts to scrape. Accepts full URLs (e.g. https://disguisedtoast.shop, https://shop.fourthwall.com) or bare handles/domains (e.g. disguisedtoast.shop). Each storefront produces one row in the Storefronts dataset with its profile, tiers and contact email.

## `discoverStorefronts` (type: `boolean`):

If true, crawls Fourthwall's public showcase pages (fourthwall.com/get-inspired and fourthwall.com/creators) and mines them for real creator storefront URLs to add to the queue. Set to false to only scrape the URLs you supplied.

## `discoveryUrls` (type: `array`):

Additional pages (e.g. a list page or blog post) to mine for Fourthwall storefront links. Only used when 'Discover storefronts from Fourthwall showcase pages' is enabled.

## `maxStorefronts` (type: `integer`):

Maximum number of creator storefronts to fully profile in one run.

## `maxProductsPerStorefront` (type: `integer`):

Cap on products extracted per storefront. Product name/price/URL come from the storefront's /collections/all page (1 request). Values > 0 additionally open that many individual product pages to enrich descriptions, SKUs, brands and variant-level pricing. Use 0 for the cheapest run.

## `includeProducts` (type: `boolean`):

Scrape the storefront product catalog (name, price, availability, image) into the separate Products dataset. Costs one extra request per storefront. Turn off for the cheapest run, which still returns the full profile, tiers and contact email.

## `includeMembersOnlyContent` (type: `boolean`):

For storefronts that sell membership tiers, also scrape the supporter posts and the members-only video catalog. Costs 2 extra requests, and only for stores that actually have tiers. Posts and videos are attached to the storefront row.

## `maxRequestsPerCrawl` (type: `integer`):

Hard safety cap on total HTTP requests for this run. Storefronts whose child pages were cut off by this cap are still pushed, flagged with `partial: true`.

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://disguisedtoast.shop"
    },
    {
      "url": "https://asmrxbabee.com"
    }
  ],
  "discoverStorefronts": true,
  "discoveryUrls": [
    {
      "url": "https://fourthwall.com/get-inspired"
    },
    {
      "url": "https://fourthwall.com/creators"
    }
  ],
  "maxStorefronts": 20,
  "maxProductsPerStorefront": 0,
  "includeProducts": true,
  "includeMembersOnlyContent": true,
  "maxRequestsPerCrawl": 400,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `storefronts` (type: `string`):

One row per creator storefront: profile, bio, social links, public contact email, membership tiers and counts of products, posts and videos.

## `products` (type: `string`):

One row per product: name, price, compare-at price, currency, availability, image, SKU, brand and variants. Carries shopId, handle and storefrontUrl so it joins back to the storefronts dataset.

# 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 = {
    "startUrls": [
        {
            "url": "https://disguisedtoast.shop"
        },
        {
            "url": "https://asmrxbabee.com"
        }
    ],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/fourthwall-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 = {
    "startUrls": [
        { "url": "https://disguisedtoast.shop" },
        { "url": "https://asmrxbabee.com" },
    ],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/fourthwall-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 '{
  "startUrls": [
    {
      "url": "https://disguisedtoast.shop"
    },
    {
      "url": "https://asmrxbabee.com"
    }
  ],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/fourthwall-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/fourthwall-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/1Z3vPcCp6oDXln94Z/builds/gQ4iJyKYpHr0xMPNC/openapi.json
