Divine

REST API

View as Markdown

Divine exposes a REST surface under /wp-json/divine/v1/ that powers the admin workspace and gives integrations a stable, versioned way to manage apps and worktrees, browse and edit theme code, read git history, persist workspace state, export standalone themes, and render capturable previews. It is the same surface the canvas, browser, code, review, history, and export views call.

/wp-json/divine/v1/

Authenticate browser requests from the admin with the standard WordPress REST nonce, and authenticate remote requests with WordPress authentication, typically an Application Password tied to a real user that holds the Divine management capability.

Permissions

Authorization follows WordPress identity through one management capability that the active workspace backend selects. On a single-site install that capability is manage_options; on a multisite install Divine runs from network admin and the capability is manage_network. Every route below is gated by that capability at the route boundary. The one exception is the show render routes, which also accept a valid signed preview token so a shared render URL can be opened without an admin session.

Route group Permission
Apps Divine management capability (manage_options / manage_network)
Worktrees Divine management capability
Builder / Canvas Divine management capability
Code Divine management capability
Git history Divine management capability
Browser state Divine management capability; state is scoped to the current user
Export Divine management capability
Show Divine management capability, or a valid signed show token for the target

Apps

The apps routes list the registered Divine apps the workspace can open and create a new app by cloning an existing one. On a single-site install an app is the active WordPress theme; on multisite an app is a network site with its active theme.

GET  /wp-json/divine/v1/apps
POST /wp-json/divine/v1/apps

A GET returns each app with its label, stylesheet, logo, and site and admin URLs. A POST creates an app by cloning another; send the new name and slug and the clone_from app to copy.

Worktrees

The worktree routes manage the git-backed theme copies an app is edited through. A worktree lives under wp-content/themes/<worktree-id>, and these routes list and create them, read and write individual worktree files, deploy a worktree’s files into the app theme, and destroy a worktree without deploying it.

You list and create worktrees per app.

GET  /wp-json/divine/v1/apps/{app_slug}/worktrees
POST /wp-json/divine/v1/apps/{app_slug}/worktrees

A single worktree is destroyed by ID. Destroy removes the worktree theme directory and its registry record without promoting any work.

DELETE /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}

Deploy promotes the worktree’s files into the paired app theme. On multisite it targets the selected site’s active theme only, and it never copies database state. The body may carry a deploy label, notes, and the resolved_files selection.

POST /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/deploy

The worktree file routes back the review surface. The diff route returns a unified diff for one changed file named by the path query parameter, and the file route reads the current and base contents of one file or writes a resolved file back into the worktree workspace.

GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/file-diff?path={path}
GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/file?path={path}
PUT /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/file

A PUT sends the file path, its contents, and an optional delete flag to remove the file rather than write it.

{
  "path": "pages/home/index.php",
  "contents": "<?php // resolved file body",
  "delete": false
}

Builder

The builder routes return the static canvas snapshots the workspace renders, for both a main app environment and one worktree environment. The pages route returns the Blockstudio page and block snapshots, the manifest route returns lightweight page and block modification times so the client can detect what changed cheaply, and the item route returns one page or block snapshot named by its source and id query parameters.

GET /wp-json/divine/v1/apps/{app_slug}/builder/pages
GET /wp-json/divine/v1/apps/{app_slug}/builder/pages/manifest
GET /wp-json/divine/v1/apps/{app_slug}/builder/pages/item

The same three snapshots exist for a worktree environment under its worktree ID.

GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/builder/pages
GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/builder/pages/manifest
GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/builder/pages/item

Code

The code routes back the code browser. The tree route returns the browsable file tree for an app, and the file route returns one file’s contents named by its path query parameter. Worktree file writes go through the worktree code file route, which reads the same way and writes on PUT.

GET /wp-json/divine/v1/apps/{app_slug}/code/tree
GET /wp-json/divine/v1/apps/{app_slug}/code/file?path={path}

The worktree variants browse and edit a worktree’s files.

GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/code/tree
GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/code/file?path={path}
PUT /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/code/file

A PUT sends the file path and its contents.

{
  "path": "blocks/hero/index.php",
  "contents": "<?php // block body"
}

Git History

The git-history routes back the history view for both apps and worktrees. The list route returns the recent commits, accepting an optional limit query parameter and an optional worktree_id to scope history to a worktree. The commit route returns the detail for one commit by its hash, and the file route returns one file’s content at that commit, named by the path query parameter. Both detail routes accept an optional parent to diff against.

GET /wp-json/divine/v1/apps/{app_slug}/git-history
GET /wp-json/divine/v1/apps/{app_slug}/git-history/{commit}
GET /wp-json/divine/v1/apps/{app_slug}/git-history/{commit}/file?path={path}

The {commit} segment is a hexadecimal commit hash between 7 and 64 characters.

Browser State

The browser-state routes persist the admin browser tabs for the current WordPress user. The collection route reads the full state map for the user or clears it, and the scoped route writes one workspace scope’s panel state. State is stored in the user’s meta, so one reviewer’s tabs do not affect another’s.

GET    /wp-json/divine/v1/browser-state
DELETE /wp-json/divine/v1/browser-state
PUT    /wp-json/divine/v1/browser-state/{scope_key}

A PUT sends the panel state for that scope_key, and the response returns the full updated state map.

Export

The export routes build the standalone, client-ready theme zip. Export bundles a copy of the Divine runtime into the theme so the exported theme runs on a site with no Divine plugin installed, and writes provenance and third-party license files alongside it. You export either an app’s current theme or a specific worktree.

POST /wp-json/divine/v1/apps/{app_slug}/export
POST /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/export

A successful export returns 201 with the exported theme_slug, the zip filename, a download_url, the size in bytes, and the sha256 of the archive.

Show

The show routes return capturable render documents for a page or block, and a labeled side-by-side compare document. They are the REST side of the dv show CLI: the CLI prints a URL, and the agent or browser tool that opens it captures the result. These routes are the one place the management capability is not required on its own. A request is allowed when the current user can manage Divine, or when it carries a valid signed show token for the target, which is what lets a shared render URL be opened without an admin session. The token is passed as a query parameter, and an invalid or missing token on a non-admin request returns 403.

The page and block render routes exist for both a main app environment and a worktree environment. They return an isolated HTML document with a text/html content type. The page route also accepts mode=live, which redirects to a signed preview URL of the real page instead of the virtual render; blocks render only as the virtual document.

GET /wp-json/divine/v1/apps/{app_slug}/show/page/{id}
GET /wp-json/divine/v1/apps/{app_slug}/show/block/{id}
GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/show/page/{id}
GET /wp-json/divine/v1/apps/{app_slug}/worktrees/{worktree_id}/show/block/{id}

The compare route renders several targets together as one labeled document. The targets, their tokens, and their labels are carried in the encoded targets query parameter, and an optional width sizes the document.

GET /wp-json/divine/v1/show/compare

Error Responses

Divine REST handlers return JSON error bodies with a code and a message and an appropriate HTTP status, so you can handle them with the same conventions as the rest of the WordPress REST API. Validation failures return 400 with a route-specific code such as divine_invalid_worktree, divine_invalid_worktree_file, divine_invalid_code_workspace, divine_invalid_git_history, or divine_invalid_show_target; a forbidden show request returns 403 with divine_forbidden; and an unexpected export failure returns 500 with divine_theme_export_failed.