Approval Workflows
An approval workflow gates publishing behind one or more review steps, instead of a save-and-publish going live immediately. It's configured once — at the Department level, optionally overridden per Project — and then every publish attempt against a gated Project is checked against it automatically.
No workflow configured means direct publish
Approval workflows are additive, not a breaking change: a Project whose Department has no workflow configured (and no Project-level override) publishes exactly as it always has, with no gate at all. You only see approval behavior once you explicitly configure a workflow.
Where a workflow is configured
A workflow can be configured at two levels, and VeroXM resolves which one actually governs a given Project's publishes:
- Department level — the default. Configure it from the Department's page; it governs every Project inside that Department unless a Project overrides it. Only a Tenant Admin (or Super Admin) can configure or remove a Department's workflow — a Department Admin can see it, but can't loosen or remove the gate governing their own Department.
- Project level — an optional override, configured from the Project's Members & Access page. When set, it fully replaces the Department's workflow for that one Project — it doesn't merge with it or add extra steps. Removing the override falls straight back to the Department's workflow, with nothing else to clean up. Configuring or removing a Project-level override also requires a Tenant Admin (or Super Admin) — the same restriction as the Department level, and for the same reason: a Project-level override that fully replaces a Department's policy is just as much "the gate governing this Department" as the Department-level workflow itself.
If a Project has no Department at all, only a Super Admin can configure or view its workflow.
Steps
A workflow is an ordered list of steps; content must pass every step, in order, before it publishes. Each step has:
- Required role kind — the "floor" tier that can act on this step: Project Admin, Department Admin, or Tenant Admin (of the relevant scope — the Project, its Department, or its Tenant respectively). This is the only requirement a step needs by default.
- Named approver (optional) — narrows the step further to a specific custom role in the Department (for example, "Brand Reviewer" or "Compliance Lead"), for release-governance-style workflows with business-named approvers rather than generic role tiers. When set, this replaces the role-kind check for that step rather than adding to it.
- Allow revision and allow rejection — per-step toggles (both default on) controlling whether that step's reviewer can send content back for changes, reject it outright, or both.
Submitting, approving, and rejecting
Checking a content entry's Published box (or calling the publish route) on a Project with an active workflow doesn't publish the entry directly — it creates an approval request instead, and the entry stays a Draft until every step approves. Re-checking Published while a request is already pending doesn't create a second one; unchecking it withdraws the request in flight.
- Approve — advances the request to the next step. Approving the last step publishes the entry immediately, unless the request has a scheduled publish time (below), in which case it's marked approved and published automatically once that time arrives.
- Reject — ends the request outright and returns the entry to Draft, with the reviewer's comment as feedback.
- Request revision — structurally similar to reject (ends the request, returns to Draft), but recorded as its own action so the difference between "send this back with feedback" and "reject" stays visible in the audit trail. A comment is required.
Resubmitting after a rejection or a revision request starts a brand-new request at step 1 — there's no partial credit for steps already passed before the rejection.
Release integrity and scheduling
Each request captures the exact content it's reviewing at submission time (a content hash and snapshot), and every approve, reject, or revision action is stamped with the content's hash at that moment — so a request can't silently drift from what reviewers actually saw. Every request is also assigned a release number (CR-2026-142, for example) as soon as it's submitted, for tracking in change-management processes outside VeroXM.
A request can optionally carry a scheduled publish time. Once it reaches final approval, it's marked approved and published automatically when that time arrives, rather than immediately — or published early with a manual Publish now action once it's already approved.
My Approvals
The dashboard's My Approvals page is a cross-project inbox: every pending request currently waiting on you, across every Project you have access to, plus summary counts — so reviewing releases doesn't mean checking each Project individually.
API reference
These routes are part of VeroXM's dashboard-session API (authenticated as a signed-in user, the same way the rest of the dashboard is) — not the public, bearer-token Content API covered elsewhere in these docs.
GET /departments/:departmentId/approval-workflow
PUT /departments/:departmentId/approval-workflow { steps: [...] }
DELETE /departments/:departmentId/approval-workflow
GET /projects/:projectId/approval-workflow
PUT /projects/:projectId/approval-workflow { steps: [...] }
DELETE /projects/:projectId/approval-workflowGET /projects/:projectId/collections/:collectionId/content/:id/approval
POST /projects/:projectId/collections/:collectionId/content/:id/approval/approve
POST /projects/:projectId/collections/:collectionId/content/:id/approval/reject
POST /projects/:projectId/collections/:collectionId/content/:id/approval/request-revision
POST /projects/:projectId/collections/:collectionId/content/:id/approval/publish-nowGET /approvals/pending
GET /approvals/summaryA steps array element is { stepOrder, requiredRoleKind, requiredCustomRoleId?, stepLabel?, allowRevision?, allowRejection? }, where requiredRoleKind is one of admin (Project Admin), department_admin, or tenant_admin. Saving replaces the entire step list — there's no separate endpoint to patch a single step.