# WordPress Themes Directory Scraper (`ninhothedev/wordpress-themes-scraper`) Actor

$0.5/1K 🔥 WordPress themes scraper! 8000+ themes with downloads, ratings, authors & screenshots. No key. JSON, CSV, Excel or API in seconds. Research the theme market ⚡

- **URL**: https://apify.com/ninhothedev/wordpress-themes-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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/platform/actors/running/actors-in-store#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

## WordPress Themes Directory Scraper

Scrape the **official WordPress.org theme directory** — 8,000+ free themes with download counts, star ratings, full ratings breakdowns, author profiles, tags, screenshots and direct `.zip` download links.

No API key. No login. No cookies. No proxy required. The actor talks directly to the free, public WordPress.org Themes API (v1.2) and returns one clean, flat dataset row per theme.

**~$0.50 per 1,000 themes.** A 200-theme run finishes in well under a minute on the 512 MB default.

***

### Themes ≠ plugins — how this differs from `wordpress-plugins-scraper`

This actor and [**WordPress Plugins Scraper**](https://apify.com/ninhothedev/wordpress-plugins-scraper) are **two separate scrapers hitting two separate WordPress.org directories**. They do not overlap:

| | **WordPress Themes Scraper** (this actor) | **WordPress Plugins Scraper** |
|---|---|---|
| Directory | `wordpress.org/themes` | `wordpress.org/plugins` |
| Catalog size | ~8,400 themes (popular listing), ~15,000 records incl. newest/updated | ~60,000+ plugins |
| API endpoint | `themes/info/1.2/` | `plugins/info/1.2/` |
| Unique fields | `screenshot_url`, `preview_url` (live wp-themes.com demo), `is_commercial`, `is_community`, theme feature tags (Block themes, Accessibility ready, RTL, Style variations…) | `active_installs`, `support_threads`, `support_threads_resolved`, `donate_link`, plugin contributors |
| Typical use | Design-market research, theme-shop competitor tracking, screenshot galleries | Plugin ecosystem research, install-base analysis |

**Use this actor when you care about design, look-and-feel, theme authors and screenshots. Use the plugins actor when you care about functionality and install counts.** Running both gives you a complete picture of the WordPress ecosystem.

***

### What you get

Every row is one theme:

```json
{
  "slug": "astra",
  "name": "Astra",
  "version": "4.13.7",
  "author_name": "Brainstorm Force",
  "author_username": "brainstormforce",
  "author_url": "https://wpastra.com/",
  "author_profile": "https://profiles.wordpress.org/brainstormforce/",
  "description": "Astra is fast, fully customizable & beautiful WordPress theme…",
  "rating": 98,
  "rating_stars": 4.9,
  "num_ratings": 6498,
  "ratings_breakdown": { "1": 84, "2": 12, "3": 15, "4": 55, "5": 6332 },
  "downloaded": 25013585,
  "last_updated": "2026-05-27",
  "creation_time": "2017-05-30T15:45:06Z",
  "requires_wp": "6.2",
  "requires_php": "7.4",
  "is_commercial": true,
  "is_community": false,
  "tags": ["Blog", "Custom colors", "E-commerce", "RTL language support", "Two columns"],
  "tag_slugs": ["blog", "custom-colors", "e-commerce", "rtl-language-support", "two-columns"],
  "tag_count": 19,
  "homepage": "https://wpastra.com/",
  "preview_url": "https://wp-themes.com/astra/",
  "screenshot_url": "https://ts.w.org/wp-content/themes/astra/screenshot.jpg?ver=4.13.7",
  "download_link": "https://downloads.wordpress.org/theme/astra.4.13.7.zip",
  "reviews_url": "https://wordpress.org/support/theme/astra/reviews/",
  "url": "https://wordpress.org/themes/astra/",
  "source": "wordpress.org",
  "scraped_at": "2026-07-28T18:02:11Z"
}
```

#### Field notes

- **`rating` is 0–100** (that is how WordPress.org returns it). `rating_stars` is the convenient 0–5 value, rounded to one decimal.
- **`ratings_breakdown`** gives you the raw review distribution `{"1": n … "5": n}` — enough to spot themes with a polarised 1★/5★ split.
- **`tags` vs `tag_slugs`** — the API returns tags as a `{slug: label}` map. You get both: human-readable labels and machine-friendly slugs.
- **`screenshot_url`** is normalised to `https://` (the API returns protocol-relative `//ts.w.org/...` URLs that break in most tools).
- **`author_name`** works for both author shapes the API emits (structured object on modern records, plain string on legacy ones).
- **`download_link`** points at the current `.zip` on downloads.wordpress.org.
- All fields are nullable — the dataset schema is permissive, so nothing breaks on partial records.

***

### Modes

#### `browse` — walk the directory

Pick a listing and page through it.

| `browse` | What it returns |
|---|---|
| `popular` | Most-installed themes, ~8,400 records |
| `featured` | WordPress.org editor picks (15 themes) |
| `new` | Newest submissions, ~15,000 records |
| `updated` | Most recently updated themes |

```json
{ "mode": "browse", "browse": "popular", "maxItems": 500 }
```

#### `search` — keyword queries

Each query is paged separately; results are de-duplicated by slug.

```json
{ "mode": "search", "queries": ["ecommerce", "portfolio", "magazine"], "maxItems": 300 }
```

#### `slugs` — specific themes

Fetch exact themes by their wordpress.org slug.

```json
{ "mode": "slugs", "slugs": ["astra", "hello-elementor", "kadence", "generatepress"] }
```

#### Tag filter

Combine any mode with a `tag` to narrow the field — e.g. `blog`, `e-commerce`, `portfolio`, `full-site-editing`, `accessibility-ready`, `dark`, `news`.

```json
{ "mode": "browse", "browse": "popular", "tag": "e-commerce", "maxItems": 1000 }
```

***

### Input reference

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `browse` | `browse`, `search` or `slugs` |
| `browse` | select | `popular` | `popular`, `featured`, `new`, `updated` |
| `queries` | array | `[]` | Search keywords (mode `search`) |
| `slugs` | array | `[]` | Exact theme slugs (mode `slugs`) |
| `tag` | string | — | Optional theme tag slug filter |
| `maxItems` | integer | `200` | Cap on total themes pushed (max 5,000) |

***

### Use cases

**Theme market research.** Pull the full popular listing with downloads, ratings and creation dates, then rank categories by demand. Which tags are saturated? Which tag combinations have high download volume but few high-rated options? `ratings_breakdown` shows you where users are actively unhappy — that gap is a product brief.

**WordPress agency prospecting.** `author_username`, `author_profile` and `author_url` give you a direct line to every theme shop on the directory. Filter by `is_commercial: true` to find authors already monetising (they have budget), or by high `downloaded` with a stale `last_updated` to find popular themes that need maintenance help. Feed the list straight into your CRM.

**Trend analysis.** `creation_time` plus `tag_slugs` lets you chart the rise of block themes and full-site editing against classic themes over time. Track `requires_wp` and `requires_php` across the catalog to see how fast the ecosystem adopts new WordPress and PHP baselines — useful for deciding your own minimum-version policy.

**Competitor tracking.** Schedule a daily `slugs` run over your competitors' themes and diff the dataset: version bumps, download deltas, new 1★ reviews and rating shifts all become time-series data. Pair it with the plugins scraper to watch a competitor's whole WordPress footprint.

***

### Output & exports

Results land in the Apify dataset and export to **JSON, CSV, Excel, XML, HTML or RSS** in one click, or via the Apify API. The dataset ships an **overview view** (theme name, downloads, star rating, last updated) for a readable table without touching the raw fields.

***

### Technical notes

- Async Python actor, batches of 50 records per API call.
- `curl_cffi` with a Chrome 124 TLS fingerprint, automatic `urllib` fallback — no third-party transport is required for the actor to work.
- Exponential backoff with jitter on transient failures; unknown slugs (HTTP 404) are logged and skipped rather than crashing the run.
- The run fails loudly with a clear message if zero themes were scraped, so an empty dataset never passes silently.
- Legal note: this actor reads a public, free, unauthenticated API published by WordPress.org for exactly this purpose. No personal data beyond public author display names and profile URLs is collected.

***

### Related actors by ninhothedev

- [WordPress Plugins Scraper](https://apify.com/ninhothedev/wordpress-plugins-scraper) — the plugin side of the WordPress ecosystem (60k+ plugins, active installs, support threads)
- [Product Hunt Scraper](https://apify.com/ninhothedev/producthunt-scraper) — daily launches, upvotes, makers
- [GitHub Repos Scraper](https://apify.com/ninhothedev/github-repos-scraper) — repository metadata, stars, topics
- [VS Code Marketplace Scraper](https://apify.com/ninhothedev/vscode-marketplace-scraper) — extension installs, ratings, publishers

***

### FAQ

**Do I need a WordPress.org account or API key?** No. The Themes API is completely open.

**How many themes can I get?** The `popular` listing exposes ~8,400 themes; `new` and `updated` expose ~15,000 records. `maxItems` caps at 5,000 per run — use multiple runs with different `browse` values or `tag` filters to cover more.

**Why is `rating` 98 and not 4.9?** WordPress.org returns ratings on a 0–100 scale. `rating_stars` (4.9) is provided for convenience.

**Are premium/commercial themes included?** Only themes listed in the free wordpress.org directory. Many of those are freemium — `is_commercial: true` flags themes with a paid upgrade path.

**Can I download the theme files?** `download_link` gives you the direct `.zip` URL for every theme; fetch it separately if you need the source.

### License

MIT

# Actor input Schema

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

How to pick themes. 'browse' walks a directory listing (popular/featured/new/updated), 'search' runs keyword queries, 'slugs' fetches specific themes by their wordpress.org slug.

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

Which directory listing to page through when mode is 'browse'. 'popular' = most installed, 'featured' = WordPress.org editor picks (15 themes), 'new' = newest submissions, 'updated' = most recently updated.

## `queries` (type: `array`):

Keywords to search the theme directory with when mode is 'search'. Each query is paged separately and results are de-duplicated by slug.

## `slugs` (type: `array`):

Exact wordpress.org theme slugs to fetch when mode is 'slugs' (the last URL segment of wordpress.org/themes/<slug>/, e.g. 'astra' or 'hello-elementor').

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

Optional theme tag slug to restrict results to, e.g. 'blog', 'e-commerce', 'portfolio', 'full-site-editing' or 'accessibility-ready'. Works with browse and search modes.

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

Maximum number of themes to push to the dataset across all queries. Themes are fetched in batches of 50.

## Actor input object example

```json
{
  "mode": "browse",
  "browse": "popular",
  "queries": [
    "ecommerce",
    "portfolio"
  ],
  "slugs": [],
  "tag": "blog",
  "maxItems": 200
}
```

# 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 = {
    "queries": [
        "ecommerce",
        "portfolio"
    ],
    "slugs": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/wordpress-themes-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 = {
    "queries": [
        "ecommerce",
        "portfolio",
    ],
    "slugs": [],
}

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/wordpress-themes-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "ecommerce",
    "portfolio"
  ],
  "slugs": []
}' |
apify call ninhothedev/wordpress-themes-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ninhothedev/wordpress-themes-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Gki1BQQUDggdUEk5V/builds/b9QTWcSpB2s9Irs7r/openapi.json
