The Versions plugin exposes an authenticated endpoint that returns version information about Craft CMS, PHP, and installed plugins. It is used by internal agency tooling (Google Sheets) to track software versions across all client sites.
- PHP ≥ 8.2
- Craft CMS ≥ 5.9.0
This is a private Composer package installed from its GitHub repository. Add it to the site's composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/engageinteractive/engage-craft-versions"
}
]
}Then require it:
composer require engageinteractive/craft-versionsInstall the plugin in Craft:
php craft plugin/install versionsRun the console command to generate a key and write it automatically to .env:
php craft versions/generate-api-keyThis will:
- Generate a cryptographically random 32-character API key
- Write
CRAFT_VERSIONS_API_KEY=<key>to.env - Save the
$CRAFT_VERSIONS_API_KEYreference in project config
The console key generator writes to the local .env only. On staging and production you must set the environment variable manually via your hosting platform, deploy configuration, or server .env file:
CRAFT_VERSIONS_API_KEY=your-key-hereNote: You can use the same key value across multiple sites if your team prefers — each site holds its own independent copy of the variable.
Admin users can see the resolved value of CRAFT_VERSIONS_API_KEY on the plugin settings page in the Craft control panel:
/admin/settings/plugins/versions
The field also accepts the $CRAFT_VERSIONS_API_KEY environment variable reference directly if you need to update it manually via the CP.
Returns version information for Craft CMS, PHP, and all installed plugins.
Authentication:
- Required header:
apiKey - Value: must match
CRAFT_VERSIONS_API_KEY - Comparison: timing-safe (
hash_equals) - Allowed method:
GETonly - Request must accept JSON (
Accept: application/jsonrecommended)
Test locally:
curl -X GET http://localhost:8000/actions/versions/check \
-H "apiKey: your-key-here" \
-H "Accept: application/json"Success response (200):
{
"success": true,
"data": {
"craftVersion": "5.4.0",
"phpVersion": "8.2.15",
"plugins": {
"verbb-hyper": "2.2.0",
"spicyweb-neo": "5.2.1"
}
}
}Failure response (401):
{
"success": false,
"error": "Unauthorised."
}Cloudflare steps.
- Go to Security→ WAF → Custom rules(or Security → Configuration → WAF Custom rules).
- Click Create rule(or Add rule).
- Rule name: e.g.Craft CMS Versions Endpoint.
- Field -> URI Path Equals -> /actions/versions/check
- Set to skip bot fight mode
- Deploy/Save.
Generates a new random API key and writes it to .env. Prompts for confirmation before overwriting an existing key.
Local use only — does not work on environments where .env is not writable or managed outside the project.
Use Google Apps Script (UrlFetchApp) to call the endpoint and write data into sheet cells:
function fetchVersionInfo() {
const url = 'https://example.com/actions/versions/check';
const apiKey = 'your-key-here';
const response = UrlFetchApp.fetch(url, {
method: 'get',
headers: {
'apiKey': apiKey,
'Accept': 'application/json',
},
muteHttpExceptions: true,
});
const data = JSON.parse(response.getContentText());
if (data.success) {
// Use data.data.craftVersion, data.data.phpVersion, data.data.plugins, etc.
}
}Native sheet
IMPORTDATA/IMPORTJSONfunctions cannot send custom headers. Google Apps Script is required.
src/
├── Versions.php # Main plugin class
├── controllers/
│ └── CheckController.php # Endpoint handler
├── console/
│ └── controllers/
│ └── GenerateController.php # CLI key generation
├── models/
│ └── Settings.php # Plugin settings model
├── services/
│ └── VersionsService.php # Version data collection
└── templates/
└── _settings.twig # CP settings UI
- Verify
CRAFT_VERSIONS_API_KEYis set in the environment - Confirm the
apiKeyrequest header value matches - Confirm the request includes an
Accept: application/jsonheader - On staging/prod, check the key is set in the server environment, not just
.env - Sync project config if the plugin settings reference is missing:
php craft project-config/apply
- The plugin handle is
versions(with underscore prefix) - Confirm the plugin is enabled: Settings → Plugins in the Craft CP
- Verify
"handle": "versions"incomposer.json
- The command only works locally where
.envis writable - Check file permissions on
.env - Review Craft logs at
storage/logs/
- The endpoint returns read-only version metadata only — no secrets, paths, or credentials are exposed
- CSRF validation is disabled only for
/actions/versions/check - The endpoint is restricted to
GETrequests only - The endpoint requires a JSON-capable request via
requireAcceptsJson() - Authentication failures return
401responses - Comparison uses
hash_equalsto prevent timing attacks - Token generation uses Craft's cryptographically secure
security->generateRandomString()helper - Secret values are intended to be stored in environment variables and resolved via Craft's env parsing helpers
- The resolved API key value is visible to admin users only via the CP settings page
For issues or changes, contact the development team.