# WordPress Plugin Intel: Abandoned Risk, Growth & Change Alerts (`signalloom/wordpress-plugin-intel`) Actor

WordPress.org plugin data from the official API: installs, ratings, support resolution, update recency, WP compatibility and 60-day download trends. Scores abandoned risk and growth with reasons, flags closed plugins, and alerts on version, rating or install changes.

- **URL**: https://apify.com/signalloom/wordpress-plugin-intel.md
- **Developed by:** [Signalloom](https://apify.com/signalloom) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 plugins

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

## WordPress Plugin Intel: Abandoned Risk, Growth & Change Alerts

Get **WordPress.org plugin data you can act on**: active installs, ratings, support resolution, update recency, WordPress compatibility and download trends, from the **official WordPress.org plugin API**. Every plugin gets an **abandoned-risk score** and a **growth signal**, each with plain-language reasons. Closed plugins are flagged with their closure date and reason. Turn on **only changes** and schedule it to get alerts when a competitor ships a version, gains installs or loses rating.

- **Look up plugins** by slug or URL, **search** the directory, list a **tag**, list an **author account's** plugins, or **browse** popular, new and recently updated plugins
- **Full plugin facts**: installs, rating and 1–5 star distribution, support threads resolved, last updated, added, tested-up-to vs the current WordPress version, required PHP and WordPress, total downloads, version, tags, contributors (WordPress.org usernames), homepage, paid/pro version where the plugin states one
- **Download trend** from WordPress.org's official stats: 7- and 30-day downloads and the change in median daily downloads
- **`abandonedRisk`** (0–100 + reasons): not updated for years, not tested with recent WordPress, unanswered support threads, closed
- **`growthSignal`**: growing, stable, declining or new, with the numbers behind it
- **Monitor mode**: remembers plugins between runs and outputs only what changed (version, installs, rating, number of ratings, tested-up-to), new plugins in your searches, and plugins that were closed

**Price: $0.003 per plugin** ($3 per 1,000). Slugs that don't exist are listed free. The prefilled example (5 slugs + one search, 15 plugins) finishes in about 10 seconds.

### Use this when…

- you're a **plugin developer tracking competitors**: watch their versions, installs, ratings and WordPress compatibility, with a weekly "what changed" list
- you're an **agency vetting plugins** before putting them on client sites: is it maintained, tested with current WordPress, answering support, closed for a security issue?
- you're **buying abandoned plugins**: find plugins with many installs that haven't been updated in years (filter on `abandonedRisk.score` and `activeInstalls`)
- you run **WordPress hosting or security**: check the plugins your customers use for closures, stale compatibility and dead support
- you want **market research** on a plugin niche (forms, backup, SEO…): who leads, who's growing, who's fading

### How to use it

1. Add **plugin slugs** (e.g. `contact-form-7`, or paste the plugin URL), and/or **search terms**, **tags**, **authors** (WordPress.org usernames such as `automattic`) or a **browse** list.
2. Set **Max plugins per search** (default 10, up to 1,000 per search, tag, author or list).
3. Optional filters for searches: **Minimum active installs** and **Minimum abandoned-risk score**. Slugs you list are always output.
4. For alerts: turn on **Only changes**, give the watch list a **Monitor ID**, and schedule the run. The first run is a baseline and outputs everything.

**Recipe: abandoned plugins worth acquiring.** Browse `popular` with Max plugins 1,000 and Minimum abandoned-risk score 60, and set Download history to 0 for speed. In our test (November 2026), this returned 39 plugins from the 1,000 most popular in about 6 seconds, each with 30,000+ active installs. Add Minimum active installs to narrow it down.

**Recipe: competitor watch.** Your competitors' slugs plus your niche's search term, Only changes on, Monitor ID `competitors`, scheduled weekly. Each run lists version bumps, install-bracket moves, rating changes and new plugins in your niche.

### Output

One record per plugin. Real examples from a run with the prefilled input:

```json
{
  "slug": "backuply",
  "name": "Backuply – Backup, Restore, Migrate and Clone",
  "url": "https://wordpress.org/plugins/backuply/",
  "status": "open",
  "closedOrRemoved": false,
  "version": "1.6.0",
  "activeInstalls": 600000,
  "downloaded": 7607723,
  "rating": 90,
  "ratingStars": 4.5,
  "numRatings": 135,
  "ratingDistribution": { "1": 13, "2": 3, "3": 0, "4": 1, "5": 118 },
  "supportThreads": 3,
  "supportThreadsResolved": 3,
  "supportResolvedPct": 100,
  "lastUpdated": "2026-10-22T13:19:00Z",
  "daysSinceUpdate": 21,
  "added": "2022-07-22",
  "testedUpTo": "7.1.4",
  "currentWpVersion": "7.1.4",
  "testedMajorsBehind": 0,
  "requiresWp": "4.7",
  "requiresPhp": "5.5",
  "requiresPlugins": [],
  "tags": ["backup", "cloud-backup", "database-backup", "restore", "wordpress-backup"],
  "authorUsername": "softaculous",
  "contributors": ["softaculous", "backuply"],
  "homepage": "http://wordpress.org/plugins/backuply/",
  "supportUrl": "https://wordpress.org/support/plugin/backuply/",
  "businessModel": null,
  "hasPaidVersion": true,
  "paidVersionBasis": "Description mentions \"Premium Features\"",
  "commercialSupportUrl": null,
  "shortDescription": "Backup, restores, and migration with Backuply are fairly simple with a wide range of storage options from Local Backups, FTP to cloud options like AWS …",
  "downloadsLast7Days": 14900,
  "downloadsLast30Days": 197730,
  "medianDailyDownloads": 2853,
  "downloadsTrendPct": -27.2,
  "abandonedRisk": { "score": 0, "level": "low", "reasons": [] },
  "growthSignal": {
    "label": "declining",
    "downloadsTrendPct": -27.2,
    "reasons": [
      "Median daily downloads, last 28 days: 2,852.5 vs 3,918.5 the 28 days before (-27.2%)",
      "Downloads include updates by existing sites, so this tracks activity of the install base as well as new installs"
    ]
  },
  "foundBy": ["search:backup"],
  "checkedAt": "2026-11-13T00:48:49.970Z"
}
```

An abandoned plugin from the same run (some fields left out here):

```json
{
  "slug": "limit-login-attempts",
  "name": "Limit Login Attempts",
  "status": "open",
  "version": "1.7.2",
  "activeInstalls": 200000,
  "ratingStars": 4.6,
  "numRatings": 202,
  "lastUpdated": "2023-04-04T19:15:00Z",
  "daysSinceUpdate": 1318,
  "testedUpTo": "6.2.15",
  "currentWpVersion": "7.1.4",
  "testedMajorsBehind": 9,
  "hasPaidVersion": null,
  "medianDailyDownloads": 266,
  "abandonedRisk": {
    "score": 70,
    "level": "high",
    "reasons": [
      "Not updated for 3+ years (last update 2023-04-04)",
      "Tested up to WordPress 6.2.15, 9 major releases behind 7.1.4"
    ]
  }
}
```

A closed plugin from the same run:

```json
{
  "slug": "display-widgets",
  "name": "Display Widgets",
  "url": "https://wordpress.org/plugins/display-widgets/",
  "status": "closed",
  "closedOrRemoved": true,
  "closedDate": "2021-01-30",
  "closedReason": "security-issue",
  "closedReasonText": "Security Issue",
  "closedNote": "This plugin has been closed as of January 30, 2021 and is not available for download. This closure is permanent. Reason: Security Issue.",
  "downloadsLast7Days": 65,
  "downloadsLast30Days": 225,
  "abandonedRisk": { "score": 100, "level": "high", "reasons": ["Closed on WordPress.org on 2021-01-30 (Security Issue)"] },
  "growthSignal": { "label": "closed", "downloadsTrendPct": null, "reasons": ["Closed on WordPress.org: not available for new installs"] },
  "foundBy": ["slug"],
  "checkedAt": "2026-11-13T00:48:49.970Z"
}
```

**Field notes**

- `activeInstalls` is WordPress.org's rounded bracket: `200000` means "200,000+".
- `rating` is 0–100 as the API gives it; `ratingStars` is the same on a 0–5 scale.
- `supportThreads` and `supportThreadsResolved` cover the **last two months**, as on the plugin's page.
- `testedMajorsBehind`: how many major WordPress releases (6.9 → 7.0 → 7.1…) separate the plugin's "tested up to" from the current version, read live from WordPress.org's version check. WordPress.org shows its own warning at 3.
- `hasPaidVersion` is `true` only where the plugin states it: marked commercial on WordPress.org, a commercial support link, or its description mentions a Pro/Premium version or plan (`paidVersionBasis` says which). `null` means "not stated", not "no".
- `status`: `open`, `closed` (with `closedDate`, `closedReason`, `closedReasonText`) or `not_found` (unknown or removed slug; listed free).
- `foundBy`: which input found the plugin (`slug`, `search:backup`, `tag:seo`, `author:automattic`, `browse:popular`).
- With a Monitor ID: `changeType` is `NEW`, `CHANGED`, `CLOSED`, `REOPENED` or `REMOVED`, and `changes` lists `{ field, from, to }`.
- `downloadsDaily` (day-by-day counts) is added when **Include the daily download series** is on.

**Scores**

- `abandonedRisk.score`: not updated for 2+ years 45 points (1+ year 25, 6+ months 10); tested 3+ major releases behind 25 (no "tested up to" 10); support with 10+ threads and none resolved 20 (3+ threads, under 30% resolved 15); median downloads falling 20%+ while not updated for a year 10. Capped at 99; **100 means closed**. Level: high 60+, medium 30+, low below.
- `growthSignal`: change in **median** daily downloads, last 28 days vs the 28 days before: +20% or more `growing`, −20% or less `declining`, otherwise `stable`. Medians are used because each release causes a few days of update downloads that would swamp a plain sum. Plugins added in the last 180 days without enough history are `new`, and others without enough history are `unknown`.

A run summary (current WordPress version, each query's status, not-found slugs, closed plugins, time) is saved as `OUTPUT` in the run's key-value store.

### Pricing

- **$0.003 per plugin** in the results (open or closed)
- Slugs that WordPress.org doesn't know are listed free
- In monitor mode you pay only for the plugins output (the changes), not for every plugin checked

### Data sources

| Source | What we use | Access |
|---|---|---|
| WordPress.org Plugin API `api.wordpress.org/plugins/info/1.2/` | `plugin_information` (one plugin) and `query_plugins` (search, tag, author, browse) | Official public API, listed in the WordPress.org API documentation; no key or login. It's the same API every WordPress site uses for its plugin screens. |
| WordPress.org stats API `api.wordpress.org/stats/plugin/1.0/downloads.php` | Daily downloads per plugin | Official, listed in the same documentation; no key |
| WordPress.org version check `api.wordpress.org/core/version-check/1.7/` | The current WordPress version | Official, listed in the same documentation; no key |

**Undocumented endpoints:** none. The Codex page lists all three endpoints. Two details come from the API's own responses rather than from written docs: the `fields[…]` switches used to leave out heavy fields, and the closed-plugin answer (HTTP 404 with `closed: true`).

### Data handling and politeness

- Only public WordPress.org directory data. No login, no CAPTCHA, no website scraping.
- Requests are paced (about 3 a second at most), run 2 at a time, and back off on errors (Retry-After respected). Heavy fields (screenshots, banners, version lists) are switched off.
- **People:** contributors and authors are output as **WordPress.org usernames only**. Display names, avatars, reviews and reviewer names from the API are never output. It's meant for researching plugins and the companies or developers behind them, not for profiling people.

### Limitations

- Installs are WordPress.org's rounded brackets, so small changes don't show until a plugin crosses a bracket.
- Downloads include automatic updates by existing sites, so the trend reflects install-base activity, not only new installs.
- Support figures cover only the last two months of the WordPress.org forum. Plugins supported elsewhere can look quiet.
- `hasPaidVersion` relies on what the plugin states on WordPress.org. Many plugins sell a Pro version without saying so there.
- Only plugins hosted on WordPress.org (not commercial-only plugins).
- Searches follow WordPress.org's own relevance order. The API returns at most 100 per page, and this tool reads at most 1,000 per query. **Max plugins per search** counts plugins before the install and risk filters.

### Feedback

Missing a field or a plugin directory feature? Open an issue on the **Issues** tab.

# Actor input Schema

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

Plugins to look up by their WordPress.org slug, the last part of the plugin URL (wordpress.org/plugins/<slug>/), e.g. "contact-form-7". Full plugin URLs are accepted too. Closed plugins are reported with their closure date and reason.

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

Search the plugin directory, the same as the search box on wordpress.org/plugins. Each term is searched separately; results come in the directory's relevance order.

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

List plugins with a directory tag, e.g. "seo", "woocommerce", "forms" (the slug in wordpress.org/plugins/tags/<tag>/).

## `authors` (type: `array`):

List the plugins of a WordPress.org account, by its username (the slug in profiles.wordpress.org/<username>/), e.g. "automattic". Meant for plugin companies and developers.

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

Also list plugins from one of the directory's own lists: most popular, newest added, or recently updated.

## `maxResultsPerQuery` (type: `integer`):

How many plugins to take from each search term, tag, author and browse list (slugs are always looked up). Up to 1,000.

## `minActiveInstalls` (type: `integer`):

Skip plugins below this many active installs (WordPress.org's rounded figure, e.g. 1000 means "1,000+"). Slugs you list are never skipped. 0 = no filter.

## `minAbandonedScore` (type: `integer`):

Keep only plugins whose abandonedRisk.score is at least this (0-100). Use 60 to find likely abandoned plugins, e.g. acquisition targets. Slugs you list are never skipped. 0 = no filter.

## `downloadHistoryDays` (type: `integer`):

Days of daily download stats to read from WordPress.org's stats API (one extra request per plugin). Used for the download totals, the trend and growthSignal; 56 or more gives a trend (median daily downloads, last 28 days vs the 28 before). 0 = skip the history (faster, but no trend).

## `includeDailyDownloads` (type: `boolean`):

Add the day-by-day download counts (downloadsDaily) to each record, e.g. for charts. Off = only the 7/30-day totals and trend.

## `onlyChanges` (type: `boolean`):

Remember each plugin between runs and output only plugins that are new to this monitor or changed (see Fields to watch), plus plugins that were closed. The first run is a baseline and outputs everything. Schedule it daily or weekly for competitor alerts.

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

Name for this watch list, so different saved tasks keep separate memories (e.g. "my-competitors"). When set, records also show changeType and changes even without Only changes. Empty with Only changes on = "default".

## `watchFields` (type: `array`):

Which changes count in monitor mode. A plugin that is closed or reopened is always reported.

## Actor input object example

```json
{
  "slugs": [
    "wordpress-seo",
    "contact-form-7",
    "classic-editor",
    "limit-login-attempts",
    "display-widgets"
  ],
  "searchTerms": [
    "backup"
  ],
  "browse": "",
  "maxResultsPerQuery": 10,
  "minActiveInstalls": 0,
  "minAbandonedScore": 0,
  "downloadHistoryDays": 60,
  "includeDailyDownloads": false,
  "onlyChanges": false,
  "monitorId": "",
  "watchFields": [
    "version",
    "activeInstalls",
    "rating",
    "numRatings",
    "testedUpTo"
  ]
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "slugs": [
        "wordpress-seo",
        "contact-form-7",
        "classic-editor",
        "limit-login-attempts",
        "display-widgets"
    ],
    "searchTerms": [
        "backup"
    ],
    "maxResultsPerQuery": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalloom/wordpress-plugin-intel").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 = {
    "slugs": [
        "wordpress-seo",
        "contact-form-7",
        "classic-editor",
        "limit-login-attempts",
        "display-widgets",
    ],
    "searchTerms": ["backup"],
    "maxResultsPerQuery": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("signalloom/wordpress-plugin-intel").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 '{
  "slugs": [
    "wordpress-seo",
    "contact-form-7",
    "classic-editor",
    "limit-login-attempts",
    "display-widgets"
  ],
  "searchTerms": [
    "backup"
  ],
  "maxResultsPerQuery": 10
}' |
apify call signalloom/wordpress-plugin-intel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,signalloom/wordpress-plugin-intel"
        }
    }
}
```

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/gKFe5vhQgTlr5J8hA/builds/Vv7HFxixaHahgRkbn/openapi.json
