Skip to content

Runtimes & capabilities

Preview Every site carries a runtime, and each runtime advertises a set of capabilities — the actions it can actually perform. A client asks a site what it can do and branches on the answer, instead of hard-coding if runtime == "wordpress". This page is the reference matrix: which capability each runtime supports, and what “no” means when it doesn’t.

The platform answers the question for you. Call GET /v1/sites/{id}/capabilities for one site, or GET /v1/runtimes for the static catalog of every runtime and its default capabilities and component kinds.

GET /v1/sites/site_01J7.../capabilities
{ "data": {
"runtime": "wordpress", "runtime_version": "6.8",
"capabilities": {
"components.plugins": { "supported": true, "actions": ["list","install","activate","update","delete"] },
"components.themes": { "supported": true, "actions": ["list","activate","update","delete"] },
"components.users": { "supported": true },
"components.content": { "supported": true },
"cron": { "supported": true, "kind": "wp-cron" },
"database": { "supported": true, "engine": "mysql" },
"exec": { "supported": true, "shells": ["wp-cli","bash"] },
"magic_link": { "supported": true },
"clone_content": { "supported": true, "selectors": ["db","files"] },
"build": { "supported": true }
} } }

Rows are runtimes; columns are capabilities. A cell shows the supported actions, or false when the runtime can’t do it at all.

Capability wordpress static drupal roadmapnode roadmap
components.plugins list · install · activate · update · delete false false false
components.themes list · activate · update · delete false activate · update false
components.modules false false list · install · enable · update false
components.users CRUD false CRUD false
components.content posts · pages · media false nodes · media false
cron wp-cron false drush-cron scheduler
database mysql false mysql/postgres false
exec wp-cli · bash false drush · bash bash
magic_link SSO into wp-admin false SSO into /user false
clone_content db · files files db · files files
build supported supported supported supported

A capability being unavailable is reported one of two ways, and the difference is deliberate — see errors:

  • Structurally absent → 404. The capability doesn’t exist on this runtime and a scope-limited key couldn’t even hold a scope for it. Asking a static site for its plugins returns not_found, the same as a resource you can’t see — existence hiding.
  • Route exists, runtime can’t → 409 environment.capability_unsupported. The endpoint is real and you’re allowed to call it, but this runtime can’t perform the action. Installing a plugin on a static site is a 409, with param naming the offending field.

Discover capabilities first and you avoid both — the matrix and the discovery endpoint exist precisely so you never have to guess.

The whole point of this model is that a new runtime inherits the entire platform — auth, jobs, SSE, observability, billing — for free. Bringing one online is two pieces of work, neither of which touches the foundational resources:

  1. A runtime-catalog entry describing its default capabilities and component kinds (what GET /v1/runtimes returns).
  2. A capability provider on the agent side that implements those capabilities — e.g. mapping components.modules to drush.

No new endpoints, no new scopes, no foundation change. A static site and a WordPress site are the same resource type with different advertised capabilities — that’s the entire trick. See build runtimes for how detection and the build pipeline fit in.