curl --request GET \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId}/pages \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}/pages', 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}/pages"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"object": "list",
"data": [
{
"id": "clz4m5n6p0006qrst7890uvwx",
"type": "PRODUCT",
"handle": "blue-shirt",
"locale": "en-us",
"pageId": "clz2r7t5w0002mnop9012qrst",
"updatedAt": "2026-10-18T14:22:05.000Z",
"isTemplateMarker": false
},
{
"id": "clz4m6p7q0007qrst1234yzab",
"type": "CUSTOM",
"handle": "pages/gift-shop",
"locale": "",
"pageId": "clz2r8u6x0003mnop3456uvwx",
"updatedAt": "2026-10-19T08:03:41.000Z",
"isTemplateMarker": false
}
],
"nextCursor": null
}{
"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>"
}List page assignments
Returns the page assignments of a project, oldest first. Each assignment maps a page type + handle + locale to a pageId; several assignments can share one template page.
- Treat
type+handleas an opaque pair and pass them unchanged toGET /projects/{projectId}/pages/{type}/{handle}. Custom page handles may contain/: an entry withtype: "CUSTOM"andhandle: "pages/gift-shop"is fetched at/projects/{projectId}/pages/CUSTOM/pages/gift-shop. - The
localefilter is an exact match with no fallback. An emptylocalevalue returns400. - An unknown
typefilter or an invalid cursor returns400 INVALID_PARAMS. updatedAtis the owning page’s revision timestamp (the same value the page detail endpoint returns), so changed pages can be detected without one request per page. Assignments that share a template page report the same value. List responses are cached, so the value may briefly lag.isTemplateMarkeristruefor internal alias rows Weaverse creates to wire a custom template to its page. Markers are labelled, never filtered, so pagination stays stable; filter them client-side when you only want real storefront pages.- Inherited pages from a parent project are not listed.
- Paginate with
limit(default50, max100) andafter(the previousnextCursor).
Required scope: content:read
curl --request GET \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId}/pages \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}/pages', 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}/pages"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"object": "list",
"data": [
{
"id": "clz4m5n6p0006qrst7890uvwx",
"type": "PRODUCT",
"handle": "blue-shirt",
"locale": "en-us",
"pageId": "clz2r7t5w0002mnop9012qrst",
"updatedAt": "2026-10-18T14:22:05.000Z",
"isTemplateMarker": false
},
{
"id": "clz4m6p7q0007qrst1234yzab",
"type": "CUSTOM",
"handle": "pages/gift-shop",
"locale": "",
"pageId": "clz2r8u6x0003mnop3456uvwx",
"updatedAt": "2026-10-19T08:03:41.000Z",
"isTemplateMarker": false
}
],
"nextCursor": null
}{
"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>"
}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
Query Parameters
INDEX, PRODUCT, ALL_PRODUCTS, COLLECTION, COLLECTION_LIST, PAGE, BLOG, ARTICLE, CART, CUSTOMER, NOT_FOUND, PASSWORD, SEARCH, CUSTOM Exact locale match (e.g. "en-us"). No fallback applied on list endpoint.
x <= 100Was this page helpful?