Skip to Content
Core ConceptsDemo Mode

Demo mode

Every SeqDesk installation can host disposable demo workspaces — fully isolated, token-keyed copies of a researcher (or facility-admin) experience that anyone can spin up, poke at, and walk away from. The data lives in the same database as the rest of the install but is partitioned per token, so a demo session can’t see or affect real facility data. Six hours after its last use the workspace stops authenticating and is deleted by a cleanup job.

This is what the seqdesk.org/demo URL points at, but the same surface is available in any install — handy for training, screencasts, or letting a prospective researcher click around before they sign up.

Enabling demo mode

Demo mode is off by default. All demo routes return 404 unless the install is started with SEQDESK_ENABLE_PUBLIC_DEMO=true (the client-exposed NEXT_PUBLIC_SEQDESK_ENABLE_PUBLIC_DEMO=true works too). With the flag unset, /demo, /demo/admin, and the embed variants all notFound().

Heads up: demo bootstrap overwrites the install’s global siteSettings singleton (display name, post-submission instructions, modules config). Don’t enable the public demo flag on a production install you also use for real work — the demo seeding mutates shared site-level state, not just per-token data.

URLs

PathAudienceWhat it shows
/demoPublic researcher demoStandalone researcher dashboard with seeded sequencing orders/studies
/demo/adminPublic facility-admin demoSame install seen as a facility admin (form builders, modules, ENA settings)
/demo/embedEmbeddable researcher demoStripped-down chrome for use inside an iframe (e.g., on the marketing site)
/demo/admin/embedEmbeddable facility-admin demoThe admin experience with the same iframe-friendly chrome as /demo/embed

All flows share the same backend. The difference is just which demoExperience is requested at bootstrap and how the page chrome renders.

Lifecycle

The flow is bootstrap → use → reset (optional) → expire → cleanup.

1. Bootstrap

When a user first hits /demo, the page calls POST /api/demo/bootstrap. The server either reuses an existing workspace (matched by a token cookie) or creates a new one:

What gets createdDetail
DemoWorkspace rowNew id, fresh random token, hashed and stored as tokenHash, expiresAt set in the future
Demo userEither a researcher or facility-admin user, marked isDemo: true
Seed dataA small set of demo sequencing orders, samples, studies, and form fields — enough that the dashboard isn’t empty
Site-settings overridesDisplay name set to “SeqDesk Demo”, help text set to a “this is a disposable session” reminder
Modules configReset to defaults
Auth cookieA session token cookie scoped to the demo user, expiring at expiresAt

The bootstrap response includes:

{ "created": true, "workspaceId": "ckxx...", "expiresAt": "2026-05-12T12:00:00.000Z", "demoExperience": "researcher" }

2. Use

From this point on, every API request the demo session makes carries the session cookie. Server-side, isDemoSession() checks the user.isDemo flag and disables a small number of features that don’t make sense in a sandbox (see Restrictions).

3. Reset

A logged-in demo user can call POST /api/demo/reset to wipe their workspace and re-seed. The same workspaceId is kept; the auth session token is re-issued. Useful when a demo gets “messy” mid-walkthrough.

4. Expire

Each DemoWorkspace.expiresAt is set to 6 hours in the future (DEMO_SESSION_TTL_HOURS). It is a sliding window, not a fixed one: every time the workspace is bootstrapped or reused, SeqDesk pushes expiresAt six hours out again and stamps lastSeenAt. A demo left open all afternoon keeps working; a demo abandoned for six hours stops. Once the window passes, the session cookie no longer authenticates and the workspace becomes a candidate for deletion.

5. Cleanup

GET /api/demo/cleanup deletes every DemoWorkspace whose expiresAt is in the past. The endpoint is gated behind a Bearer token check so it can be wired to a cron job (Vercel Cron, GitHub Actions, systemd timer) without exposing the cleanup ability to anonymous traffic. The expected secret comes from CRON_SECRET (or DEMO_CLEANUP_SECRET as an alias); the request must send Authorization: Bearer <that value>. In non-production environments with no secret configured the endpoint is open, to keep local testing simple. A typical setup runs it every 15 minutes.

Embed mode

/demo/embed renders the same researcher demo with chrome simplified for iframe embedding:

  • Top navigation collapsed
  • Branded SeqDesk header hidden
  • Sidebar minimized

The marketing site at seqdesk.org embeds this view to give visitors a working demo without leaving the page. The bootstrap, reset, and expiry flows are identical to the standalone /demo route — only the layout differs. There is also a /demo/admin/embed variant that renders the facility-admin demo with the same iframe-friendly chrome.

Restrictions

Anything that touches real storage, real compute, or a real delivery decision is switched off for a demo session. The server checks isDemoSession() (the user.isDemo flag) and returns 403 with an explanatory message:

EndpointMessage
GET /api/files/downloadDownloads are disabled in the public demo.
GET /api/files/previewPreview is not available for this file in the demo. — except for the bundled demo pipeline reports, which are served
GET /api/assembliesAssemblies are disabled in the public demo. The Assemblies page renders a notice instead of the table
POST /api/pipelines/runs and …/[id]/startPipeline creation and launch are blocked
…/[id]/resolve-outputs, …/cleaned-reads, …/pending-writebacksOutput resolution and read write-back are blocked
…/[id]/selection (PUT / DELETE)Pipeline result selection is disabled in the public demo.
…/[id]/delete, …/[id]/sync, …/[id]/debugRun maintenance is blocked
POST/DELETE /api/orders/[id]/sequencing/delivery/publicationSequencing delivery publication is disabled in the public demo.
POST /api/orders/[id]/files/inspectFilesystem inspection is blocked

Pipelines can therefore be browsed — the seeded runs, their DAGs, their reports — but never executed.

ENA submission is not specially gated for demo sessions. It is harmless in practice because SiteSettings.enaTestMode defaults to true and a demo workspace never has Webin credentials, so a submission attempt targets the ENA test server and fails on authentication. Do not rely on that as a safety mechanism on an install that does have production credentials configured — which is another reason not to enable the public demo flag on a working instance.

Everything else — clicking through sequencing orders, editing forms, browsing studies, running MIxS validation — behaves exactly like the real application.

DemoWorkspace fields

Defined at prisma/schema.prisma:

FieldTypePurpose
idcuidWorkspace identifier
tokenHashunique stringSHA-256 of the bootstrap token; the raw token only lives in the browser cookie
userIdunique stringResearcher User row owned by this workspace
adminUserIdoptional stringFacility-admin User row, populated for admin demos
seedVersionintBumped when the seeder schema changes, used for migrations
lastSeenAtdatetimeUpdated on each request — useful for “active demos” telemetry
expiresAtdatetime, indexedCleanup query target
createdAt / updatedAtdatetimeStandard timestamps

Operating a public demo

A typical configuration for a public-facing demo:

# Run the cleanup endpoint every 15 minutes */15 * * * * curl -fsS -H "Authorization: Bearer $CRON_SECRET" \ https://your-host/api/demo/cleanup

Set CRON_SECRET (or DEMO_CLEANUP_SECRET) in the demo install’s environment to the same value the cron sends, plus SEQDESK_ENABLE_PUBLIC_DEMO=true to expose the demo routes at all. Workspace expiry is 6 hours (DEMO_SESSION_TTL_HOURS) and is baked into the build; rebuild the install to change it.

Run the demo on its own install with its own database. The bootstrap step rewrites the global siteSettings singleton and resets the modules configuration, so a demo and a working facility cannot share an instance.

When to use it

  • Onboarding — give new researchers a working sandbox before exposing them to production.
  • Marketing — embed /demo/embed on a landing page; visitors can interact with a fully functional SeqDesk without account creation.
  • Training & screencasts — record against /demo so the reset flow gives you a clean state between takes.
  • Bug repro — pipeline launches and file downloads are gated, but everything else (form configuration, MIxS validation, study workflows) reproduces faithfully.

When not to use it

  • On a production install. Bootstrap mutates shared site-level state.
  • To demonstrate pipeline execution. Runs cannot be launched; only the seeded example runs are browsable.
  • As a staging environment. Workspaces are deleted six hours after their last use, and there is no way to extend or export one.