Skip to content

Powered by Grav + Helios

Demo Mode

Demo Mode

Control the demo-mode reset engine, for public demo sites. A demo account is any account with access.api.demo set. Demo accounts can read, but writes are blocked except for the permissions listed in plugins.api.demo.writable, and some reads that reveal server paths or other visitors' data are hi...

Control the demo-mode reset engine, for public demo sites. A demo account is any account with access.api.demo set. Demo accounts can read, but writes are blocked except for the permissions listed in plugins.api.demo.writable, and some reads that reveal server paths or other visitors' data are hidden from them.

A baseline is a snapshot of the content folders that demo accounts can write to. Once one is captured, the demo content is put back to it every reset_interval minutes, either lazily during API requests (reset_on_request) or by a scheduler job (reset_on_schedule), or both. Nothing is reset until a baseline exists.

Permissions: Demo Status needs any authenticated account. Capture Baseline and Reset Demo need a super admin (a scoped API key needs the admin.super scope), and demo accounts are always refused on them, even when they are super, so a visitor can't save a vandalized state as the baseline or force a reset.

Status fields

All three routes return the same status object:

Field Meaning
baseline_exists Whether a baseline has been captured
writable The permissions a demo account may still use for writes (plugins.api.demo.writable, default api.pages.write and api.media.write)
roots The content folders those permissions map to and that a reset restores: pages (user/pages), media (user/media) and data (user/data, for api.flex* permissions), where they exist
reset_interval Minutes between resets
reset_on_request Whether stale content is reset lazily during API requests
reset_on_schedule Whether a scheduler job performs resets
last_reset Unix timestamp of the last reset, or null if none has run
seconds_until_reset Seconds until the next reset is due; 0 means due now, null when there is no baseline

Demo Status

GET /demo/status
The demo-mode reset state that drives the Admin Next demo banner and its countdown. Any authenticated account can call it; no specific permission is needed. See the [collection introduction](/2/api/endpoints/demo) for the fields.
JSON
{"data": {"baseline_exists": true, "writable": ["api.pages.write", "api.media.write"], "roots": ["pages", "media"], "reset_interval": 30, "reset_on_request": true, "reset_on_schedule": true, "last_reset": 1790000000, "seconds_until_reset": 1234}}

Response Codes

200 Status returned.
401 Unauthorized.

Capture Baseline

POST /demo/baseline
Snapshot the writable demo content folders as the baseline that resets restore. When `plugins.api.demo.writable` maps to no existing content folder nothing is captured and `captured` is `false`, still with a 200. On success it fires `onApiDemoBaselineCaptured` and sends `X-Invalidates: demo:status`. Requires a super admin (a scoped API key needs the `admin.super` scope); demo accounts get 403 even when they are super.
JSON
{"data": {"captured": true, "message": "Demo baseline captured.", "status": {"baseline_exists": true, "writable": ["api.pages.write", "api.media.write"], "roots": ["pages", "media"], "reset_interval": 30, "reset_on_request": true, "reset_on_schedule": true, "last_reset": 1790000000, "seconds_until_reset": 1800}}}

Response Codes

200 Capture attempted; `captured` says whether a baseline was saved.
401 Unauthorized.
403 Not a super admin, a scoped key without `admin.super`, or a demo account.

When nothing was captured, message is "No writable demo resources are configured, so there is nothing to capture."

Capturing replaces any previous baseline and restarts the reset timer, so last_reset is set to the capture time.

Reset Demo

POST /demo/reset
Restore the demo content from the captured baseline now, waiting for any background reset already in progress. Without a baseline nothing happens and `reset` is `false`, still with a 200. Fires `onApiDemoReset` and sends `X-Invalidates: demo:status`. Requires a super admin (a scoped API key needs the `admin.super` scope); demo accounts get 403 even when they are super.
JSON
{"data": {"reset": true, "message": "Demo content reset to baseline.", "status": {"baseline_exists": true, "writable": ["api.pages.write", "api.media.write"], "roots": ["pages", "media"], "reset_interval": 30, "reset_on_request": true, "reset_on_schedule": true, "last_reset": 1790000000, "seconds_until_reset": 1800}}}

Response Codes

200 Reset attempted; `reset` says whether content was restored.
401 Unauthorized.
403 Not a super admin, a scoped key without `admin.super`, or a demo account.