Contents
- Domma CMS User Manual
- 1. Using the CMS
- 2. Tutorials
- 3. Components
- 4. API Reference
- 5. Tools
Plugins API
Updated by Darryl Waterhouse on 29 September 2026 · 5 min read
These endpoints drive the Marketplace screen (System > Plugins, #/plugins). They need the plugins permission for the action named: read, create (install), update (switch on or off, settings) or develop (the source editor, export and restart). Installing from, and uninstalling through, the managed catalogue needs an admin (role level 0 or 1).
Restarts. A plugin's routes and screens are read when the server starts, so switching a plugin or a built-in Tool on or off restarts the server by itself, about a second and a half after the reply, when something will bring it back (the fleet manager, or pm2) and restartOnPluginToggle in config/server.json is not false. The reply says what happened: restartRequired, supervised, restarting. Installing, updating and uninstalling do not restart; the new code runs after the next restart.
GET /api/plugins
Requires Bearer token + plugins read permission.
Every installed plugin, with its state.
// Response 200
[ { "name": "blog", "displayName": "Blog", "version": "1.9.0", "description": "...", "author": "...", "icon": "edit",
"core": false, "enabled": true, "closedSource": false, "licence": "...",
"entitlement": null, // for a licensed plugin: valid, grace, expired, support-ended, unlicensed...
"supersededBy": null, // enabled but replaced by another plugin (a Pro edition)
"blockedBy": null, // enabled but not running: something it requires is off
"locked": false, // the site's manager holds this switch
"requires": [], "uses": {},
"settings": {}, "settingsSchema": null, "effectiveSettings": {} } ]
Secret settings come back masked; sending the mask back keeps the stored value.
PUT /api/plugins/:name
Requires Bearer token + plugins update permission.
Switch a plugin on or off, or save its settings. A switch goes through the same check as the screen: a switch the site's manager has locked is refused with 423, and one that changes other Tools or plugins (a plugin that requires this one goes off with it; switching one on brings on what it requires) answers 409 with the plan until repeated with "cascade": true. A built-in plugin cannot be switched off.
| Field | Type | Description |
|---|---|---|
enabled | boolean | On or off |
settings | object | The plugin's settings |
cascade | boolean | Confirm the knock-on changes in a 409's plan |
// Response 200 - a switch
{ "success": true, "restartRequired": true, "supervised": true, "restarting": true }
// Error 409 - confirm first
{ "error": "This switch changes other Tools too.", "needsConfirm": true, "plan": { ... } }
GET /api/tools
Requires Bearer token + plugins read permission.
The built-in Tools that can be switched off - Contacts, Notes, Todo, Analytics and SEO - with their state and the plugins that depend on each. GET /api/tools/enabled (any signed-in user) answers just {"notes": true, ...}.
// Response 200
[ { "name": "contacts", "displayName": "Contacts", "enabled": true, "locked": false,
"requiredBy": [ { "name": "contacts-pro", "displayName": "Contacts Pro" } ],
"usedBy": [ { "name": "calendar", "displayName": "Calendar", "reason": "Invite a contact group" } ] } ]
PUT /api/tools/:name
Requires Bearer token + plugins update permission.
Switch a built-in Tool on or off ({"enabled": false}). Nothing is deleted; switched back on, everything is where it was. The same 423 / 409-with-plan / cascade rules and restart as a plugin.
POST /api/plugins/install-upload
Requires Bearer token + plugins create permission. Content-Type: multipart/form-data.
Install or update a plugin from a .dcmsplugin file (Install from file). The plugin is named by the manifest inside, not the file name. Refusals come back as questions to confirm with form fields set to true: confirmUpgrade (it is already installed - 409, code: "already-installed"), confirmDowngrade and confirmUnsigned (a file not signed by the Marketplace; a site with requireSignedPlugins refuses those outright). A plugin whose minCmsVersion is newer than this site is refused, naming both versions, and an update leaves the installed version in place. A licensed plugin's licence travels in the file. A new plugin arrives switched off.
// Response 200
{ "success": true, "name": "invoices", "action": "install", "from": null, "version": "1.6.1", "restartRequired": true }
// Error 400
{ "error": "Invoices needs Domma CMS 0.93.0 or later; this site runs 0.92.2. Update the CMS first." }
GET /api/plugins/marketplace
Requires Bearer token + an admin role (level 0 or 1).
The Browse tab: what this site can get from its manager, with what is installed and what can be updated. A site that is not managed answers {"available": false, "catalogue": []} and installs from a file instead.
cmsVersion is the Domma CMS this site runs. Each entry's needsCms is null, or - when the plugin's minCmsVersion is newer than this site - the sentence an install would be refused with.
// Response 200
{ "available": true, "site": "my-site", "cmsVersion": "0.94.0",
"catalogue": [ { "slug": "invoices", "version": "1.6.1", "installed": true, "installedVersion": "1.6.0", "updatable": true, "needsCms": null, ... } ] }
POST /api/plugins/marketplace/install
Requires Bearer token + an admin role (level 0 or 1). Managed sites only.
Fetch a plugin from the manager and install it, licensed to this site; "update": true updates one already installed. If the update fails, the installed version is put back. A refusal from the manager (no licence) answers 403 with its reason; 503 when the manager cannot be reached. A plugin that needs a newer Domma CMS answers 400 naming both versions, as Install from file does.
// Request body
{ "slug": "invoices", "version": "1.6.1", "update": true }
// Response 200
{ "success": true, "name": "invoices", "action": "upgrade", "from": "1.6.0", "version": "1.6.1", "restartRequired": true }
// Error 400
{ "error": "SEO Pro needs Domma CMS 0.90.0 or later; this site runs 0.89.2. Update the CMS first." }
DELETE /api/plugins/marketplace/:slug
Requires Bearer token + an admin role (level 0 or 1).
Uninstall a plugin. Its files and its data/ folder are removed, roles it added are removed and their users moved to user. Restart to finish.
// Response 200
{ "success": true }
GET /api/plugins/admin-config
Requires Bearer token (any role).
What the admin needs from the running plugins: sidebar items, screens (routes) and the scripts behind them.
// Response 200
{ "sidebar": [ { "id": "blog", "text": "Blog", "icon": "edit", "url": "#/plugins/blog" } ],
"routes": [ { "path": "/plugins/blog", "view": "plugin-blog", "title": "Blog - Domma CMS" } ],
"views": { "plugin-blog": { "entry": "blog/admin/views/blog.js", "exportName": "blogView" } } }
POST /api/plugins/scaffold
Requires Bearer token + plugins create permission.
Start a new plugin from the template (New plugin). It is created switched on and runs after the next restart.
// Request body
{ "slug": "my-plugin", "displayName": "My Plugin", "description": "...", "author": "...", "icon": "package" }
// Response 200
{ "success": true, "name": "my-plugin", "files": [ ... ], "restartRequired": true }
GET /api/plugins/:name/export
Requires Bearer token + plugins develop permission.
Download a plugin as an unsigned .dcmsplugin file (?includeData=1 adds its data). Licensed plugins cannot be exported (403). The source editor uses GET /api/plugins/:name/files and GET, PUT, DELETE /api/plugins/:name/file, and POST /api/plugins/restart restarts the server to run edited code; a licensed plugin's source is open only to the level-0 role.
On this page