Skip to content

Powered by Grav + Helios

Package Manager

Package Manager

Endpoints for managing Grav packages (plugins and themes) via the GPM, including installation, removal, updates, and repository search.

Endpoints for managing Grav packages (plugins and themes) via the GPM, including installation, removal, updates, and repository search.

List Plugins

GET /gpm/plugins
List all installed plugins with enablement flags, update status, and whether each plugin is installed via a symlink (important for upgrade gating — symlinked packages should not be overwritten).
JSON
{"data": [{"slug": "admin2", "name": "Admin2", "version": "3.0.0-beta.1", "enabled": true, "is_symlink": false, "updatable": false}]}

Response Codes

200 Plugins returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.

Get Plugin

GET /gpm/plugins/{slug}
Get details for a single installed plugin, including `enabled`, `updatable`, `installed_version`, `available_version`, and the `is_symlink` flag.

Parameters

Name Type Description
slug required string The plugin slug.
JSON
{"data": {"slug": "simplesearch", "name": "SimpleSearch", "enabled": true, "is_symlink": false, "installed_version": "2.3.0", "available_version": "2.4.0", "updatable": true}}

Response Codes

200 Plugin returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Plugin not found.

Install Package

POST /gpm/install
Install a plugin or theme from the GPM repository.

Parameters

Name Type Description
package required string Package slug to install
type required string Package type: plugin or theme
license optional string License key for premium packages
JSON
{"package": "sitemap", "type": "plugin"}

Response Codes

201 Package installed
401 Unauthorized
422 Validation error (package not found or install failed)

Remove Package

POST /gpm/remove
Remove an installed package.

Parameters

Name Type Description
package required string Package slug to remove
JSON
{"package": "sitemap"}

Response Codes

204 Package removed
401 Unauthorized
404 Package not found

Check Updates

GET /gpm/updates
Check for available updates across plugins, themes, and the Grav core. `total` counts Grav itself as well as plugin/theme updates. The `grav` object includes `is_symlink` so admin UIs can disable the core-upgrade action when Grav is symlinked.

Parameters

Name Type Description
flush optional boolean Bypass cache and fetch fresh update data.
JSON
{"data": {"total": 4, "grav": {"installed_version": "2.0.0-beta.1", "available_version": "2.0.0-beta.2", "updatable": true, "is_symlink": false}, "plugins": [{"slug": "seo-magic", "installed_version": "1.9.0", "available_version": "1.10.0"}], "themes": []}}

Response Codes

200 Update summary returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.

Search Repository

GET /gpm/search
Search the GPM repository for plugins and themes.

Parameters

Name Type Description
q required string Search query string
page optional integer Page number for pagination (default: 1)
per_page optional integer Number of results per page (default: 20, max: 100)

Response Codes

200 Success
401 Unauthorized

List Themes

GET /gpm/themes
List all installed themes with thumbnail URLs, update status, and the `is_symlink` flag.
JSON
{"data": [{"slug": "quark", "name": "Quark", "version": "2.0.0", "updatable": false, "is_symlink": false, "thumbnail": "/api/v1/thumbnails/quark-thumb.jpg"}]}

Response Codes

200 Themes returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.

Get Theme

GET /gpm/themes/{slug}
Get details for a specific installed theme, including screenshot URL, `updatable` status, and the `is_symlink` flag.

Parameters

Name Type Description
slug required string The theme slug.
JSON
{"data": {"slug": "quark", "name": "Quark", "version": "2.0.0", "updatable": false, "is_symlink": false, "screenshot": "/api/v1/thumbnails/quark-screen.jpg"}}

Response Codes

200 Theme returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Theme not installed.

Update Package

POST /gpm/update
Update a specific installed plugin or theme to the latest version.

Parameters

Name Type Description
package required string Package slug to update
JSON
{"package": "admin"}
JSON
{"data": {"message": "Package 'admin' updated successfully.", "package": "admin"}}

Response Codes

200 Package updated
401 Unauthorized
422 Package not updatable or not installed
500 Update failed

Update All Packages

POST /gpm/update-all
Update every updatable plugin and theme in one request. Each package is attempted independently — one failure does not abort the batch. Returns two arrays: `updated` (slugs that succeeded) and `failed` (objects with `package` and `error`). Fires `onApiBeforePackageUpdate` / `onApiPackageUpdated` for each package.
JSON
{"data": {"updated": ["simplesearch", "seo-magic"], "failed": [{"package": "broken-plugin", "error": "Dependency unmet"}]}}

Response Codes

200 Batch completed; per-package outcome in `updated[]` / `failed[]`.
401 Unauthorized.
403 Missing `api.gpm.write` permission.

Browse Repository Themes

GET /gpm/repository/themes
List all themes available in the GPM repository with `installed` flag on each. Supports pagination and `q` text search. 502 if the repository is unreachable.

Parameters

Name Type Description
q optional string Search query to filter themes (matches name / slug / description).
page optional integer Page number (default 1).
per_page optional integer Items per page (default from config; max 2000 so the install modal can fetch the full list).
JSON
{"data": [{"slug": "quark", "name": "Quark", "description": "Modern theme", "installed": true}], "meta": {"total": 120, "page": 1, "per_page": 20}}

Response Codes

200 Repository themes returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
502 GPM repository unreachable.

Get README

GET /gpm/plugins/{slug}/readme
Get the README.md content for an installed plugin or theme. Also available at /gpm/themes/{slug}/readme.

Parameters

Name Type Description
slug required string The package slug
JSON
{"data": {"content": "# My Plugin\n\nThis plugin does..."}}

Response Codes

200 Success
401 Unauthorized
404 Package or README not found

Get Changelog

GET /gpm/plugins/{slug}/changelog
Get the CHANGELOG.md content for an installed plugin or theme. Also available at /gpm/themes/{slug}/changelog.

Parameters

Name Type Description
slug required string The package slug
JSON
{"data": {"content": "# v1.2.0\n## 01/15/2025\n\n* Added feature X..."}}

Response Codes

200 Success
401 Unauthorized
404 Package or changelog not found

Get Plugin Page

GET /gpm/plugins/{slug}/page
Get the admin page definition for a plugin. Returns the page type, blueprint reference, data/save endpoints, and action buttons. Resolution order: 1) onApiPluginPageInfo event, 2) admin-next/pages/{slug}.yaml, 3) admin-next/pages/{slug}.js (inferred component mode).

Parameters

Name Type Description
slug required string The plugin slug
JSON
{"data": {"id": "license-manager", "plugin": "license-manager", "title": "License Manager", "icon": "fa-key", "page_type": "blueprint", "blueprint": "licenses", "data_endpoint": "/licenses/form-data", "save_endpoint": "/licenses", "actions": [{"id": "save", "label": "Save", "icon": "fa-check", "primary": true}], "has_custom_component": false}}

Response Codes

200 Success
401 Unauthorized
404 No admin page found for plugin

Get Plugin Page Script

GET /gpm/plugins/{slug}/page-script
Serve the page-level web component JavaScript file for a plugin. The file is loaded from admin-next/pages/{slug}.js within the plugin directory. Returned with Content-Type application/javascript and immutable cache headers.

Parameters

Name Type Description
slug required string The plugin slug

Response Codes

200 Success (JavaScript content)
401 Unauthorized
404 Page component not found for plugin

Upgrade Grav Core

POST /gpm/upgrade
Self-upgrade the Grav core. Refuses to run when Grav is installed via symlink (typical dev/monorepo setups). Fires `onApiBeforeGravUpgrade` and `onApiGravUpgraded` around the upgrade.
JSON
{"data": {"message": "Grav upgraded successfully.", "previous_version": "2.0.0-beta.1", "new_version": "2.0.0-beta.2"}}

Response Codes

200 Core upgraded.
400 Grav is already at the latest version, or installed via symlink.
401 Unauthorized.
403 Missing `api.gpm.write` permission.
500 Upgrade failed mid-flight.

Direct Install

POST /gpm/direct-install
Install a plugin or theme from a URL or uploaded zip — bypasses the GPM repository lookup. Accepts either a JSON body with `url`, or a multipart upload with a `file` field. Useful for private/unpublished packages, pre-release builds, or local development.

Parameters

Name Type Description
url optional string URL of the package zip (mutually exclusive with `file`).
file optional file Uploaded zip file (multipart; mutually exclusive with `url`).
JSON
{"url": "https://example.com/builds/my-plugin-1.0.0.zip"}
JSON
{"data": {"message": "Package installed successfully via direct install."}}

Response Codes

201 Package installed.
400 Neither `url` nor a valid `file` was provided.
401 Unauthorized.
403 Missing `api.gpm.write` permission.
500 Installation failed.

List Repository Plugins

GET /gpm/repository/plugins
List all plugins available in the GPM repository, with `installed` flag on each. Supports pagination (`page`, `per_page` — capped at 2000 so the install modal can fetch the full list) and `q` text search. 502 if the repository is unreachable.

Parameters

Name Type Description
page optional integer Page number (default 1).
per_page optional integer Items per page (default from config; max 2000).
q optional string Search filter matched against name / slug / description.
JSON
{"data": [{"slug": "simplesearch", "name": "SimpleSearch", "version": "2.4.0", "installed": true, "installed_version": "2.3.0"}], "meta": {"total": 250, "page": 1, "per_page": 50}}

Response Codes

200 Repository plugins returned.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
502 GPM repository unreachable.

Get Repository Package

GET /gpm/repository/{slug}
Get full repository details for a plugin or theme (whichever matches the slug), plus an `installed` flag.

Parameters

Name Type Description
slug required string Package slug.
JSON
{"data": {"slug": "simplesearch", "name": "SimpleSearch", "version": "2.4.0", "description": "...", "author": {"name": "Trilby Media"}, "installed": false}}

Response Codes

200 Package found.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Package not found in the GPM repository.

Get Custom Field Script

GET /gpm/plugins/{slug}/field/{type}
Serve the JavaScript web component for a plugin's custom blueprint field type. Also available under `/gpm/themes/{slug}/field/{type}` for theme-provided fields. Admin2 loads these on demand when rendering a blueprint that uses an unknown field type. Convention: the file lives at `admin-next/fields/{type}.js` inside the package. Response is served with `Content-Type: application/javascript`.

Parameters

Name Type Description
slug required string Plugin (or theme) slug.
type required string Field type identifier (matches the `type:` value in the blueprint).

Response Codes

200 JavaScript file served.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Field component not found.

Get Report Script

GET /gpm/plugins/{slug}/report-script/{reportId}
Serve the web component for a custom report shown on the Admin2 Reports page. Plugins ship the file at `admin-next/reports/{reportId}.js` and register the report via the `onApiGenerateReports` event. Admin2 loads the script only when the matching report is rendered.

Parameters

Name Type Description
slug required string Plugin slug.
reportId required string Report identifier (matches the `id` from `onApiGenerateReports`).

Response Codes

200 JavaScript file served.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Report component not found.

Get Floating Widget Script

GET /gpm/plugins/{slug}/widget-script
Serve the web component for a plugin-provided floating widget. Convention: the file lives at `admin-next/widgets/{slug}.js`. Registered via the `onApiFloatingWidgets` event and listed by `GET /floating-widgets`.

Parameters

Name Type Description
slug required string Plugin slug.

Response Codes

200 JavaScript file served.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Widget component not found.

Get Context Panel Script

GET /gpm/plugins/{slug}/panel-script
Serve the web component for a plugin-provided context panel (right-rail panel shown while editing pages or other content). Convention: the file lives at `admin-next/panels/{slug}.js`. Registered via the `onApiContextPanels` event and listed by `GET /context-panels`.

Parameters

Name Type Description
slug required string Plugin slug.

Response Codes

200 JavaScript file served.
401 Unauthorized.
403 Missing `api.gpm.read` permission.
404 Panel component not found.