Drupal Module Health Monitor — Releases and Security
Pricing
$10.00 / 1,000 completed project health reports
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Security
Limited permissionsShare
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
advisoriesTotalbut do not raise the flag. - Never crashes on a bad name: an unknown project, a typo or a failed lookup gives one free
statusrow 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
| Field | Description |
|---|---|
projects | drupal.org machine names (token) or project URLs (https://www.drupal.org/project/pathauto). Modules, themes and recipes work. Drupal core itself is not checked. |
searchTerms | Optional. Words for drupal.org's package search, for example sitemap. The best matches are checked. |
coreVersions | Core majors you care about. Default 10 and 11. Choices: 9, 10, 11, 12. |
maxItems | Total number of projects to check. Default 25, 0 = no limit. |
maxSearchResults | Matches 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). |
staleAfterMonths | Age of the newest stable release after which a project is flagged STALE. Default 18. |
includeAdvisoryList | Default 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:
healthFlagis 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 thanstaleAfterMonths), otherwise OK.healthReasonslists 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).latestStableReleaseis the newest stable release overall.latestStableByCorehas one entry per core major you asked for: the newest stable release whose Composer requirement admits that core, withcoreRequirementas the module declares it.supportedCoreVersionslists 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
healthReasonssays so.newerPreReleaseshows a pre-release that is newer than the latest stable one. reportedInstallsis the sum of the sites that report using the project, over all branches, as drupal.org counts them;installsByBranchshows the split. Drupal 7 and older sites are included in the sum, so use the branch split for Drupal 8 and newer.openAdvisoriesentries haveid(SA-CONTRIB-YYYY-NNN),date,risk(Critical, Highly critical, Moderately critical, Less critical, Not critical),type,cve,affectedVersionsandurl.
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.txton drupal.org setsCrawl-delay: 10. The Actor waits at least 10 seconds between requests to any drupal.org host and checksrobots.txtbefore 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.