Domma CMS User Manual

Actions API

Updated by Darryl Waterhouse on 29 September 2026 3 min read

Actions need a MongoDB connection (a Pro feature): action configs are kept in the cms__actions collection on the default connection, and without it these endpoints answer 503. The admin endpoints need the actions permission for the action named (read, create, update, delete).

Admin Endpoints

GET /api/actions

Requires: actions read permission

Every action config.

POST /api/actions

Requires: actions create permission

Create an action. Answers 201. Step types: updateField, deleteEntry, moveToCollection, createInCollection, webhook, email, notify (see Documentation > Usage > Actions). manual is the only trigger.

{
  "title": "Approve Application",
  "slug": "approve-application",
  "collection": "applications",
  "trigger": { "type": "manual", "label": "Approve", "icon": "check-circle", "confirmMessage": "Approve this application?" },
  "transition": { "field": "status", "from": ["submitted", "reviewing"], "to": "approved" },
  "steps": [
    { "type": "updateField", "config": { "field": "status",     "value": "approved" } },
    { "type": "updateField", "config": { "field": "approvedAt", "value": "{{now}}"  } },
    { "type": "email",       "config": { "to": "{{entry.data.email}}", "subject": "Application approved",
                                         "template": "Hi {{entry.data.name}}, your application is approved." } }
  ],
  "access": { "roles": ["admin"], "rowLevel": null }
}

Who may run it. Any role in access.roles is enough: its holders may run the action, and so may everyone in a more senior role, across all the roles a user holds - the page and view visibility rule. An action naming no roles is for admins (levels 0 and 1); a role name the site does not have admits only the level-0 role. access.rowLevel ({"mode": "owner"}, {"mode": "field", "field": "assignedTo"} or reference) limits a user to the rows they own; the level-0 role bypasses it.

Transitions. With transition set, the action only runs while the entry's field holds one of the from values. to is informational - an updateField step does the writing.

GET /api/actions/:slug

Requires: actions read permission

One action config.

PUT /api/actions/:slug

Requires: actions update permission

Update an action.

DELETE /api/actions/:slug

Requires: actions delete permission

Delete an action.

POST /api/actions/:slug/execute

Requires: actions read permission

Run an action on one entry (the buttons on the admin's entry list). The row-level rule is checked (403 Row-level access denied), then the transition (409 when the entry has moved on). Steps run in order and stop at the first failure; steps already run are not undone.

// Request body
{ "entryId": "uuid-of-the-entry" }
// Response
{ "success": true, "stepsCompleted": 3, "results": [ { "type": "updateField", "success": true, "result": { ... } }, ... ] }
// Partial failure
{ "success": false, "stepsCompleted": 2, "results": [ ..., { "type": "webhook", "success": false, "error": "Webhook returned HTTP 500" } ] }
// Error 409 - the transition no longer applies
{ "error": "Cannot apply \"Approve Application\" - current status is \"rejected\", allowed: submitted, reviewing" }

POST /api/actions/:slug/check-access

Requires: actions read permission

Which of the given entries the row-level rule lets you run the action on.

// Request body
{ "entryIds": ["id-1", "id-2"] }
// Response
{ "allowed": ["id-1"] }

GET /api/actions/collection/:slug

Requires: actions read permission

The actions on a collection - the per-row buttons of its entry list.

Public Endpoints

POST /api/actions/:slug/public

Requires: a signed-in user (JWT) whom access.roles admits

Run an action from the public site - [cta], a [collection] with cta=, or a transition button. 401 without a token, 403 when the roles do not admit the user. The body and response are the same as /execute, plus an optional scope: "mine", which a [collection scope="mine"] block sends: a row the user did not create is then refused with 403, before the transition check (409).

GET /api/actions/transitions

Authentication optional; anonymous callers get none

The transitions a user can take on one entry right now - what an interactive [collection ... transitions] shows as buttons. Query: collection, entryId, and scope=mine from a "my entries" block. Only actions whose from matches the entry's state, whose roles admit the user and whose row-level rule passes are listed.

// Response
{ "transitions": [ { "slug": "withdraw-application", "title": "Withdraw", "trigger": { ... }, "transition": { ... } } ] }