curl --request GET \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId}/page-drafts/{pageId} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}/page-drafts/{pageId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://studio.weaverse.io/api/v1/content/projects/{projectId}/page-drafts/{pageId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"object": "page_draft",
"pageId": "clz7pg9k2m4n6p8r0t2v4x6z",
"projectId": "clz7prj0a1b2c3d4e5f6g7h8",
"name": "Home",
"rootId": "root-1",
"items": [
{
"id": "root-1",
"type": "main",
"children": [
{
"id": "hero-1"
}
],
"data": {}
},
{
"id": "hero-1",
"type": "hero-image",
"data": {
"heading": "Summer collection",
"height": "large"
}
}
],
"pageUpdatedAt": "2026-10-08T10:00:00.000Z",
"projectUpdatedAt": "2026-10-08T09:00:00.000Z",
"headVersionId": "clz9drf1q3s5u7w9y1a3c5e7"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}Get a page's editable content and revision tokens
Returns the content you should edit for one page, plus the revision tokens that a later save must send back unchanged. This is step 1 of draft-first editing.
Workflow. Drafts and publishing work together like this:
GET /projects/{projectId}/page-drafts/{pageId}reads the editable content and its revision tokens.PUTon the same path saves a new draft head (versionId). Live content is not touched.- Publish the draft with
POST /publish-versions/{versionId}, or schedule it withPOST /versions/{versionId}/schedule. - Manage history and the schedule with
GET /projects/{projectId}/versions,/versions/{versionId}(read, reschedule, replace content, cancel),publish-nowandrestore.
What is returned
- When the page has a draft head: the draft’s items, with
headVersionIdset to that draft.pageUpdatedAtandprojectUpdatedAtare the live revisions the draft was built on, not the current live revisions. If live content has changed since the draft was saved, a save from this read is refused with 409STALE_PAGE, so a draft can never quietly publish over a newer live edit. - When there is no draft: the live items, with
headVersionId: nulland the current livepageUpdatedAt/projectUpdatedAt. - Items are a flat list. Each item has
id,type,dataandchildren(child id references).rootIdnames the root item. pageUpdatedAtorprojectUpdatedAtisnullfor a legacy row whose revision was never set. Send thatnullback as is. A read never repairs it.
Addressing. The page is addressed by pageId only. There is no locale or handle fallback, so a draft can never be read from or saved onto another assignment. A page that is not a live page of this project, or a draft head whose snapshot cannot be read, returns 404.
Required scope: content:read
curl --request GET \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId}/page-drafts/{pageId} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}/page-drafts/{pageId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://studio.weaverse.io/api/v1/content/projects/{projectId}/page-drafts/{pageId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"object": "page_draft",
"pageId": "clz7pg9k2m4n6p8r0t2v4x6z",
"projectId": "clz7prj0a1b2c3d4e5f6g7h8",
"name": "Home",
"rootId": "root-1",
"items": [
{
"id": "root-1",
"type": "main",
"children": [
{
"id": "hero-1"
}
],
"data": {}
},
{
"id": "hero-1",
"type": "hero-image",
"data": {
"heading": "Summer collection",
"height": "large"
}
}
],
"pageUpdatedAt": "2026-10-08T10:00:00.000Z",
"projectUpdatedAt": "2026-10-08T09:00:00.000Z",
"headVersionId": "clz9drf1q3s5u7w9y1a3c5e7"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}Authorizations
Bearer authentication: a shop API key (WEAVERSE_API_KEY), a scoped API key, a delegated MCP OAuth token, or (translation-unit routes only) a project-bound translation agent token. Scopes: content:read — Read projects, pages, theme settings, versions, drafts and translation units. content:write — Save drafts and make non-destructive edits (page items, metadata, SEO, assignments, languages, glossary). Never publishes or deletes. content:publish — Publish drafts, schedule/reschedule/cancel publications, restore versions, publish global sections. content:delete — Delete pages, global sections, languages, static keys, override reverts; required with project:manage for project deletion. project:manage — Create/copy/delete projects, settings, variants, hierarchy, backups, restore-as-new, previews, hostname policy. translations:read — Read translation units only (no general content access). translations:write — Apply translation units only; never mutates page content. A legacy unscoped API key keeps read/write/translation baseline access and every pre-scope endpoint, but never gains publish/delete/project-manage implicitly.
Response
Draft basis (draft snapshot or live items)
The response is of type object.
Was this page helpful?