The publish flow
1
Check the head version
POST /v1/websiteSourceCode/head/check runs the framework quality gate without changing anything: format, typecheck, lint, build, and a server-render of every page. It returns { "version": 12, "ok": true } or { "version": 12, "ok": false, "message": "...", "details": { ... } } describing what to fix.2
Publish
POST /v1/websiteSourceCode/head/publish with { "websiteId": "...", "leaseToken": "..." } validates the head version, builds it in a sandbox, and promotes it. Publishing requires an active edit lease.3
Wait for the deployment
The publish response includes the deployment. Its status is
building, ready, or failed. You can poll POST /v1/websiteSourceCode/deployment/status with { "websiteId": "...", "target": "published" } at any time.4
Verify the live site
On success,
publishedVersion moves to the published head version. Open the platform subdomain and confirm the change. See Domains.Run
head/check before every publish. It surfaces framework validation errors cheaply, without holding the live site’s fate on a build.head/check and head/publish run real builds and use the expensive rate-limit class. See Rate limits.
Unpublish a site
POST /v1/websiteSourceCode/published/unpublish with { "websiteId": "..." } takes the site offline on its platform and custom domains. Cached pages may take a few minutes to disappear. It clears publishedVersion without changing head, deleting the built deployment, or rewriting version history. No edit lease or rebuild is required.
Unpublish is the fastest recovery when nothing should remain public, including when an agent published without approval. Publish head again whenever the site is ready to return.
What the head check covers
The check goes past compilation. After formatting, typechecking, linting, and bundling, it server-renders every page in the build, including dynamic routes such as/blog/:slug, and reports the pages that threw.
Rendering needs page data, so the check synthesizes placeholder content from your CMS schema rather than reading CMS items. Each query a page declares becomes a sample item, or a one-item list, built from that collection’s field definitions, and each route parameter gets a placeholder value. That has two consequences:
- The result depends only on your source and your CMS schema. Identical source checks identically every time, and a page never fails the gate because of one unusual CMS row.
- The check catches render-time failures such as browser-only globals like
window, invalid hook usage, and libraries that do not render on the server. It does not catch failures that depend on specific content.
renderFailures, one entry per page:
Deployment statuses
The status response includes whether pages exist, the availablepageId and route values, an opaque preview revision, and whether the draft is ready to publish.
What can go wrong
Publish is designed to fail safe: if any step fails,publishedVersion does not move and the live site keeps serving the previous published version.
Publish can rewrite head once: if the framework returns canonical formatting or normalized route literals, the formatted files are committed as a new head version before promotion. The response then includes
"message": "Source formatting was applied before publishing." — your published version may be one higher than the head you started from.Recovery paths
Both recovery operations require an edit lease, and both preserve history. Versions are append-only, so nothing is ever overwritten.Restore head to a previous state
POST /v1/websiteSourceCode/head/restore copies an earlier state’s files into a new head version without touching the live site. Pass { "to": "published" } to discard draft work when the live site is the state you trust (404 Website has no published version on a never-published website), or { "to": "38" } for any historical version between 1 and the current headVersion (anything higher returns 400 Version does not exist). Publish afterward if you want it live.
Roll back the published site
POST /v1/websiteSourceCode/published/rollback-version with { "version": 38 } re-publishes a prior version directly: it validates and builds that version, commits it as the new head, and moves publishedVersion to it. This is the fast path when a bad publish is live. It runs the same quality gate and build as a normal publish, so it can fail the same ways.
Prepare a build
POST /v1/websiteSourceCode/deployment/ensure with { "target": "head" } or { "target": "published" } prepares that version without publishing it. Draft pages do this automatically. If a draft build fails, use the retry action shown on the draft page.
Next steps
Roll back and recover
Step-by-step recovery from bad publishes and failed builds.
Agent-safe publishing
Draft-first workflows and approval checkpoints for agents.