Drupal Module Health Monitor — Releases and Security avatar

Drupal Module Health Monitor — Releases and Security

Pricing

$10.00 / 1,000 completed project health reports

Go to Apify Store
Drupal Module Health Monitor — Releases and Security

Drupal Module Health Monitor — Releases and Security

Check Drupal modules using public project and Composer data: maintenance status, stable releases, core compatibility, installs and open security advisories. Flags stale or unsupported projects and known security issues. No login or proxy required.

Pricing

$10.00 / 1,000 completed project health reports

Rating

0.0

(0)

Developer

Atesen Software

Atesen Software

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 days ago

Last modified

Categories

Security

Limited permissions

Share

Check Drupal modules on drupal.org: health flag, maintenance status, latest stable release for Drupal 10 and 11, installs and open security advisories.

Drupal Module Health Monitor

Give it a list of drupal.org project names (or a search term) and get one row per project with a simple health flag (OK, STALE, UNSUPPORTED or SECURITY) and the facts behind it: maintenance status, development status, the latest stable release for each Drupal core major (10.x and 11.x) with its release date, which core versions the newest release supports, reported installs and the open security advisories (SA-CONTRIB id, date, risk). It reads drupal.org's public data only. No login, no browser, no proxy.

  • Built for agency audits: paste the modules of a client site and see in one table which ones are safe, which are going stale and which have unfixed security advisories.
  • Per-core answer: for every Drupal core major you choose, the newest stable release that works with it. A module that is ready for Drupal 10 but not yet for 11 shows exactly that.
  • Open advisories only: an advisory counts as open when it still affects the newest stable release. Fixed advisories are counted in advisoriesTotal but do not raise the flag.
  • Never crashes on a bad name: an unknown project, a typo or a failed lookup gives one free status row that says why.
  • No personal data: maintainer and author names are not saved.

Use cases

  • Client site audits: a monthly health table for every module a client runs.
  • Upgrade planning, Drupal 10 to 11: which modules already have a stable release for 11.
  • Security watch: modules that carry an unfixed SA-CONTRIB advisory, including abandoned ones that drupal.org marks unsupported.
  • Module selection: compare candidate modules by maintenance status, last release and installs before you build on them.

Input

FieldDescription
projectsdrupal.org machine names (token) or project URLs (https://www.drupal.org/project/pathauto). Modules, themes and recipes work. Drupal core itself is not checked.
searchTermsOptional. Words for drupal.org's package search, for example sitemap. The best matches are checked.
coreVersionsCore majors you care about. Default 10 and 11. Choices: 9, 10, 11, 12.
maxItemsTotal number of projects to check. Default 25, 0 = no limit.
maxSearchResultsMatches checked per search term. Default 10, up to 100 (the package search answers 50 matches per page; further pages are read as needed, 10 seconds apart).
staleAfterMonthsAge of the newest stable release after which a project is flagged STALE. Default 18.
includeAdvisoryListDefault on. Adds the open advisories to every row.
{
"projects": ["token", "https://www.drupal.org/project/webform", "pathauto", "raw_formatter"],
"maxItems": 10
}

drupal.org asks API clients for one request every 10 seconds, so plan on roughly 25 seconds per project (two lookups per project plus one shared advisory lookup for every ten projects).

Output

One row per project.

A healthy project. Webform has 31 advisories in its history, none of them affects the newest release, so the flag is OK:

{
"type": "project",
"name": "Webform",
"machineName": "webform",
"url": "https://www.drupal.org/project/webform",
"projectType": "project_module",
"composerPackage": "drupal/webform",
"healthFlag": "OK",
"healthReasons": [],
"maintenanceStatus": "Actively maintained",
"developmentStatus": "Under active development",
"securityCoverage": "covered",
"latestStableRelease": "6.3.1",
"latestStableReleaseDate": "2026-09-23",
"supportedCoreVersions": [
"10",
"11"
],
"latestStableByCore": {
"10": {
"version": "6.3.1",
"date": "2026-09-23",
"coreRequirement": "^10.3 || ^11.0"
},
"11": {
"version": "6.3.1",
"date": "2026-09-23",
"coreRequirement": "^10.3 || ^11.0"
}
},
"newerPreRelease": null,
"reportedInstalls": 357014,
"installsByBranch": {
"5.x-2.x": 23,
"6.x-2.x": 405,
"6.x-3.x": 2396,
"7.x-4.x": 68496,
"8.x-5.x": 13749,
"6.0.x": 3389,
"6.2.x": 64207,
"8.x-4.x": 2,
"5.x-1.x": 8,
"7.x-3.x": 22418,
"6.1.x": 17273,
"6.3.x": 164452,
"6.x": 196
},
"openAdvisoryCount": 0,
"openAdvisories": [],
"advisoriesTotal": 31,
"lastAdvisoryDate": "2026-09-23",
"license": "GNU General Public License, version 2 or later",
"description": "Build forms to collect data from site visitors. Create everything from a simple contact form to a multi-page form with many fields, conditional logic, and email notifications.",
"createdAt": "2004-04-26T20:54:31.000Z",
"projectChangedAt": "2026-07-21T16:37:33.000Z",
"input": "https://www.drupal.org/project/webform",
"scrapedAt": "2026-10-24T01:05:14.315Z"
}

A project with an open advisory. The long description is cut at 300 characters with "…":

{
"type": "project",
"name": "Raw Formatter [Meta Tag Formatter]",
"machineName": "raw_formatter",
"url": "https://www.drupal.org/project/raw_formatter",
"projectType": "project_module",
"composerPackage": "drupal/raw_formatter",
"healthFlag": "SECURITY",
"healthReasons": [
"1 open security advisory affects the latest stable release: SA-CONTRIB-2026-077",
"Maintenance status is \"Unsupported\"",
"Security advisory coverage was revoked"
],
"maintenanceStatus": "Unsupported",
"developmentStatus": "No further development",
"securityCoverage": "revoked",
"latestStableRelease": "2.0.2",
"latestStableReleaseDate": "2026-07-08",
"supportedCoreVersions": [
"10",
"11"
],
"latestStableByCore": {
"10": {
"version": "2.0.2",
"date": "2026-07-08",
"coreRequirement": "^10 || ^11"
},
"11": {
"version": "2.0.2",
"date": "2026-07-08",
"coreRequirement": "^10 || ^11"
}
},
"newerPreRelease": null,
"reportedInstalls": 71,
"installsByBranch": {
"2.0.x": 63,
"8.x-1.x": 8
},
"openAdvisoryCount": 1,
"openAdvisories": [
{
"id": "SA-CONTRIB-2026-077",
"date": "2026-07-08",
"risk": "Critical",
"type": "Unsupported",
"title": "Raw Formatter [Meta Tag Formatter] - Critical - Unsupported - SA-CONTRIB-2026-077",
"cve": "CVE-2026-15086",
"affectedVersions": "*",
"url": "https://www.drupal.org/sa-contrib-2026-nnvker3eee"
}
],
"advisoriesTotal": 1,
"lastAdvisoryDate": "2026-07-08",
"license": "GNU General Public License, version 2 or later",
"description": "This module is unsupported due to a security issue the maintainer didn’t fix. If you want to use this module, your options are: Choose another, actively maintained module instead Following the unsupported project process . Hire someone to fix the security bug so the module can be re-published and s…",
"createdAt": "2015-10-09T05:56:14.000Z",
"projectChangedAt": "2026-07-08T17:13:30.000Z",
"input": "raw_formatter",
"scrapedAt": "2026-10-24T01:05:14.324Z"
}

Field notes:

  • healthFlag is decided in this order: SECURITY (at least one open advisory affects the newest stable release for your core versions), UNSUPPORTED (maintenance status "Unsupported", development status "Obsolete", security coverage revoked, or no release at all that works with your core versions), STALE (the newest stable release for your core versions is older than staleAfterMonths), otherwise OK. healthReasons lists every reason, plus notes such as "Seeking new maintainer". A note also says so when something could not be checked: a status that drupal.org lists but that could not be read, a release without a date, or an advisory whose affected-version range could not be read (that advisory is then named and not counted as open).
  • latestStableRelease is the newest stable release overall. latestStableByCore has one entry per core major you asked for: the newest stable release whose Composer requirement admits that core, with coreRequirement as the module declares it. supportedCoreVersions lists the core majors (8 to 12) the newest release admits.
  • When no stable release exists for your cores but a pre-release (alpha, beta, rc) does, the flag is judged on that pre-release and healthReasons says so. newerPreRelease shows a pre-release that is newer than the latest stable one.
  • reportedInstalls is the sum of the sites that report using the project, over all branches, as drupal.org counts them; installsByBranch shows the split. Drupal 7 and older sites are included in the sum, so use the branch split for Drupal 8 and newer.
  • openAdvisories entries have id (SA-CONTRIB-YYYY-NNN), date, risk (Critical, Highly critical, Moderately critical, Less critical, Not critical), type, cve, affectedVersions and url.

Free helper rows share the same dataset: type: "status" with status, input, message, and project (a project problem) or httpStatus (a failed search).

Status values you may see: project_not_found, invalid_project, unsupported_project, search_no_results, search_failed, blocked_by_robots, fetch_failed, limit_reached, invalid_input.

{
"type": "status",
"status": "project_not_found",
"input": "no_such_project_zzz",
"message": "No project with the machine name \"no_such_project_zzz\" exists on drupal.org. Not charged.",
"project": "no_such_project_zzz",
"scrapedAt": "2026-10-24T01:07:30.253Z"
}

Where the data comes from

All data is public and comes from drupal.org's own services:

  • Project data: www.drupal.org/api-d7/node (maintenance status, development status, security coverage, reported installs, license, summary).
  • Releases: the drupal.org Composer repository at packages.drupal.org (release numbers, dates, and the Drupal core each release requires).
  • Security advisories: the security advisory feed of the same Composer repository (SA-CONTRIB ids, risk, dates, affected versions).
  • Search: the package search of that repository.

The update status XML at updates.drupal.org/release-history/<project>/current is deliberately not used. That host's robots.txt disallows all robots, so the Actor stays away from it and gets the release data from the Composer repository instead, which also states the core requirement of every release.

Drupal.org API terms (checked 24 October 2026)

  • The API guide asks clients to use the APIs respectfully: an appropriate user agent, requests from a single thread, local caching, and it says abuse will be blocked. This Actor identifies itself as DrupalModuleHealth/1.0, sends one request at a time, and asks for each project once per run.
  • robots.txt on drupal.org sets Crawl-delay: 10. The Actor waits at least 10 seconds between requests to any drupal.org host and checks robots.txt before every URL.
  • The Drupal Association's page on automation tools says traditional API requests are allowed by default but rate limited, and that read-only tools may be blocked or rate limited. It also reserves the right to prohibit using content scraped from drupal.org to train commercial AI models without written permission. This Actor only reads; do not use its output for that purpose.
  • You are responsible for how you use the data. Check the current terms before you build a service on it.

Limits

  • Needs a Composer-packaged release (Drupal 8 and newer). A Drupal 7 only project is reported as UNSUPPORTED with a reason.
  • An advisory is judged against the newest stable release per core you chose, not against the version installed on a site. Installed versions are not an input.
  • The health flag is a screening aid. It does not read code and does not replace the security team's advisories or your own review.
  • Core compatibility comes from the release's Composer requirement (drupal/core). A module with no declared core requirement counts as not compatible.
  • The search returns the repository's best matches, which can include themes and recipes.

FAQ

Why does it take so long? drupal.org's robots.txt asks for 10 seconds between requests and its API guide asks for a single thread. A project needs two lookups, so a run of 25 projects takes about ten minutes. The Actor never goes faster than that.

What does SECURITY mean exactly? At least one security advisory (SA-CONTRIB) lists the newest stable release as affected. Typical cases are modules that drupal.org marked unsupported after an unfixed vulnerability. An advisory that was fixed in the latest release does not count.

Why is a module flagged UNSUPPORTED although it exists? Either its maintenance status is "Unsupported" or "Obsolete", its security coverage was revoked, or none of its releases works with the core versions you selected. healthReasons names the cause.

Can I check my own site's installed versions? Not yet. The Actor checks the newest releases against drupal.org's advisories. Feed it the module names from your composer.lock and compare the versions yourself.

Does it use the Drupal.org update status XML? No. That endpoint's robots.txt disallows robots, so the same facts are read from the Composer repository.

Pricing

Pay per result — see the Pricing tab.

Each checked project row is one result. Status rows are free. The run stops when it reaches the maximum cost per run that you set. If no result fits the remaining budget, it makes no robots, search or project-data requests. On graceful abort it saves RUN_SUMMARY and a STATE progress snapshot (completed project names, current project and counters) before shutdown; the snapshot does not automatically resume a later run.

Support and disclaimers

Questions and feature requests belong on the Issues tab of this Actor's page on Apify. This Actor is an independent tool and is not affiliated with the Drupal Association or any module maintainer. Drupal is a registered trademark of Dries Buytaert.