Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.weaverse.io/llms.txt

Use this file to discover all available pages before exploring further.

Get Page

GET /api/v1/content/projects/:projectId/pages/:type/:handle
Returns the full page content including all component items. This is the primary endpoint for rendering Weaverse pages in external applications.

Authentication

Requires a Content API key. See Authentication.

Path parameters

ParameterTypeRequiredDescription
projectIdstringYesThe project ID
typestringYesPage type (e.g., INDEX, PRODUCT, COLLECTION)
handlestringYesPage handle (e.g., default, blue-shirt)

Query parameters

ParameterTypeDefaultDescription
localestring""Locale code for localized content (e.g., en-us, fr-fr)
formatweaverse | portable-textweaverseOutput format. See Portable Text format below.
metabooleanfalseWhen true and format=portable-text, each block carries a _weaverse: { id, schemaVersion } field for round-tripping back to the original Weaverse item.
The format can also be requested via the Accept header (application/portable-text+json). The query parameter takes precedence when both are present.

Locale fallback

When a page is not found for the requested locale, the API falls back in order:
  1. Requested locale (e.g., fr-fr)
  2. Project’s default locale
  3. English default
If no assignment is found after all fallbacks, a 404 is returned.

Response

{
  "object": "page",
  "id": "clz5wxy12abc345defg",
  "type": "PRODUCT",
  "handle": "blue-shirt",
  "locale": "en-us",
  "items": [
    {
      "id": "019503a2-c4b6-7c9d-8e3f-1a2b3c4d5e6f",
      "type": "root",
      "data": {},
      "children": [{ "id": "01950b17-d8a3-7f1e-9c4b-2d6e8f0a1b3c" }, { "id": "01950c4e-a1b2-7d3f-8e9c-4a5b6c7d8e9f" }]
    },
    {
      "id": "01950b17-d8a3-7f1e-9c4b-2d6e8f0a1b3c",
      "type": "hero-banner",
      "data": {
        "title": "Summer Collection",
        "subtitle": "New arrivals for the season",
        "backgroundImage": "https://cdn.shopify.com/...",
        "buttonText": "Shop Now",
        "buttonLink": "/collections/summer"
      },
      "children": null
    },
    {
      "id": "01950c4e-a1b2-7d3f-8e9c-4a5b6c7d8e9f",
      "type": "product-details",
      "data": {
        "showPrice": true,
        "showVariants": true,
        "layout": "two-column"
      },
      "children": null
    }
  ],
  "updatedAt": "2026-03-20T10:30:00.000Z",
  "meta": {
    "inherited": false,
    "sourceProjectId": "clx1abc23def456ghij",
    "depth": 0
  }
}

Response fields

FieldTypeDescription
objectstringAlways "page"
idstring | nullPage ID
typestringPage type
handlestringPage handle
localestringResolved locale
itemsarrayArray of component items (see below)
updatedAtstring | nullISO 8601 timestamp of last update
metaobjectMetadata about content inheritance
meta.inheritedbooleanWhether this page was inherited from a parent project
meta.sourceProjectIdstringProject that owns this page content
meta.depthnumberInheritance depth (0 = own content)

Item structure

Each item in the items array represents a page section or component:
FieldTypeDescription
idstringUnique item ID
typestringComponent type identifier (e.g., hero-banner, product-details)
dataobjectComponent settings and content configured in the editor
childrenJSON | nullChild item references for nested layouts (passed through from the database as-is; null when the item has no children)
The items array is a flat list. Use the children field on each item to reconstruct the component tree. The item with type: "root" is the tree’s entry point.

Portable Text format

Pass ?format=portable-text (or Accept: application/portable-text+json) to receive the page as a Portable Text array. This format is designed for multi-channel rendering (web, native, email, PDF) and AI consumption — rich-text fields are converted from opaque HTML strings into structured blocks that any official PT renderer can render.

Envelope difference

The items field becomes content, and the response carries Content-Type: application/portable-text+json. All other envelope fields are unchanged.
{
  "object": "page",
  "id": "clz5wxy12abc345defg",
  "type": "PRODUCT",
  "handle": "blue-shirt",
  "locale": "en-us",
  "content": [ /* Portable Text blocks — see below */ ],
  "updatedAt": "2026-03-20T10:30:00.000Z",
  "meta": { "inherited": false, "sourceProjectId": "...", "depth": 0 }
}

Mapping rules

Each Weaverse item becomes a custom Portable Text block:
WeaversePortable Text
type_type
id_key (truncated to 8 chars; full id available in _weaverse.id when ?meta=true)
data.* fieldsflattened onto the block root
nested childrenchildren: PTBlock[] on the parent block
HTML-valued field (richtext)array of standard PT text blocks with marks, markDefs, style, listItem
Synthetic root itemdropped — its children become the top-level content array
Field types other than richtext (text, image URL, color, range, switch, product/collection refs, etc.) pass through unchanged.

Example

{
  "content": [
    {
      "_type": "hero-banner",
      "_key": "01950b17",
      "backgroundImage": "https://cdn.shopify.com/hero.jpg",
      "overlayOpacity": 40,
      "children": [
        { "_type": "heading", "_key": "01950c22", "text": "Summer 2026", "level": "h1" },
        {
          "_type": "text-section",
          "_key": "01950d55",
          "content": [
            {
              "_type": "block",
              "_key": "b1",
              "style": "normal",
              "children": [
                { "_type": "span", "_key": "s1", "text": "Read the " },
                { "_type": "span", "_key": "s2", "text": "documentation", "marks": ["link1"] },
                { "_type": "span", "_key": "s3", "text": " for details." }
              ],
              "markDefs": [
                { "_type": "link", "_key": "link1", "href": "/docs" }
              ]
            }
          ]
        }
      ]
    }
  ]
}
Note how the text-section’s content field — originally an HTML string — is now a queryable array of PT blocks with explicit marks and link annotations.

Rendering with @portabletext/react

import { PortableText } from '@portabletext/react'

const components = {
  types: {
    'hero-banner': HeroBanner,
    'heading': Heading,
    'text-section': TextSection,
  },
  marks: {
    link: ({ children, value }) => <a href={value.href}>{children}</a>,
  },
}

function Page({ content }) {
  return <PortableText value={content} components={components} />
}
Official renderers exist for React, Vue, Svelte, Astro, React Native and more.

Errors

CodeStatusWhen
UNAUTHORIZED401Missing or invalid API key
FORBIDDEN403API key does not have access to this project
PROJECT_NOT_FOUND404Project does not exist or was deleted
PAGE_NOT_FOUND404No page found for this type/handle (after locale fallback)
INVALID_PARAMS400Missing projectId, type, or handle, or unsupported format value
INTERNAL_ERROR500Unexpected server error

Examples

# Get the homepage
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://studio.weaverse.io/api/v1/content/projects/clx1abc23def456ghij/pages/INDEX/default"

# Get a product page with locale
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://studio.weaverse.io/api/v1/content/projects/clx1abc23def456ghij/pages/PRODUCT/blue-shirt?locale=fr-fr"