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

# Edit page content

> Adds, changes and removes text, images, shapes, frames, QR codes and other items on a design's pages, as one batch of operations. The batch is checked against the operation schemas first and refused as a whole if any operation is malformed (400). It then runs in order; if any operation fails, nothing is saved (422). With `dryRun: true` it runs without saving.

Place images and SVG graphics as files: upload them with `POST /v2/files` (from a URL) or `POST /v2/files/uploads`, then give the file id as `asset`. An SVG file stays vector in print. Don't send SVG markup inline (`svg`): the firewall in front of the API refuses request bodies that carry markup, with an HTML 403.



## OpenAPI

````yaml openapi.json POST /v2/designs/{id}/ops
openapi: 3.1.0
info:
  title: Print.App API
  version: 2.1.0
  description: >-
    Server-to-server API for Print.App integrations: designs and their page
    content, folders, files, fonts, palettes, product assignments, projects and
    editor links. Authenticate every request with a secret key: `Authorization:
    Bearer sk_…`. Never call it from a browser.
servers:
  - url: https://api.print.app
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Account
    description: The account a secret key belongs to.
  - name: Designs
    description: >-
      The designs (templates) your customers start from: create them at a size,
      manage their pages, and place text, images and shapes on them.
  - name: Design folders
    description: >-
      Folders that organise your designs. A design can sit in more than one
      folder.
  - name: Files
    description: >-
      Your own images and graphics, used in designs and offered to customers in
      the editor.
  - name: Graphic folders
    description: >-
      Folders of files, shown in the editor under Pictures, Backgrounds,
      Textures or Frames.
  - name: Fonts
    description: >-
      The fonts your designs and customers can use: the built-in set, imported
      Google fonts and fonts you upload.
  - name: Palettes
    description: Colour palettes offered in the editor.
  - name: Products
    description: Which designs open for each product (and variant) in your store.
  - name: Projects
    description: Your customers' saved designs.
  - name: Links
    description: Shareable editor links that open a design or project at create.print.app.
  - name: Connectors
    description: >-
      Links between the options on a store's product page and the editor: the
      choice a customer makes shows the right pages, opens the right design, or
      sets the size, orientation or colour. Read a product page for what a
      connector can point at, and test one against a design before customers
      meet it.
  - name: Resource profiles
    description: >-
      Limits on the fonts, colour palettes and graphic folders the editor
      offers, for the designs that use them.
  - name: PDF profiles
    description: >-
      The settings print PDFs are made with: colour conversion, PDF standard,
      cut lines, image resolution, fonts.
  - name: 3D scenes
    description: >-
      The 3D scenes the editor previews designs on: models with print areas,
      folds, flipbooks and sheets, yours and the Print.App library's. A design
      picks one with `sceneId`.
  - name: Library
    description: >-
      The Print.App library, the store catalogue the dashboard's Import Designs
      and Import from Library open: ready-made designs, and themed kits of
      graphics. Find what suits a product, then bring it into your account: a
      design as your own copy, a kit as a folder that follows it, single
      graphics into a folder.
  - name: Settings
    description: >-
      The account's editor and product page settings: how the editor opens and
      behaves, and the selectors Print.App uses on your product pages. Settings
      that run code in your store, send data elsewhere or delete projects are
      kept to the dashboard.
paths:
  /v2/designs/{id}/ops:
    post:
      tags:
        - Designs
      summary: Edit page content
      description: >-
        Adds, changes and removes text, images, shapes, frames, QR codes and
        other items on a design's pages, as one batch of operations. The batch
        is checked against the operation schemas first and refused as a whole if
        any operation is malformed (400). It then runs in order; if any
        operation fails, nothing is saved (422). With `dryRun: true` it runs
        without saving.


        Place images and SVG graphics as files: upload them with `POST
        /v2/files` (from a URL) or `POST /v2/files/uploads`, then give the file
        id as `asset`. An SVG file stays vector in print. Don't send SVG markup
        inline (`svg`): the firewall in front of the API refuses request bodies
        that carry markup, with an HTML 403.
      operationId: applyOps
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: The `designId`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpsBatch'
            example:
              units: mm
              ops:
                - op: shape.add
                  ref: band
                  kind: rect
                  box:
                    - 0
                    - 0
                    - 85
                    - 14
                  fill: '#1f2a44'
                - op: text.add
                  ref: name
                  box:
                    - 6
                    - 22
                    - 73
                    - 10
                  content: Ada Lovelace
                  font: open sans
                  size: 14
                  weight: 700
                  align: left
                  color: '#1f2a44'
                  field:
                    title: Name
                    maxTextCount: 30
                - op: graphic.add
                  ref: logo
                  box:
                    - 62
                    - 3
                    - 18
                    - 8
                  asset: file_01JB2W3X4Y5Z6A7B8C9D0E1F2G.png
      responses:
        '200':
          description: OK.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpsResult'
        '400':
          description: >-
            A parameter or body field is malformed: `param` names it and
            `details` lists every problem found.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: invalid_request
                message: width is required.
                param: width
                requestId: FZn-uhymjoEEJow=
        '401':
          description: Missing, unknown, revoked or expired secret key.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: unauthorized
                message: >-
                  Missing or invalid secret key. Send it as "Authorization:
                  Bearer sk_…".
                requestId: FZn-uhymjoEEJow=
        '403':
          description: The account is suspended for an unpaid invoice.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: account_suspended
                message: >-
                  This account is suspended. Settle the outstanding invoice in
                  the Print.App dashboard.
                requestId: FZn-uhymjoEEJow=
        '404':
          description: >-
            Not found in your account. Another account's resources answer 404
            too.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: not_found
                message: Not found.
                requestId: FZn-uhymjoEEJow=
        '409':
          description: >-
            The request conflicts with the current state; `code` says how
            (`folder_not_empty`, `builtin_folder`, `builtin_palette`,
            `editor_not_supported`, `design_changed`, `idempotency_key_reused`,
            `idempotency_in_progress`).
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: folder_not_empty
                message: >-
                  The folder still holds designs. Remove them from it (or delete
                  them) first.
                requestId: FZn-uhymjoEEJow=
        '415':
          description: The body is not JSON.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: unsupported_media_type
                message: >-
                  Send the request body as JSON, with "Content-Type:
                  application/json".
                requestId: FZn-uhymjoEEJow=
        '422':
          description: >-
            An operation failed while the batch ran. Nothing was saved;
            `details` holds every operation's result.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: ops_failed
                message: >-
                  ops[1] (item.update) failed: no item 'logo'. Nothing was
                  saved.
                param: ops
                requestId: FZn-uhymjoEEJow=
                details:
                  - index: 0
                    op: text.add
                    ok: true
                    id: itm_7f3b
                    ref: name
                  - index: 1
                    op: item.update
                    ok: false
                    error: no item 'logo'
        '429':
          description: >-
            Rate limited by the API gateway. Back off and retry. This response
            comes from the gateway, so its body is `{ "message": "Too Many
            Requests" }`, not the standard error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
              example:
                message: Too Many Requests
        '500':
          description: >-
            Something failed on our side. Retry; quote the requestId to support
            if it persists.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: true
                code: internal_error
                message: >-
                  Something went wrong on our side. Retry the request; if it
                  keeps failing, contact support with the requestId.
                requestId: FZn-uhymjoEEJow=
components:
  schemas:
    OpsBatch:
      title: OpsBatch
      description: >-
        A batch of design operations, run in order as one change: either every
        operation succeeds and the design is saved, or nothing is. Each
        operation is checked against its own schema (the DesignOp schemas)
        before anything runs.
      type: object
      additionalProperties: false
      required:
        - ops
      properties:
        units:
          type: string
          enum:
            - mm
            - cm
            - in
            - pt
            - px
          description: >-
            The unit of every box and length in the batch. Default: the design's
            unit (mm for designs measured in ft). Text sizes are always in
            points.
        page:
          oneOf:
            - type: integer
              minimum: 1
              maximum: 500
            - type: string
              minLength: 1
              maxLength: 40
          description: >-
            The page item operations go on: a page number from 1, or a page's
            ref. An operation's own `page` wins. Default 1.
        ops:
          type: array
          minItems: 1
          maxItems: 100
          items:
            oneOf:
              - $ref: '#/components/schemas/DesignOpTextAdd'
              - $ref: '#/components/schemas/DesignOpFrameAdd'
              - $ref: '#/components/schemas/DesignOpGraphicAdd'
              - $ref: '#/components/schemas/DesignOpShapeAdd'
              - $ref: '#/components/schemas/DesignOpPatternAdd'
              - $ref: '#/components/schemas/DesignOpBorderAdd'
              - $ref: '#/components/schemas/DesignOpModuleAdd'
              - $ref: '#/components/schemas/DesignOpPageAdd'
              - $ref: '#/components/schemas/DesignOpPageSet'
              - $ref: '#/components/schemas/DesignOpDesignSet'
              - $ref: '#/components/schemas/DesignOpItemUpdate'
              - $ref: '#/components/schemas/DesignOpItemRemove'
              - $ref: '#/components/schemas/DesignOpAlign'
            discriminator:
              propertyName: op
          description: >-
            The operations, run in order. Items added in the batch can be
            targeted by later operations through their `ref`.
        dryRun:
          type: boolean
          default: false
          description: >-
            Run the batch and report every operation's result and the resulting
            content, without saving anything.
      examples:
        - units: mm
          ops:
            - op: shape.add
              ref: band
              kind: rect
              box:
                - 0
                - 0
                - 85
                - 14
              fill: '#1f2a44'
            - op: text.add
              ref: name
              box:
                - 6
                - 22
                - 73
                - 10
              content: Ada Lovelace
              font: open sans
              size: 14
              weight: 700
              align: left
              color: '#1f2a44'
              field:
                title: Name
                maxTextCount: 30
            - op: graphic.add
              ref: logo
              box:
                - 62
                - 3
                - 18
                - 8
              asset: file_01JB2W3X4Y5Z6A7B8C9D0E1F2G.png
    OpsResult:
      title: OpsResult
      description: >-
        The outcome of a batch that ran: every operation's result, the design as
        saved (unchanged on a dry run), and its content now.
      type: object
      required:
        - object
        - dryRun
        - results
        - design
        - content
      properties:
        object:
          type: string
          const: ops_result
        dryRun:
          type: boolean
        results:
          type: array
          items:
            $ref: '#/components/schemas/OpResult'
        design:
          $ref: '#/components/schemas/Design'
        content:
          $ref: '#/components/schemas/DesignContent'
    Error:
      title: Error
      description: >-
        Every error the API itself returns. Match on `code`; `message` is for
        people and may be reworded.
      type: object
      required:
        - error
        - code
        - message
        - requestId
      properties:
        error:
          type: boolean
          const: true
        code:
          type: string
          enum:
            - unauthorized
            - account_suspended
            - invalid_request
            - not_found
            - route_not_found
            - idempotency_key_reused
            - idempotency_in_progress
            - folder_not_empty
            - builtin_folder
            - builtin_palette
            - editor_not_supported
            - design_changed
            - payload_too_large
            - unsupported_media_type
            - ops_failed
            - internal_error
            - service_unavailable
          description: >-
            `unauthorized` (401): missing, unknown, revoked or expired secret
            key. `account_suspended` (403): the account has an unpaid invoice.
            `invalid_request` (400): a parameter or body field is malformed —
            see `param` and `details`. `not_found` (404): no such resource in
            your account. `route_not_found` (404): no such endpoint.
            `idempotency_key_reused` (409): the Idempotency-Key was used for a
            different request. `idempotency_in_progress` (409): the first
            request with that key is still running. `folder_not_empty` (409):
            the folder still holds designs or folders. `builtin_folder`,
            `builtin_palette` (409): Print.App's own folders and palettes cannot
            be changed. `editor_not_supported` (409): page content can only be
            edited on accounts that use the new editor. `design_changed` (409):
            the design was saved elsewhere while the batch ran; read it again
            and retry. `payload_too_large` (413): a body or file over the limit.
            `unsupported_media_type` (415): send JSON. `ops_failed` (422): an
            operation in the batch failed, nothing was saved — see `details`.
            `internal_error` (500): retry; contact support with the `requestId`
            if it persists. `service_unavailable` (503): retry in a few seconds.
        message:
          type: string
        param:
          type: string
          description: The parameter or body field at fault, as a path (`pages[0].title`).
        details:
          type: array
          description: >-
            Every problem found, when there was more than one
            (`invalid_request`), or each operation's result (`ops_failed`).
          items:
            type: object
        requestId:
          type: string
          description: >-
            Also sent as the `x-request-id` header. Quote it when contacting
            support.
      examples:
        - error: true
          code: invalid_request
          message: limit must be an integer from 1 to 100.
          param: limit
          requestId: FZn-uhymjoEEJow=
    GatewayError:
      type: object
      properties:
        message:
          type: string
      description: Returned by the API gateway itself (429).
    DesignOpTextAdd:
      title: text.add
      type: object
      required:
        - op
        - ref
        - box
        - font
        - size
        - align
      additionalProperties: false
      oneOf:
        - required:
            - content
        - required:
            - template
      properties:
        op:
          const: text.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartBox'
        content:
          type: string
          maxLength: 5000
        template:
          type: string
          minLength: 3
          maxLength: 5000
          description: >-
            Smart tokens: "{Phone | type: tel, default: +1 555 0100}"; each
            token is a form field.
        font:
          $ref: '#/components/schemas/DesignOpPartFont'
        size:
          type: number
          minimum: 1
          maximum: 2000
          description: pt
        weight:
          type: integer
          minimum: 100
          maximum: 900
        style:
          type: string
          enum:
            - normal
            - italic
        color:
          $ref: '#/components/schemas/DesignOpPartSolidColor'
        leading:
          type: number
          minimum: 0.5
          maximum: 5
          description: Line spacing as a multiple of size.
        tracking:
          type: number
          minimum: -500
          maximum: 2000
          description: Letter spacing, 1/1000 em.
        align:
          type: string
          enum:
            - left
            - center
            - right
        anchor:
          type: string
          enum:
            - top
            - center
            - bottom
        frame:
          $ref: '#/components/schemas/DesignOpPartTextFrame'
        field:
          $ref: '#/components/schemas/DesignOpPartField'
        lock:
          $ref: '#/components/schemas/DesignOpPartLock'
    DesignOpFrameAdd:
      title: frame.add
      type: object
      required:
        - op
        - ref
        - box
      additionalProperties: false
      properties:
        op:
          const: frame.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartBox'
        mask:
          type: string
          enum:
            - rect
            - ellipse
            - star
            - heart
            - arch
            - path
        radius:
          $ref: '#/components/schemas/DesignOpPartLength'
        points:
          type: integer
          minimum: 3
          maximum: 50
        path:
          $ref: '#/components/schemas/DesignOpPartSvgPath'
        fit:
          type: string
          enum:
            - cover
            - contain
        border:
          $ref: '#/components/schemas/DesignOpPartStroke'
        asset:
          $ref: '#/components/schemas/DesignOpPartAsset'
        svg:
          $ref: '#/components/schemas/DesignOpPartSvg'
        field:
          type: object
          required:
            - title
          additionalProperties: false
          properties:
            title:
              type: string
              minLength: 1
              maxLength: 100
            hint:
              type: string
              maxLength: 300
        shuffle:
          const: false
        lock:
          $ref: '#/components/schemas/DesignOpPartLock'
    DesignOpGraphicAdd:
      title: graphic.add
      type: object
      required:
        - op
        - ref
        - box
      additionalProperties: false
      oneOf:
        - required:
            - asset
        - required:
            - svg
      properties:
        op:
          const: graphic.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartBox'
        asset:
          $ref: '#/components/schemas/DesignOpPartAsset'
        svg:
          $ref: '#/components/schemas/DesignOpPartSvg'
        fit:
          type: string
          enum:
            - contain
            - cover
            - stretch
        opacity:
          $ref: '#/components/schemas/DesignOpPartOpacity'
        rotate:
          $ref: '#/components/schemas/DesignOpPartDegrees'
        lock:
          $ref: '#/components/schemas/DesignOpPartLock'
    DesignOpShapeAdd:
      title: shape.add
      type: object
      required:
        - op
        - ref
        - kind
      additionalProperties: false
      properties:
        op:
          const: shape.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        kind:
          type: string
          enum:
            - rect
            - ellipse
            - line
            - polygon
            - star
            - heart
            - path
        box:
          $ref: '#/components/schemas/DesignOpPartBox'
        from:
          $ref: '#/components/schemas/DesignOpPartPoint'
        to:
          $ref: '#/components/schemas/DesignOpPartPoint'
        cornerRadius:
          $ref: '#/components/schemas/DesignOpPartLength'
        sides:
          type: integer
          minimum: 3
          maximum: 64
        points:
          type: integer
          minimum: 3
          maximum: 64
        path:
          $ref: '#/components/schemas/DesignOpPartSvgPath'
        fill:
          $ref: '#/components/schemas/DesignOpPartColor'
        stroke:
          $ref: '#/components/schemas/DesignOpPartStroke'
        opacity:
          $ref: '#/components/schemas/DesignOpPartOpacity'
        rotate:
          $ref: '#/components/schemas/DesignOpPartDegrees'
        lock:
          $ref: '#/components/schemas/DesignOpPartLock'
    DesignOpPatternAdd:
      title: pattern.add
      type: object
      required:
        - op
        - ref
      additionalProperties: false
      properties:
        op:
          const: pattern.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartArea'
        motifs:
          type: array
          minItems: 1
          maxItems: 4
          items:
            type: string
            enum:
              - dot
              - sparkle
              - star
              - snowflake
              - plus
              - diamond
              - heart
              - tree
              - stripes
        assets:
          type: array
          minItems: 1
          maxItems: 4
          items:
            $ref: '#/components/schemas/DesignOpPartAsset'
        colors:
          type: array
          minItems: 1
          maxItems: 6
          items:
            $ref: '#/components/schemas/DesignOpPartSolidColor'
        size:
          type: number
          exclusiveMinimum: 0
          maximum: 100000
        spacing:
          type: number
          exclusiveMinimum: 0
          maximum: 100000
        layout:
          type: string
          enum:
            - half-drop
            - grid
        angle:
          $ref: '#/components/schemas/DesignOpPartDegrees'
        rotate:
          type: array
          minItems: 1
          maxItems: 12
          items:
            $ref: '#/components/schemas/DesignOpPartDegrees'
        clear:
          type: array
          maxItems: 30
          items:
            $ref: '#/components/schemas/DesignOpPartBox'
        opacity:
          $ref: '#/components/schemas/DesignOpPartOpacity'
    DesignOpBorderAdd:
      title: border.add
      type: object
      required:
        - op
        - ref
        - style
      additionalProperties: false
      properties:
        op:
          const: border.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartArea'
        style:
          type: string
          enum:
            - solid
            - line
            - double
            - dots
            - candy
        width:
          type: number
          exclusiveMinimum: 0
          maximum: 100000
        inset:
          $ref: '#/components/schemas/DesignOpPartLength'
        colors:
          type: array
          minItems: 1
          maxItems: 2
          items:
            $ref: '#/components/schemas/DesignOpPartSolidColor'
        size:
          type: number
          exclusiveMinimum: 0
          maximum: 100000
    DesignOpModuleAdd:
      title: module.add
      type: object
      required:
        - op
        - ref
        - type
        - params
      additionalProperties: false
      properties:
        op:
          const: module.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartArea'
        type:
          type: string
          enum:
            - qrcode
            - calendar
            - curved-text
            - stamp-grid
            - pattern-fill
        params:
          type: object
          maxProperties: 40
          description: >-
            Per type, as playbook/ops.md module.add (colours hex, fonts family
            names, sizes pt, lengths in the batch units, motifs as asset ids).
        field:
          $ref: '#/components/schemas/DesignOpPartField'
        lock:
          $ref: '#/components/schemas/DesignOpPartLock'
    DesignOpPageAdd:
      title: page.add
      type: object
      required:
        - op
        - ref
      additionalProperties: false
      properties:
        op:
          const: page.add
        ref:
          $ref: '#/components/schemas/DesignOpPartRef'
        position:
          type: integer
          minimum: 1
          maximum: 500
          description: >-
            1-based index to insert at (default: the end). The new page copies
            the first page's size, bleed and margin.
        title:
          type: string
          maxLength: 100
    DesignOpPageSet:
      title: page.set
      type: object
      required:
        - op
        - page
      additionalProperties: false
      properties:
        op:
          const: page.set
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        title:
          type: string
          maxLength: 100
        folds:
          $ref: '#/components/schemas/DesignOpPartFolds'
        background:
          $ref: '#/components/schemas/DesignOpPartBackground'
        underlay:
          oneOf:
            - type: 'null'
            - type: object
              required:
                - asset
              additionalProperties: false
              properties:
                asset:
                  $ref: '#/components/schemas/DesignOpPartAsset'
                tint:
                  $ref: '#/components/schemas/DesignOpPartSolidColor'
        window:
          $ref: '#/components/schemas/DesignOpPartBox'
    DesignOpDesignSet:
      title: design.set
      type: object
      required:
        - op
      additionalProperties: false
      minProperties: 2
      properties:
        op:
          const: design.set
        freedom:
          type: string
          enum:
            - templates
            - mix
            - free
        settings:
          type: object
          additionalProperties: false
          minProperties: 1
          properties:
            dpiCheck:
              type: boolean
            dpi:
              type: integer
              minimum: 72
              maximum: 1200
            renderCutLines:
              type: boolean
        modules:
          type: object
          additionalProperties: false
          minProperties: 1
          properties:
            pageselector:
              type: object
              additionalProperties: false
              properties:
                title:
                  type: string
                  maxLength: 100
                maxPageCount:
                  type: integer
                  minimum: 1
                  maximum: 500
                enablePageSwap:
                  type: boolean
            calendar:
              type: object
              maxProperties: 30
            stickers:
              type: object
              additionalProperties: false
              properties:
                margin:
                  $ref: '#/components/schemas/DesignOpPartLength'
                cutlineWidth:
                  type: number
                  minimum: 0
                  maximum: 100
                autoRemoveBackground:
                  type: boolean
                outerEdgeOnly:
                  type: boolean
                showPanelToCustomers:
                  type: boolean
            pattern:
              type: object
              required:
                - instance
              maxProperties: 10
              properties:
                instance:
                  $ref: '#/components/schemas/DesignOpPartRef'
            photoshuffle:
              type: object
              additionalProperties: false
              properties:
                promptOnLaunch:
                  type: boolean
                autoFill:
                  type: boolean
                allowShuffle:
                  type: boolean
                minPhotos:
                  type: integer
                  minimum: 0
                  maximum: 500
                maxPhotos:
                  type: integer
                  minimum: 0
                  maximum: 500
            mailmerge:
              type: object
              additionalProperties: false
              properties:
                mode:
                  type: string
                  enum:
                    - numbers
                    - list
                start:
                  type: integer
                  minimum: 0
                linkQuantity:
                  type: boolean
    DesignOpItemUpdate:
      title: item.update
      type: object
      required:
        - op
        - target
      additionalProperties: false
      minProperties: 3
      description: >-
        Changes an item. Items added earlier in the same batch take any property
        of the op that added them. Items already on the saved design take: box,
        content, font, size, weight, style, color, leading, tracking, align,
        anchor, fill, stroke, opacity, rotate, lock, field, asset, svg,
        cornerRadius.
      properties:
        op:
          const: item.update
        target:
          $ref: '#/components/schemas/DesignOpPartTarget'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
        box:
          $ref: '#/components/schemas/DesignOpPartArea'
        content:
          type: string
          maxLength: 5000
        template:
          type: string
          minLength: 3
          maxLength: 5000
        font:
          $ref: '#/components/schemas/DesignOpPartFont'
        size:
          type: number
          minimum: 1
          maximum: 2000
        weight:
          type: integer
          minimum: 100
          maximum: 900
        style:
          type: string
          enum:
            - normal
            - italic
        color:
          $ref: '#/components/schemas/DesignOpPartSolidColor'
        leading:
          type: number
          minimum: 0.5
          maximum: 5
        tracking:
          type: number
          minimum: -500
          maximum: 2000
        align:
          type: string
          enum:
            - left
            - center
            - right
        anchor:
          type: string
          enum:
            - top
            - center
            - bottom
        frame:
          $ref: '#/components/schemas/DesignOpPartTextFrame'
        field:
          type: object
        lock:
          $ref: '#/components/schemas/DesignOpPartLock'
        mask:
          type: string
          enum:
            - rect
            - ellipse
            - star
            - heart
            - arch
            - path
        radius:
          $ref: '#/components/schemas/DesignOpPartLength'
        points:
          type: integer
          minimum: 3
          maximum: 64
        sides:
          type: integer
          minimum: 3
          maximum: 64
        path:
          $ref: '#/components/schemas/DesignOpPartSvgPath'
        fit:
          type: string
          enum:
            - contain
            - cover
            - stretch
        border:
          $ref: '#/components/schemas/DesignOpPartStroke'
        asset:
          $ref: '#/components/schemas/DesignOpPartAsset'
        svg:
          $ref: '#/components/schemas/DesignOpPartSvg'
        shuffle:
          const: false
        kind:
          type: string
          enum:
            - rect
            - ellipse
            - line
            - polygon
            - star
            - heart
            - path
        from:
          $ref: '#/components/schemas/DesignOpPartPoint'
        to:
          $ref: '#/components/schemas/DesignOpPartPoint'
        cornerRadius:
          $ref: '#/components/schemas/DesignOpPartLength'
        fill:
          $ref: '#/components/schemas/DesignOpPartColor'
        stroke:
          $ref: '#/components/schemas/DesignOpPartStroke'
        opacity:
          $ref: '#/components/schemas/DesignOpPartOpacity'
        rotate:
          oneOf:
            - $ref: '#/components/schemas/DesignOpPartDegrees'
            - type: array
              minItems: 1
              maxItems: 12
              items:
                $ref: '#/components/schemas/DesignOpPartDegrees'
        motifs:
          type: array
          minItems: 1
          maxItems: 4
          items:
            type: string
        assets:
          type: array
          minItems: 1
          maxItems: 4
          items:
            $ref: '#/components/schemas/DesignOpPartAsset'
        colors:
          type: array
          minItems: 1
          maxItems: 6
          items:
            $ref: '#/components/schemas/DesignOpPartSolidColor'
        spacing:
          type: number
          exclusiveMinimum: 0
          maximum: 100000
        layout:
          type: string
          enum:
            - half-drop
            - grid
        angle:
          $ref: '#/components/schemas/DesignOpPartDegrees'
        clear:
          type: array
          maxItems: 30
          items:
            $ref: '#/components/schemas/DesignOpPartBox'
        width:
          type: number
          exclusiveMinimum: 0
          maximum: 100000
        inset:
          $ref: '#/components/schemas/DesignOpPartLength'
        params:
          type: object
          maxProperties: 40
    DesignOpItemRemove:
      title: item.remove
      type: object
      required:
        - op
        - target
      additionalProperties: false
      properties:
        op:
          const: item.remove
        target:
          $ref: '#/components/schemas/DesignOpPartTarget'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
    DesignOpAlign:
      title: align
      type: object
      required:
        - op
        - targets
        - edge
      additionalProperties: false
      properties:
        op:
          const: align
        targets:
          type: array
          minItems: 1
          maxItems: 50
          items:
            $ref: '#/components/schemas/DesignOpPartTarget'
        edge:
          type: string
          enum:
            - left
            - right
            - top
            - bottom
            - centerX
            - centerY
        to:
          type: string
          minLength: 1
          maxLength: 100
          description: 'safe, page, panel or a ref (default: the first target).'
        page:
          $ref: '#/components/schemas/DesignOpPartPage'
    OpResult:
      title: OpResult
      description: >-
        One operation's result. Also the items of an error's `details` for
        `invalid_request` and `ops_failed` on `POST /v2/designs/{id}/ops`.
      type: object
      required:
        - index
        - op
        - ok
      properties:
        index:
          type:
            - integer
            - 'null'
          description: >-
            The operation's position in `ops`; null for a problem with the batch
            itself.
        op:
          type:
            - string
            - 'null'
        ok:
          type: boolean
        id:
          type: string
          description: The id of the item it added or changed.
        pageId:
          type: string
          description: The id of the page it added.
        ref:
          type:
            - string
            - 'null'
        error:
          type:
            - string
            - 'null'
        path:
          type:
            - string
            - 'null'
          description: The part of the operation at fault.
        warnings:
          type: array
          items:
            type: string
    Design:
      title: Design
      description: >-
        A design (template) your customers start from. Open it in the editor
        with `new PrintAppClient({ designId })`.
      type: object
      required:
        - object
        - id
        - title
        - unit
        - pages
        - tags
        - connectorIds
        - resourceProfileIds
        - pdfProfileId
        - settings
        - sceneId
        - created
        - modified
      properties:
        object:
          type: string
          const: design
        id:
          type: string
          description: The `designId` to pass to `PrintAppClient`.
        title:
          type:
            - string
            - 'null'
        unit:
          type:
            - string
            - 'null'
          description: >-
            The unit the design is measured in: `mm`, `cm`, `in`, `pt`, `px` or
            `ft`.
        pages:
          type: array
          items:
            type: object
            required:
              - index
              - title
              - previewUrl
            properties:
              index:
                type: integer
                minimum: 0
              title:
                type:
                  - string
                  - 'null'
                description: The page's name, when it has one (for example *Front*).
              previewUrl:
                type:
                  - string
                  - 'null'
                description: A preview image of the page.
        tags:
          type: array
          items:
            type: string
        connectorIds:
          type: array
          items:
            type: string
          description: The connectors the design runs on the product page.
        resourceProfileIds:
          type: array
          items:
            type: string
          description: The resource profiles that limit what its editor offers.
        pdfProfileId:
          type:
            - string
            - 'null'
          description: >-
            The PDF profile its print PDF is made with; `null`: its own
            settings.
        settings:
          type: object
          description: >-
            The settings this design sets for itself, over the store's (see `GET
            /v2/settings`). Settings it doesn't set follow the store.
          properties:
            welcomeMsg:
              type: string
              maxLength: 2000
              description: A message shown when the editor opens.
            lockBackground:
              type: boolean
              description: Customers cannot change the background.
            pdfVersion:
              type: string
              enum:
                - '1.4'
                - '1.5'
                - '1.6'
                - '1.7'
                - '2.0'
                - PDF/A-3a
                - PDF/UA-1
                - PDF/X-5n
              description: >-
                The PDF version of the print file, when the design has no PDF
                profile.
            renderCutLines:
              type: boolean
              description: Cut marks in the print PDF, from the bleed.
            displayMode:
              type: string
              enum:
                - ''
                - modal
                - dialog
                - inline
                - mini
              description: How the editor opens for this design (`""` the store's setting).
            enablePageSorting:
              type: boolean
              description: Customers can reorder pages.
            enableSaveLater:
              type: boolean
              description: >-
                Customers can save and finish later. Only adds: the store's
                setting, when on, wins.
            graphicsSearchCustomers:
              type: boolean
              description: >-
                A graphics search box for this design's customers. Only adds to
                the store's setting.
            graphicsSearchScope:
              type: string
              enum:
                - ''
                - store
                - mine
                - both
              description: >-
                What the graphics search covers on this design (`""` the store's
                setting).
            addToCartOnSave:
              type: boolean
              description: Finishing the design adds the product to the cart.
            hideCustomColor:
              type: boolean
              description: Customers cannot add colours of their own.
            hideUploads:
              type: boolean
              description: Hide the Uploads tab.
            hideGraphics:
              type: boolean
              description: Hide the Graphics tab.
            hideBackgrounds:
              type: boolean
              description: Hide the Backgrounds tab.
            hideTypography:
              type: boolean
              description: Hide the Text tab.
            hideColorButton:
              type: boolean
              description: Customers cannot change an item's colour.
            hideMenubar:
              type: boolean
              description: Hide the top menu bar.
            hideContextbar:
              type: boolean
              description: Hide the bar beside a selected item.
            showItemTabInProject:
              type: boolean
              description: Show the selected item's tab to customers.
            disableCanvas:
              type: boolean
              description: Customers cannot select items on the canvas (fields only).
        sceneId:
          type:
            - string
            - 'null'
          description: >-
            The 3D scene the editor previews the design on (GET /v2/scenes);
            `null`: none.
        created:
          type:
            - string
            - 'null'
          format: date-time
        modified:
          type:
            - string
            - 'null'
          format: date-time
      examples:
        - object: design
          id: design_01J8Z9K2M3N4P5Q6R7S8T9V0W1
          title: Business Card
          unit: mm
          pages:
            - index: 0
              title: Front
              previewUrl: >-
                https://d1p81tn8mwpox2.cloudfront.net/?k=s3%3A%2F%2Fapp-print-cdn%2Fcontent_f1.png&size=1000
            - index: 1
              title: Back
              previewUrl: >-
                https://d1p81tn8mwpox2.cloudfront.net/?k=s3%3A%2F%2Fapp-print-cdn%2Fcontent_b1.png&size=1000
          tags:
            - cards
          connectorIds: []
          resourceProfileIds: []
          pdfProfileId: null
          settings: {}
          sceneId: null
          created: '2026-09-02T14:05:11Z'
          modified: '2026-10-11T08:40:27Z'
    DesignContent:
      title: DesignContent
      description: >-
        What is on each page of a design. Boxes are `[x, y, width, height]` in
        `unit`, measured from the top-left of the trim (of the print area, on
        garment pages); text sizes are in points.
      type: object
      required:
        - object
        - designId
        - unit
        - pages
      properties:
        object:
          type: string
          const: design_content
        designId:
          type: string
        unit:
          type:
            - string
            - 'null'
        pages:
          type: array
          items:
            type: object
            required:
              - index
              - id
              - title
              - width
              - height
              - bleed
              - safeMargin
              - items
            properties:
              index:
                type: integer
                minimum: 0
              id:
                type:
                  - string
                  - 'null'
              title:
                type:
                  - string
                  - 'null'
              width:
                type:
                  - number
                  - 'null'
                description: Trim width.
              height:
                type:
                  - number
                  - 'null'
                description: Trim height.
              bleed:
                type:
                  - number
                  - 'null'
              safeMargin:
                type:
                  - number
                  - 'null'
                description: >-
                  How far inside the trim the safe zone starts; null without
                  one.
              safeArea:
                type: array
                items:
                  type:
                    - number
                    - 'null'
                minItems: 4
                maxItems: 4
                description: >-
                  The safe zone as [x, y, width, height] from the top-left of
                  the trim: keep text and key artwork inside it.
              printArea:
                type: boolean
                description: >-
                  The page is a garment mockup: boxes are measured from its
                  print area.
              panels:
                type: array
                items:
                  type: object
                  required:
                    - 'n'
                    - box
                  properties:
                    'n':
                      type: integer
                    box:
                      type:
                        - array
                        - 'null'
                      items:
                        type:
                          - number
                          - 'null'
                description: The panels of a folded page.
              items:
                type: array
                items:
                  $ref: '#/components/schemas/ContentItem'
      examples:
        - object: design_content
          designId: design_01J8Z9K2M3N4P5Q6R7S8T9V0W1
          unit: mm
          pages:
            - index: 0
              id: page_5b1e
              title: Front
              width: 85
              height: 55
              bleed: 3
              safeMargin: 3
              items:
                - id: itm_7f3a
                  ref: band
                  type: rect
                  box:
                    - 0
                    - 0
                    - 85
                    - 14
                  fill: '#1f2a44'
                  lock: decor
                - id: itm_7f3b
                  ref: name
                  type: text
                  box:
                    - 6
                    - 22
                    - 73
                    - 10
                  text: Ada Lovelace
                  font: open sans
                  weight: 700
                  size: 14
                  align: left
                  color: '#1f2a44'
                  field:
                    title: Name
                  lock: field
    DesignOpPartRef:
      type: string
      pattern: ^[A-Za-z][A-Za-z0-9_-]{0,63}$
      description: >-
        A short name you choose; later ops (and later batches) can target the
        item by it.
    DesignOpPartPage:
      oneOf:
        - type: integer
          minimum: 1
          maximum: 500
        - $ref: '#/components/schemas/DesignOpPartRef'
    DesignOpPartBox:
      type: array
      minItems: 4
      maxItems: 4
      items:
        $ref: '#/components/schemas/DesignOpPartCoord'
      description: >-
        [x, y, width, height] from the trim top-left (the print window's on
        garment pages).
    DesignOpPartFont:
      type: string
      minLength: 1
      maxLength: 100
      description: A font family name from the account's fonts (GET /v2/fonts).
    DesignOpPartSolidColor:
      type: string
      pattern: ^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})$
    DesignOpPartTextFrame:
      oneOf:
        - type: string
          enum:
            - wrap
            - hug
        - type: object
          required:
            - fit
          additionalProperties: false
          properties:
            fit:
              type: object
              additionalProperties: false
              properties:
                minSize:
                  type: number
                  minimum: 0
                  maximum: 1000
    DesignOpPartField:
      type: object
      required:
        - title
      additionalProperties: false
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 100
        maxTextCount:
          type: integer
          minimum: 1
          maximum: 10000
        hint:
          type: string
          maxLength: 300
        required:
          type: boolean
    DesignOpPartLock:
      type: string
      enum:
        - decor
        - field
        - hard
        - none
    DesignOpPartLength:
      type: number
      minimum: 0
      maximum: 100000
    DesignOpPartSvgPath:
      type: string
      minLength: 3
      maxLength: 20000
      description: SVG path data drawn in a 0..1 box, stretched to the box.
    DesignOpPartStroke:
      type: object
      required:
        - color
        - width
      additionalProperties: false
      properties:
        color:
          $ref: '#/components/schemas/DesignOpPartColor'
        width:
          type: number
          minimum: 0
          maximum: 1000
    DesignOpPartAsset:
      type: string
      pattern: ^[A-Za-z0-9_.:-]{1,200}$
      description: >-
        One of your file ids (file_…) or a print.app library graphic id (c_…).
        An SVG file stays vector in print.
    DesignOpPartSvg:
      type: string
      minLength: 10
      maxLength: 12000
      description: >-
        SVG markup, inline. Through the API, upload SVGs as files instead (POST
        /v2/files or /v2/files/uploads) and place them with `asset`: the
        firewall in front of api.print.app refuses request bodies that carry
        markup, with an HTML 403.
    DesignOpPartOpacity:
      type: number
      exclusiveMinimum: 0
      maximum: 1
    DesignOpPartDegrees:
      type: number
      minimum: -360
      maximum: 360
    DesignOpPartPoint:
      type: array
      minItems: 2
      maxItems: 2
      items:
        $ref: '#/components/schemas/DesignOpPartCoord'
    DesignOpPartColor:
      type: string
      pattern: ^(#[0-9A-Fa-f]{6}|#[0-9A-Fa-f]{3}|none|transparent)$
      description: '#rrggbb, #rgb, none or transparent.'
    DesignOpPartArea:
      oneOf:
        - $ref: '#/components/schemas/DesignOpPartBox'
        - type: string
          pattern: ^(bleed|trim|safe|panel:[1-9][0-9]?)$
    DesignOpPartFolds:
      type: object
      additionalProperties: false
      properties:
        v:
          type: array
          maxItems: 20
          items:
            $ref: '#/components/schemas/DesignOpPartLength'
        h:
          type: array
          maxItems: 20
          items:
            $ref: '#/components/schemas/DesignOpPartLength'
    DesignOpPartBackground:
      oneOf:
        - $ref: '#/components/schemas/DesignOpPartColor'
        - type: object
          additionalProperties: false
          properties:
            color:
              $ref: '#/components/schemas/DesignOpPartColor'
            asset:
              $ref: '#/components/schemas/DesignOpPartAsset'
            fit:
              type: string
              enum:
                - cover
                - contain
                - stretch
          oneOf:
            - required:
                - color
            - required:
                - asset
    DesignOpPartTarget:
      type: string
      minLength: 1
      maxLength: 100
      description: An item ref or item id.
    ContentItem:
      title: ContentItem
      description: >-
        One item on a page. Target it in `POST /v2/designs/{id}/ops` by `id`, or
        by `ref` when it has one.
      type: object
      required:
        - id
        - type
        - box
        - lock
      properties:
        id:
          type: string
        ref:
          type:
            - string
            - 'null'
          description: The name it was added with.
        type:
          type: string
          description: >-
            `text`, `image`, `rect`, `ellipse`, `path`, `group`, `tiles`, or the
            module type (`qrcode`, `calendar`, …).
        box:
          type:
            - array
            - 'null'
          items:
            type:
              - number
              - 'null'
          minItems: 4
          maxItems: 4
        text:
          type:
            - string
            - 'null'
        font:
          type:
            - string
            - 'null'
        weight:
          type:
            - number
            - 'null'
        size:
          type:
            - number
            - 'null'
          description: Font size in points.
        drawnSize:
          type:
            - number
            - 'null'
          description: The size the text is drawn at, when a fitting frame shrank it.
        align:
          type:
            - string
            - 'null'
        color:
          type:
            - string
            - 'null'
          description: Text colour.
        fill:
          type:
            - string
            - 'null'
          description: Shape fill.
        asset:
          type:
            - string
            - 'null'
          description: The file or library graphic it shows.
        module:
          type:
            - string
            - 'null'
        tiles:
          type:
            - number
            - 'null'
          description: How many tiles a pattern has.
        field:
          type: object
          required:
            - title
          properties:
            title:
              type:
                - string
                - 'null'
          description: Customers edit it in the form.
        photoFrame:
          type: boolean
        background:
          type: boolean
        overflow:
          type: boolean
          description: Its text does not fit its box.
        lock:
          type:
            - string
            - 'null'
          description: '`none`, `field`, `decor` or `hard`.'
    DesignOpPartCoord:
      type: number
      minimum: -100000
      maximum: 100000
  headers:
    RequestId:
      description: Identifies the request. Quote it when contacting support.
      schema:
        type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        A secret key from Print.App admin → Domains → Secret keys, sent as
        `Authorization: Bearer sk_…`. Server-side only.

````

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