curl --request PATCH \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Holiday Storefront"
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Holiday Storefront'})
};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}', 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}"
payload = { "name": "Holiday Storefront" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"object": "project",
"id": "clz1k8m2n0000abcd1234efgh",
"name": "Holiday Storefront",
"parentProjectId": null,
"createdAt": "2026-01-15T08:30:00.000Z",
"revision": "2026-10-20T10:15:00.000Z"
}{
"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>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "STALE_PROJECT",
"message": "This project changed after it was read. Reload before renaming.",
"status": 409
}{
"object": "error",
"code": "PRECONDITION_REQUIRED",
"message": "\"expectedUpdatedAt\" is required for delegated writes: read the current content first and pass it so the write targets exactly what was read.",
"status": 428
}Update project
Renames a project. This endpoint does not create, delete or reconfigure projects.
- Only
nameis writable: a non-empty string of at most 191 characters. - Unknown fields are rejected with
400 INVALID_PARAMSrather than silently ignored. - Send
expectedUpdatedAt(therevisionfrom GET) to fence the rename: if the project changed since that read, the call returns409 STALE_PROJECTinstead of overwriting a newer name. Shop API keys may omit it; delegated (MCP OAuth) tokens must send it or get428 PRECONDITION_REQUIRED. - Hierarchy, shop linkage and market settings belong to Studio and the Dashboard and are not writable with an API key.
- No cache invalidation happens:
namedoes not affect rendered storefront content. - Clients or proxies that cannot send
PATCHmay sendPOSTto the same URL with the same body.
Required scope: content:write
curl --request PATCH \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Holiday Storefront"
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Holiday Storefront'})
};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}', 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}"
payload = { "name": "Holiday Storefront" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"object": "project",
"id": "clz1k8m2n0000abcd1234efgh",
"name": "Holiday Storefront",
"parentProjectId": null,
"createdAt": "2026-01-15T08:30:00.000Z",
"revision": "2026-10-20T10:15:00.000Z"
}{
"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>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "STALE_PROJECT",
"message": "This project changed after it was read. Reload before renaming.",
"status": 409
}{
"object": "error",
"code": "PRECONDITION_REQUIRED",
"message": "\"expectedUpdatedAt\" is required for delegated writes: read the current content first and pass it so the write targets exactly what was read.",
"status": 428
}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.
Path Parameters
Body
New project name.
1 - 191The project revision from your last GET, sent back unchanged. When it no longer matches, the rename is refused with 409 STALE_PROJECT. Optional for shop API keys; required for delegated (MCP OAuth) tokens, which get 428 PRECONDITION_REQUIRED without it.
Response
The updated project
Was this page helpful?