# Marketplace Signal (`bessuraba/marketplace-signal`) Actor

Scrape Framer Marketplace and ThemeForest to compare templates across both. Deterministic opportunity grades, category density, price benchmarks, and cross-marketplace signals — no AI — for niche selection, pricing calibration, and deciding where to sell.

- **URL**: https://apify.com/bessuraba/marketplace-signal.md
- **Developed by:** [Slawa Warda](https://apify.com/bessuraba) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Cross-marketplace intelligence for design/code template sellers — for creative solos and small
agencies selling templates, components, plugins, and UI kits on **Framer Marketplace** and
**ThemeForest**. Scrapes both, then grades every listing deterministically (no AI): category
density, pricing benchmarks, and cross-marketplace comparison — not just what's in a marketplace,
but how it stacks up against the other one.

### Disclaimer

- **Not affiliated.** This is an independent, unofficial tool. It is not affiliated with, endorsed
  by, or sponsored by Framer or Envato/ThemeForest.
- **Data accuracy.** Framer and ThemeForest can change their site structure, categories, or listed
  prices at any time without notice, which can make scraped fields incomplete or stale until this
  Actor is updated to match. Verify time-sensitive figures (price, availability) against the source
  before acting on them.
- **Intended use.** Built for research, monitoring, and competitive/market analysis at reasonable
  scale — not for bulk resale or republishing of the underlying marketplace data. Compliance with
  Framer's and Envato's own Terms of Service for your specific use case is your responsibility.

### What can marketplace-signal do?

- **Niche selection**: see how crowded a category actually is — item count and density
  (low/medium/high) for the exact category you're considering, on both marketplaces.
- **Pricing calibration**: real median price, price percentile, and above/below/at-median flag per
  listing — not guesswork.
- **Deciding where to sell**: the only tool that compares the *same* niche across Framer and
  ThemeForest side by side — item count and median price per marketplace, for the same vertical.
- **Competitor research**: pull every listing in a category with pricing, description, and
  engagement signal in one dataset.
- **Opportunity scoring**: every listing gets a deterministic A-F grade and a fast `enter` /
  `monitor` / `avoid` triage label — no AI, no black box, just item-count math you can verify.

See the **Input** and **Pricing** tabs above for exact fields and cost — kept out of this README
since Apify generates both natively from this Actor's real configuration, always in sync.

### FAQ

**Is this affiliated with Framer or ThemeForest?** No — see Disclaimer above.

**Is scraping Framer and ThemeForest legal?** Both are scraped unauthenticated, public-page data
only — no login, no bypassing access controls. This project did its own legal-risk review before
publishing; see [`docs/legal/legal-risk-assessment.md`](./docs/legal/legal-risk-assessment.md) for
the full analysis. Not legal advice — your own use case is your own responsibility.

**Does this work for ThemeForest too, or just Framer?** Both, and that's the point — run `source: ["framer", "themeforest"]` together to get the cross-marketplace comparison (`crossMarketSignal`)
that neither marketplace's own tools, nor any other scraper found, provides.

**Why no seller/creator name in the output?** Out of scope for a market-signal tool — this Actor
reports on categories and pricing, not individual sellers.

# Actor input Schema

## `source` (type: `array`):

Which marketplace site(s) to run — named after the site itself, not its parent company. Leave empty to run the default, 'Framer Marketplace' only. 'ThemeForest' is implemented but not run by default — Envato (its operator)'s Acceptable Use Policy bans scraping outright (see docs/legal/legal-risk-assessment.md), so it must be named explicitly to opt in. An unknown value errors rather than silently falling back to "run everything".

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

A shared vocabulary across sources — never a source's own name, that's what `source` is for. Meaning and validity are still source-specific: Framer accepts "template"/"plugin"/"component" (its three marketplace sections, defaults to "template"; verified live 2026-09-07: framer.com/marketplace/{templates,plugins,components}/ are all real, distinct sections). ThemeForest accepts "template"/"theme" (its site-templates vs. WordPress-themes category trees, defaults to "template"; verified live 2026-09-07: themeforest.net/category/{site-templates,wordpress} are both real). "template" is valid for both at once — that's intentional overlap, not a collision, since `type` is always read together with `source`. Leave empty to use each requested source's own default; an explicit value invalid for that source errors rather than silently falling back.

## `category` (type: `string`):

Filter by category — taxonomy differs per source, not a shared list. The dropdown below is every known-real category across both sources, combined (Framer's 49/6/6 template/plugin/component slugs plus ThemeForest's 8/7 template/theme subcategory slugs) — pick one, or type your own: neither list is proven exhaustive (Framer's own API confirms real categories exist outside its scraped list, e.g. "coaching", "startup", "non-profit"; ThemeForest's nav undercounted its own page's tile data the same way), so this is suggestions, not a closed set — see README's Category taxonomy section for which values belong to which source/type. Leave empty to scrape the unfiltered root/taxonomy.

## `search` (type: `string`):

Filters results by title. Applied client-side against rendered-page results; if the internal API fallback kicks in, it also runs as real server-side search there. Not supported for ThemeForest yet (v1 is category-browsing only) — set for that source is ignored with a warning.

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

Result ordering, matching Framer's own "Latest"/"Trending" toggle. Verified live 2026-09-07 on both the rendered page and the internal API: 'popular' reorders results to match the site's "Trending" tab. Not applied when 'search' is set — untested in combination with search relevance ranking.

## `priceFilter` (type: `string`):

Filter to free-only or paid-only items. Client-side only — verified live 2026-09-07 that Framer's internal API silently ignores both `isFree` and `sort=price` params, so there is no real server-side equivalent to ask for. Applied after price is known, before an item counts toward maxResults, so a narrow filter on a mostly-opposite category can return fewer than maxResults.

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

Maximum number of items to scrape and output. Framer: rendered pages alone cap out around ~24-30 per category/search, the internal API fills the rest automatically. ThemeForest: capped at whatever one category page naturally contains (~40, ~126 seen on the WordPress-themes root) — v1 doesn't paginate, so a higher value is a no-op past that.

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

Apify Proxy settings, used as-is for Framer's requests. ThemeForest defaults to the RESIDENTIAL group instead (Cloudflare blocks datacenter IPs much harder) unless you set this field, in which case your choice is used for both sources.

## Actor input object example

```json
{
  "source": [],
  "search": "saas",
  "sort": "newest",
  "priceFilter": "all",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (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 = {
    "search": "saas",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bessuraba/marketplace-signal").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 = {
    "search": "saas",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("bessuraba/marketplace-signal").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 '{
  "search": "saas",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call bessuraba/marketplace-signal --silent --output-dataset

```

## MCP server setup

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

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/pBkqjGnJ8PCtokG9M/builds/KYv4h3oavY77HVkIz/openapi.json
