> ## Documentation Index
> Fetch the complete documentation index at: https://weaverse.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Weaverse component configuration uses `settings`. `inspector` is deprecated; never generate it.
> Weaverse Hydrogen themes use React Router v7: import from `react-router`, never `react-router-dom` or `@remix-run/*`.
> Define component schemas with `createSchema()` from `@weaverse/hydrogen` (React Router themes) or `@weaverse/next` (Next.js themes).
> These docs cover @weaverse/hydrogen, @weaverse/react and @weaverse/core 5.x, and @weaverse/next 1.x. Do not use APIs from other major versions.
> For live project data (pages, theme settings, translations), use the Weaverse MCP server: https://docs.weaverse.io/developer-tools/weaverse-mcp

# Assign resources to a shared template page

> Assigns many Shopify resources to one existing template page: the shared-template model (one page, many assignments). Each resource becomes its own assignment row pointing at `pageId`, so the template content stays shared, not copied. To create an independent, editable copy per resource, use `POST /projects/{projectId}/pages` instead.

- The target must be a live page assigned to this project. Its type is derived from its existing assignments and must be resource-backed (`PRODUCT`, `COLLECTION`, `PAGE`, `BLOG`, `ARTICLE`); any other type returns `400`.
- Send 1-100 entries in `assignments`. `handle` is the Shopify resource handle (trimmed, kept verbatim); `locale` defaults to the global assignment (`""`).
- A resource already assigned to this page is an idempotent no-op, reported under `existing`.
- **All-or-nothing.** Every handle is checked first. If any handle already belongs to a different live page, the whole request returns `409 CONFLICT` with the clashing handles in `details.conflicts`, and nothing is written. A resource is never repointed away from another page: unassign it from its current template, then retry.
- New rows are created in a single transaction. All lookups and writes are scoped to `projectId`.

Required scope: `content:write`



## OpenAPI

````yaml https://studio.weaverse.io/api/v1/content/openapi.json post /projects/{projectId}/template-assignments/{pageId}
openapi: 3.1.0
info:
  title: Weaverse Content API
  version: 1.0.0
  description: >-
    Authenticated REST API for querying Weaverse-managed content (projects,
    pages, theme settings, languages) and for reading and writing per-locale
    translations.
servers:
  - url: https://studio.weaverse.io/api/v1/content
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Projects
    description: List, read, rename, create, copy and delete projects.
  - name: Pages
    description: List, read, create, update and delete the pages of a project.
  - name: Drafts and publishing
    description: >-
      Edit page drafts, then publish, schedule, restore and manage page
      versions.
  - name: Global sections
    description: Read, edit and publish sections shared across pages.
  - name: Page settings
    description: Read and edit page-level settings such as SEO metadata.
  - name: Assignments
    description: Map Shopify resources and routes to Weaverse pages and templates.
  - name: Theme settings
    description: Read and update a project's theme settings.
  - name: Languages and localization
    description: List project languages and manage locales, static text and glossary.
  - name: Translations
    description: >-
      Read and write per-locale translations, built for external translation
      agents.
  - name: Project structure
    description: Manage project variants and the project hierarchy.
  - name: Backups and portability
    description: Back up, restore, export and import project content.
  - name: Previews and hostnames
    description: Create preview links and manage the hostnames a project accepts.
  - name: Specification
    description: This OpenAPI document.
paths:
  /projects/{projectId}/template-assignments/{pageId}:
    post:
      tags:
        - Assignments
      summary: Assign resources to a shared template page
      description: >-
        Assigns many Shopify resources to one existing template page: the
        shared-template model (one page, many assignments). Each resource
        becomes its own assignment row pointing at `pageId`, so the template
        content stays shared, not copied. To create an independent, editable
        copy per resource, use `POST /projects/{projectId}/pages` instead.


        - The target must be a live page assigned to this project. Its type is
        derived from its existing assignments and must be resource-backed
        (`PRODUCT`, `COLLECTION`, `PAGE`, `BLOG`, `ARTICLE`); any other type
        returns `400`.

        - Send 1-100 entries in `assignments`. `handle` is the Shopify resource
        handle (trimmed, kept verbatim); `locale` defaults to the global
        assignment (`""`).

        - A resource already assigned to this page is an idempotent no-op,
        reported under `existing`.

        - **All-or-nothing.** Every handle is checked first. If any handle
        already belongs to a different live page, the whole request returns `409
        CONFLICT` with the clashing handles in `details.conflicts`, and nothing
        is written. A resource is never repointed away from another page:
        unassign it from its current template, then retry.

        - New rows are created in a single transaction. All lookups and writes
        are scoped to `projectId`.


        Required scope: `content:write`
      operationId: assignTemplateResources
      parameters:
        - name: projectId
          in: path
          required: true
          schema:
            type: string
        - name: pageId
          in: path
          required: true
          schema:
            type: string
          description: The template page id to assign resources to.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateAssignmentRequest'
            example:
              assignments:
                - handle: summer-sale
                  shopifyResourceId: gid://shopify/Collection/123456789
                - handle: winter-drop
                  shopifyResourceId: gid://shopify/Collection/987654321
      responses:
        '200':
          description: >-
            Assignments applied. `created` = new rows; `existing` = idempotent
            no-ops.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateAssignmentResult'
              example:
                object: template_assignments
                pageId: clz2r7t5w0002mnop9012qrst
                type: COLLECTION
                requested: 2
                created:
                  - handle: summer-sale
                    locale: ''
                    assignmentId: clz5b1c2d0008wxyz3456abcd
                existing:
                  - handle: winter-drop
                    locale: ''
                    assignmentId: clz5b0a1b0009wxyz7890efgh
        '400':
          description: Invalid params, or the page cannot carry resource assignments
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Project or template page not found in this project
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '405':
          description: Method not allowed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            A handle already belongs to a different live page (or a concurrent
            write won the race); nothing was assigned. `details.conflicts` lists
            the clashing handles.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                object: error
                code: CONFLICT
                message: >-
                  1 of 2 resource(s) already belong to a different page; no
                  assignments were created
                status: 409
                details:
                  conflicts:
                    - handle: winter-drop
                      locale: ''
                      assignmentId: clz5b0a1b0009wxyz7890efgh
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    TemplateAssignmentRequest:
      type: object
      required:
        - assignments
      properties:
        assignments:
          type: array
          minItems: 1
          maxItems: 100
          description: >-
            Shopify resources to assign to this template page. Each becomes its
            own assignment row pointing at the same page — no page copies are
            created.
          items:
            type: object
            required:
              - handle
            additionalProperties: false
            properties:
              handle:
                type: string
                description: Shopify resource handle (trimmed, kept verbatim).
              shopifyResourceId:
                type: string
                description: >-
                  Optional non-empty Shopify resource id (gid) bound to the
                  assignment.
              locale:
                type: string
                description: >-
                  Optional assignment locale. Defaults to the global/default
                  assignment ("").
      additionalProperties: false
    TemplateAssignmentResult:
      type: object
      properties:
        object:
          type: string
          enum:
            - template_assignments
        pageId:
          type: string
        type:
          type: string
        requested:
          type: integer
        created:
          type: array
          description: Newly created assignment rows pointing at this page.
          items:
            type: object
            properties:
              handle:
                type: string
              locale:
                type: string
              assignmentId:
                type: string
        existing:
          type: array
          description: Resources already assigned to this page (idempotent no-op).
          items:
            type: object
            properties:
              handle:
                type: string
              locale:
                type: string
              assignmentId:
                type: string
    Error:
      type: object
      required:
        - object
        - code
        - message
        - status
      properties:
        object:
          type: string
          enum:
            - error
        code:
          type: string
          enum:
            - UNAUTHORIZED
            - FORBIDDEN
            - INSUFFICIENT_SCOPE
            - PROJECT_NOT_FOUND
            - PAGE_NOT_FOUND
            - STALE_PAGE
            - STALE_PROJECT
            - STALE_TRANSLATION
            - TRANSLATION_UNIT_NOT_FOUND
            - SERVICE_UNAVAILABLE
            - CONFLICT
            - PRECONDITION_REQUIRED
            - INVALID_PARAMS
            - INTERNAL_ERROR
        message:
          type: string
        status:
          type: integer
        details:
          description: >-
            Optional machine-readable context, for example the clashing handles
            of a 409 CONFLICT.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: WEAVERSE_API_KEY
      description: >-
        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.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.