---
title: "Animate a template with a preset"
method: POST
path: "/animation_templates/{uid}/animate"
---

# Animate a template with a preset

`POST /animation_templates/{uid}/animate`

## Request

- Base URL: `https://api.bannerbear.com/v5`
- URL: `https://api.bannerbear.com/v5/animation_templates/{uid}/animate`
- Auth: HTTP bearer

Applies a named preset to layers, optionally staggered. Deterministic and free: no model call, no AI credits, and the same request always produces the same keyframes — three layers at `stagger: 500` begin at 0, 500 and 1000ms exactly. Use this whenever the request already says what it wants. The template is versioned before it is overwritten.

## Path parameters

- `uid` string, required

## Request body

- object
  - `preset` 'FadeIn' | 'FadeOut' | 'ZoomIn' | 'ZoomOut' | 'GetBigger' | 'GetSmaller' | 'ScaleIn' | 'ScaleOut' | 'PopIn' | 'PopOut', required: FadeIn, FadeOut, ZoomIn, ZoomOut, GetBigger, GetSmaller, ScaleIn, ScaleOut work on any layer. PopIn and PopOut are measured in `em` and apply to text layers only.
  - `objects` string[]: Layer ids, in the order the stagger should run. Omit to animate every layer in stacking order.
  - `duration` integer: How long each layer's tween runs, in milliseconds
  - `stagger` integer: Milliseconds between each layer's START. At 500, layers begin at 0, 500, 1000 — not 500ms of gap after each finishes.
  - `easing` string: Optional anime.js easing, e.g. easeOutCubic
  - `merge` boolean: Keep keyframes on layers this call does not touch. False replaces the whole timeline.

## Response `200`

Template with its new keyframes

- object
  - `uid` string
  - `name` string
  - `description` string, nullable
  - `tags` string[]
  - `width` integer
  - `height` integer
  - `frame_rate` 24 | 30 | 60
  - `duration_seconds` number: Derived from the template's keyframes — not settable. 0 until something is animated.
  - `preview` string, uri, nullable: Preview image URL
  - `ui_write_access` 'owner_only' | 'team': Who can edit in the dashboard — `owner_only` (default) or `team`
  - `api_write_access` 'team' | 'owner_only' | 'nobody': Who can update or delete via the API — `team` (default), `owner_only`, or `nobody` (locked; unlock via dashboard)
  - `config` object: Canvas configuration. `objects` are the layers; `keyframes` drives the animation and determines duration.
    - `objects` Layer[]
      - union
        - LayerText: A `text` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'text', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `align-items` 'start' | 'center' | 'end': Vertical text alignment within the container
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: background-color
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `color` string: color
          - `color-secondary` string: Text color for text wrapped in *asterisks*
          - `direction` 'ltr' | 'rtl': direction
          - `font-family` string: Font family name (Google Fonts or custom font)
          - `font-family-secondary` string: Font family for text wrapped in *asterisks*
          - `font-size` number: font-size
          - `font-style` 'normal' | 'italic': font-style
          - `font-style-secondary` 'normal' | 'italic', nullable: Font style for text wrapped in *asterisks*
          - `font-weight` 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900: font-weight
          - `font-weight-secondary` 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900, nullable: Font weight for text wrapped in *asterisks*
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `letter-spacing` number: letter-spacing
          - `line-height` number: Line height multiplier for text spacing
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `skewX` number: Horizontal skew angle in degrees
          - `skewY` number: Vertical skew angle in degrees
          - `text` string: Text content to display
          - `text-align` 'left' | 'center' | 'right' | 'justify' | 'start' | 'end': Horizontal text alignment
          - `text-background-image-mask` string: Image URL to use as a clipping mask for the text fill
          - `text-decoration` 'none' | 'underline' | 'overline': text-decoration
          - `text-decoration-secondary` 'none' | 'underline' | 'line-through', nullable: Text decoration for text wrapped in *asterisks*
          - `text-ellipsis` boolean: Truncate overflowing text with an ellipsis
          - `text-fit` 'off' | 'auto_fit' | 'resize_overflow': How text is sized to fit its container
          - `text-highlight-border-radius` number: Corner radius of the text highlight in pixels
          - `text-highlight-color` string: Background color behind individual lines of text
          - `text-highlight-padding-horizontal` number: Horizontal padding around text highlight in pixels
          - `text-highlight-padding-vertical` number: Vertical padding around text highlight in pixels
          - `text-highlight-shadow` string: CSS box-shadow applied to the text highlight, e.g. 0px 2px 4px #000
          - `text-shadow` string: text-shadow
          - `text-stroke-color` string: Color of the text outline stroke
          - `text-stroke-width` number: Width of the text outline stroke in pixels
          - `text-transform` 'none' | 'uppercase' | 'lowercase' | 'capitalize': text-transform
          - `text-transform-secondary` 'none' | 'uppercase' | 'lowercase' | 'capitalize', nullable: Text transform for text wrapped in *asterisks*
          - `top` number: top
          - `white-space` 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | 'pre-line': How whitespace and line breaks are handled
          - `width` number: width
          - `word-break` 'normal' | 'break-all' | 'keep-all' | 'break-word': word-break
        - LayerRectangle: A `rectangle` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'rectangle', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: Background color of the container
          - `background-color-gradient` string: Second color for a two-color gradient fill
          - `background-gradient` string: Full CSS gradient for the fill, e.g. linear-gradient(135deg, #f00 0%, #00f 60%, transparent 100%) — any number of stops at any angle, and radial-gradient or conic-gradient are accepted. Takes priority over background-color-gradient and is drawn on top of background-color
          - `background-gradient-direction` 'left' | 'right' | 'top' | 'bottom': Direction of the gradient fill
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerRectangleImageContainer: A `rectangle_image_container` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'rectangle_image_container', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `ai-background-generate` 'disabled' | 'enabled': Whether the container should generate its background image via AI when an ai-prompt is supplied in the API request
          - `ai-background-remove` 'disabled' | 'enabled': Whether to automatically remove the background of images submitted to this container via the API
          - `ai-detect` 'off' | 'face' | 'subject': AI detection mode for automatic image positioning
          - `ai-detect-anchor` string: Manual anchor point override for AI detection in x:y format (0-100)
          - `ai-detect-focus` 'first' | 'largest' | 'group': Which detection to focus on when multiple are found
          - `ai-detect-on-fail` 'fallback_cover' | 'fallback_contain': Fallback background-size when no face or subject is detected
          - `ai-detect-zoom` 'auto' | '50%' | '60%' | '70%' | '80%' | '90%': Zoom level for AI detection crop
          - `ai-model` 'flux_schnell' | 'flux_1_1_pro' | 'nano_banana' | 'gpt_image_2': Which AI model generates this layer's background. Costs vary by model — Flux Schnell is a tenth the price of Flux 1.1 Pro. Can be overridden per request by sending ai-model alongside ai-prompt
          - `ai-prompt` string: Prompt for AI background generation — applies when the layer has ai-background-generate enabled
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-blend-mode` 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity': Blend mode applied to the background image
          - `background-color` string: Background color of the container
          - `background-color-gradient` string: Second color for a two-color gradient fill
          - `background-crop` string: Region of the source image to show, as four percentages of the image: left top width height, e.g. 10% 5% 60% 80%. The region is stretched to fill the layer, so give it the layer's aspect ratio. Overrides background-size and background-position; send none to clear it. Ignored while ai-detect is on
          - `background-gradient` string: Full CSS gradient for the fill, e.g. linear-gradient(135deg, #f00 0%, #00f 60%, transparent 100%) — any number of stops at any angle, and radial-gradient or conic-gradient are accepted. Takes priority over background-color-gradient and is drawn on top of background-color
          - `background-gradient-direction` 'left' | 'right' | 'top' | 'bottom': Direction of the gradient fill
          - `background-image` string: Image URL to display in the container
          - `background-position` 'center' | 'top' | 'right' | 'bottom' | 'left' | 'top left' | 'top right' | 'bottom left' | 'bottom right': Anchor position for the background image within the container — most useful when background-size is contain
          - `background-size` 'cover' | 'contain': background-size
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `brightness` number: Brightness adjustment where 1 is normal
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `contrast` number: Contrast adjustment where 1 is normal
          - `grayscale` number: Grayscale filter intensity from 0 to 1
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `png-shadow` string: Drop shadow for PNG images in CSS shadow format
          - `png-stroke-color` string: Outline stroke color around PNG images
          - `png-stroke-width` number: Outline stroke width around PNG images in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `saturate` number: Saturation adjustment where 1 is normal
          - `sepia` number: Sepia filter intensity from 0 to 1
          - `top` number: top
          - `width` number: width
        - LayerCircle: A `circle` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'circle', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `aspect-ratio-locked` boolean: aspect-ratio-locked
          - `background-color` string: Background color of the container
          - `background-color-gradient` string: Second color for a two-color gradient fill
          - `background-gradient` string: Full CSS gradient for the fill, e.g. linear-gradient(135deg, #f00 0%, #00f 60%, transparent 100%) — any number of stops at any angle, and radial-gradient or conic-gradient are accepted. Takes priority over background-color-gradient and is drawn on top of background-color
          - `background-gradient-direction` 'left' | 'right' | 'top' | 'bottom': Direction of the gradient fill
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': responsive-aspect-ratio
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerCircleImageContainer: A `circle_image_container` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'circle_image_container', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `ai-background-generate` 'disabled' | 'enabled': Whether the container should generate its background image via AI when an ai-prompt is supplied in the API request
          - `ai-background-remove` 'disabled' | 'enabled': Whether to automatically remove the background of images submitted to this container via the API
          - `ai-detect` 'off' | 'face' | 'subject': AI detection mode for automatic image positioning
          - `ai-detect-anchor` string: Manual anchor point override for AI detection in x:y format (0-100)
          - `ai-detect-focus` 'first' | 'largest' | 'group': Which detection to focus on when multiple are found
          - `ai-detect-on-fail` 'fallback_cover' | 'fallback_contain': Fallback background-size when no face or subject is detected
          - `ai-detect-zoom` 'auto' | '50%' | '60%' | '70%' | '80%' | '90%': Zoom level for AI detection crop
          - `ai-model` 'flux_schnell' | 'flux_1_1_pro' | 'nano_banana' | 'gpt_image_2': Which AI model generates this layer's background. Costs vary by model — Flux Schnell is a tenth the price of Flux 1.1 Pro. Can be overridden per request by sending ai-model alongside ai-prompt
          - `ai-prompt` string: Prompt for AI background generation — applies when the layer has ai-background-generate enabled
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `aspect-ratio-locked` boolean: aspect-ratio-locked
          - `background-blend-mode` 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity': Blend mode applied to the background image
          - `background-color` string: Background color of the container
          - `background-color-gradient` string: Second color for a two-color gradient fill
          - `background-crop` string: Region of the source image to show, as four percentages of the image: left top width height, e.g. 10% 5% 60% 80%. The region is stretched to fill the layer, so give it the layer's aspect ratio. Overrides background-size and background-position; send none to clear it. Ignored while ai-detect is on
          - `background-gradient` string: Full CSS gradient for the fill, e.g. linear-gradient(135deg, #f00 0%, #00f 60%, transparent 100%) — any number of stops at any angle, and radial-gradient or conic-gradient are accepted. Takes priority over background-color-gradient and is drawn on top of background-color
          - `background-gradient-direction` 'left' | 'right' | 'top' | 'bottom': Direction of the gradient fill
          - `background-image` string: Image URL to display in the container
          - `background-position` 'center' | 'top' | 'right' | 'bottom' | 'left' | 'top left' | 'top right' | 'bottom left' | 'bottom right': Anchor position for the background image within the container — most useful when background-size is contain
          - `background-size` 'cover' | 'contain': background-size
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `brightness` number: Brightness adjustment where 1 is normal
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `contrast` number: Contrast adjustment where 1 is normal
          - `grayscale` number: Grayscale filter intensity from 0 to 1
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `png-shadow` string: Drop shadow for PNG images in CSS shadow format
          - `png-stroke-color` string: Outline stroke color around PNG images
          - `png-stroke-width` number: Outline stroke width around PNG images in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': responsive-aspect-ratio
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `saturate` number: Saturation adjustment where 1 is normal
          - `sepia` number: Sepia filter intensity from 0 to 1
          - `top` number: top
          - `width` number: width
        - LayerImage: A `image` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'image', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `aspect-ratio-locked` boolean: aspect-ratio-locked
          - `background-blend-mode` 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity': Blend mode applied to the image
          - `background-color` string: Background color of the container
          - `background-crop` string: Region of the source image to show, as four percentages of the image: left top width height, e.g. 10% 5% 60% 80%. The region is stretched to fill the layer, so give it the layer's aspect ratio. Overrides background-size and background-position; send none to clear it. Ignored while ai-detect is on
          - `background-image` string: Image URL to display
          - `background-size` 'cover' | 'contain': background-size
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `brightness` number: Brightness adjustment where 1 is normal
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `contrast` number: Contrast adjustment where 1 is normal
          - `grayscale` number: Grayscale filter intensity from 0 to 1
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `png-shadow` string: Drop shadow for PNG images in CSS shadow format
          - `png-stroke-color` string: Outline stroke color around PNG images
          - `png-stroke-width` number: Outline stroke width around PNG images in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `saturate` number: Saturation adjustment where 1 is normal
          - `sepia` number: Sepia filter intensity from 0 to 1
          - `top` number: top
          - `width` number: width
        - LayerSvgShape: A `svg_shape` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'svg_shape', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: Background color of the container
          - `background-color-gradient` string: Second color for a two-color gradient fill
          - `background-gradient` string: Full CSS gradient for the fill, e.g. linear-gradient(135deg, #f00 0%, #00f 60%, transparent 100%) — any number of stops at any angle, and radial-gradient or conic-gradient are accepted. Takes priority over background-color-gradient and is drawn on top of background-color
          - `background-gradient-direction` 'left' | 'right' | 'top' | 'bottom': Direction of the gradient fill
          - `basic-shape` 'triangle' | 'scalene' | 'pentagon' | 'right' | 'trapeze' | 'kite' | 'polygon' | 'parallelogram' | 'ellipse' | 'trefoil' | 'star' | 'semicircle' | 'hexagon' | 'crescent' | 'octagon' | 'cross' | 'ring' | 'heart' | 'arrow' | 'rhombus' | 'custom': The SVG shape to render
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `fill` string: Fill color of the shape
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `stroke` string: Stroke color of the shape outline
          - `stroke-width` number: Stroke width of the shape outline in pixels
          - `svg-url` string: URL of the SVG file to draw when basic-shape is custom. The file keeps its own colors unless fill, a gradient or a stroke is set
          - `top` number: top
          - `width` number: width
        - LayerQrCode: A `qr_code` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'qr_code', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: Background color of the container
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `qr-color` string: Foreground color of the QR code
          - `qr-target` string: URL or text content to encode in the QR code
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerBarCode: A `bar_code` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'bar_code', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: Background color of the container
          - `barcode-color` string: Foreground color of the barcode
          - `barcode-data` string: Data to encode in the barcode
          - `barcode-format` 'CODE128' | 'EAN13' | 'UPC' | 'EAN8': Barcode encoding format
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerRating: A `rating` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'rating', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: Background color of the container
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `rating-background-color` string: Fill color for inactive rating shapes
          - `rating-color` string: Fill color for active rating shapes
          - `rating-count` number: Number of shapes to display
          - `rating-gap` number: Gap between rating shapes in pixels
          - `rating-score` number: Rating score from 0 to 100
          - `rating-shadow` string: Drop shadow for rating shapes in CSS shadow format
          - `rating-shape` 'star' | 'cute_star' | 'heart' | 'circle' | 'diamond' | 'square' | 'hexagon': Shape used for each rating unit
          - `rating-stroke-color` string: Outline stroke color for rating shapes
          - `rating-stroke-width` number: Outline stroke width for rating shapes in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerLottie: A `lottie` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'lottie', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `aspect-ratio-locked` boolean: aspect-ratio-locked
          - `background-color` string: background-color
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `lottie-delay` number: Milliseconds to wait after the animation starts before this Lottie begins playing
          - `lottie-loop` boolean: Whether the Lottie repeats when it reaches its end, rather than holding its last frame
          - `lottie-url` string: URL of the Lottie JSON file to play
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerAnimatedBackground: A `animated_background` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'animated_background', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `aspect-ratio-locked` boolean: aspect-ratio-locked
          - `background-color` string: background-color
          - `background-image` string: background-image
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `motion-blur` number: Softness of the background in pixels
          - `motion-color` string: Colour of the background — its hue drives the preset, so any colour of that hue gives the same result
          - `motion-cycle` number: Milliseconds for one full loop of the background motion
          - `motion-hue` number: Base hue of the background, 0-360
          - `motion-preset` 'aurora' | 'mesh' | 'conic' | 'pulse': Which moving background preset to draw
          - `motion-spread` number: How far the secondary colours sit from the base hue, in degrees
          - `motion-travel` number: How far the background moves, as a percentage of the layer
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
        - LayerAudioWave: A `audio_wave` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'audio_wave', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `aspect-ratio-locked` boolean: aspect-ratio-locked
          - `audio-url` string: URL of the audio file the wave follows
          - `background-color` string: background-color
          - `background-image` string: background-image
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `wave-bars` number: Number of bars
          - `wave-color` string: Colour of the bars
          - `wave-envelope` string: Loudness samples the wave is drawn from, 25 per second from 0 to 1, comma-separated — set automatically when the audio URL is analysed
          - `wave-gap` number: Gap between bars in pixels
          - `wave-min-height` number: Height of a bar in silence, as a percentage of the layer
          - `wave-mirror` boolean: Grow the bars from the middle in both directions rather than up from the bottom
          - `wave-offset` number: Milliseconds into the audio at which the animation starts
          - `wave-radius` number: Corner radius of each bar in pixels
          - `wave-sensitivity` number: Scales how far the bars move — above 1 exaggerates quiet passages
          - `width` number: width
        - LayerGroup: A `group` layer.
          - `id` string, required: Unique layer id within the config
          - `type` 'group', required: Layer type discriminator
          - `name` string: Optional human-readable layer name
          - `anchor-gap-x` number: Horizontal offset from the anchor point in pixels
          - `anchor-gap-y` number: Vertical offset from the anchor point in pixels
          - `anchor-point` 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right': Which point on the target layer to anchor to
          - `anchor-to` string: Name of another layer to anchor this layer's position to
          - `anchor-type` 'container' | 'text': Whether to anchor to the container bounds or text bounds
          - `background-color` string: Background color of the container
          - `blur` number: Gaussian blur radius in pixels
          - `border-color` string: border-color
          - `border-radius` number: Border radius in pixels for rounded corners
          - `border-style` 'none' | 'solid': border-style
          - `border-width` number: border-width
          - `box-shadow` string: box-shadow
          - `clip-mode` 'outline' | 'alpha': How clip-to hides this layer. outline cuts it to the target's shape. alpha also fades it by the transparency of the target's fill — its background-gradient, or else its background-color — so a gradient running to transparent fades this layer out. Hide the target layer to use it as a mask only
          - `clip-to` string: Id or name of another layer to clip this layer to — only the part inside that layer's box is drawn, following its border-radius and rotation. Clips chain: a layer clipped to a layer that is itself clipped shows only inside both
          - `collapsed` boolean: collapsed
          - `height` number: height
          - `hidden` boolean: Hide or show this layer
          - `left` number: left
          - `opacity` number: Opacity from 0 (transparent) to 1 (opaque)
          - `padding` number: padding
          - `perspective` number: Perspective distance for 3D transforms in pixels
          - `responsive-anchor-gap` 'none' | 'scale' | 'scale-x' | 'scale-y' | 'stretch' | 'stretch-x' | 'stretch-y': How the anchor gap adjusts when the template is resized
          - `responsive-aspect-ratio` 'free' | 'locked': Whether the layer keeps its aspect ratio when responsively resized
          - `responsive-position` 'none' | 'scale' | 'center-x' | 'center-y' | 'center' | 'pin-right' | 'pin-bottom' | 'pin-right-bottom' | 'center-x-pin-bottom' | 'center-y-pin-right': How the layer repositions when the template is resized
          - `responsive-size` 'none' | 'scale' | 'stretch-x' | 'stretch-y' | 'stretch': How the layer resizes when the template is resized
          - `rotate` number: Rotation angle in degrees
          - `rotateX` number: 3D rotation around the X axis in degrees
          - `rotateY` number: 3D rotation around the Y axis in degrees
          - `rotateZ` number: 3D rotation around the Z axis in degrees
          - `top` number: top
          - `width` number: width
    - `keyframes` Keyframes: Animation keyframes keyed by object id. Each value is an ordered array of keyframes for that object.
  - `created_at` string, date-time

## Other responses

- `403`: Template's api_write_access is `owner_only` and the caller's key is not owned by its creator
- `404`: Template not found
- `422`: Unknown preset, unknown layer id, or a text-only preset aimed at a non-text layer
- `423`: Template's api_write_access is `nobody` — unlock via the dashboard

## Changes

- **2026-09-24** `745da36239a3`: 28 warning
  - added the new `center-x-pin-bottom` enum value to the `config/objects/items/oneOf[#/components/schemas/LayerAnimatedBackground]/responsive-position` response property for the response status `200`
  - added the new `center-x-pin-bottom` enum value to the `config/objects/items/oneOf[#/components/schemas/LayerAudioWave]/responsive-position` response property for the response status `200`
  - added the new `center-x-pin-bottom` enum value to the `config/objects/items/oneOf[#/components/schemas/LayerBarCode]/responsive-position` response property for the response status `200`
  - added the new `center-x-pin-bottom` enum value to the `config/objects/items/oneOf[#/components/schemas/LayerCircleImageContainer]/responsive-position` response property for the response status `200`
  - …24 more
- **2026-09-23** `37156820eb24`: 1 warning, 1 info
  - added the new `custom` enum value to the `config/objects/items/oneOf[#/components/schemas/LayerSvgShape]/basic-shape` response property for the response status `200`
  - added the optional property `config/objects/items/oneOf[#/components/schemas/LayerSvgShape]/svg-url` to the response with the `200` status
- …earlier changes not shown

[Operation history](https://skmtc.dev/bannerbear/apis/bannerbear-v5-api/changes/animation_templates/:uid/animate/post.md)

---

[API](https://skmtc.dev/bannerbear/apis/bannerbear-v5-api.md) - [All operations](https://skmtc.dev/bannerbear/apis/bannerbear-v5-api/llms.txt) - [OpenAPI document](https://skmtc.dev/bannerbear/apis/bannerbear-v5-api/revisions/357256cbd1e5?raw)
