Skip to main content
PUT
/
pictoryapis
/
v2
/
video
/
storyboard
/
{jobid}
/
elements
Update Storyboard Elements
curl --request PUT \
  --url https://api.pictory.ai/pictoryapis/v2/video/storyboard/{jobid}/elements \
  --header 'Authorization: <authorization>' \
  --header 'Content-Type: <content-type>' \
  --data '
{
  "id": "<string>",
  "elementType": "<string>",
  "type": "<string>",
  "startTime": 123,
  "duration": 123
}
'
// No content returned. The elements have been updated successfully.

Overview

The Update Storyboard Elements API allows you to modify existing render elements generated from the Create Storyboard Preview API. Use this endpoint to update background visuals, scene text, or background music URLs before rendering the final video using the Render from Preview API.
This endpoint only updates existing elements in the storyboard. You cannot add new elements — only modify elements that were generated during preview creation. Each element is identified by its unique id.
The storyboard preview job must be in a completed status before you can update its elements. Use the Get Job API to verify the job status.

When to Use This API

ScenarioDescription
Replace background visualsChange a scene’s background image or video URL
Update scene textModify the text content displayed on a scene
Change background musicReplace the background music track URL
Adjust element timingModify startTime or duration of elements

Workflow


API Endpoint

PUT https://api.pictory.ai/pictoryapis/v2/video/storyboard/{jobid}/elements

Path Parameters

jobid
string
required
The job ID returned from the Create Storyboard Preview API. The job must be in completed status.

Request Headers

Authorization
string
required
API key for authentication
Authorization: YOUR_API_KEY
Content-Type
string
required
Must be application/json

Request Body

The request body is a JSON array of element objects. Each object must include the required fields (id, elementType, type, startTime, duration) along with any properties you want to update. Only elements with matching id values in the existing storyboard will be updated.
id
string
required
The unique identifier of the element to update. Must match an existing element id from the storyboard preview renderParams.elements array.Examples: backgroundElement_20260306230202544742ecd40c041449..., bgMusic, voiceOver, SceneText_202603062302035443dd4953bf12...
elementType
string
required
The type category of the element. Must match the existing element’s elementType.Values:
  • backgroundElement — Scene background image or video
  • audioElement — Background music or voice-over audio
  • SceneText — Scene text overlay (displayed on scenes)
  • layerItem — Layer items such as title text, avatars, or overlays
type
string
required
The media type of the element. Must match or be compatible with the element.Values:
  • video — Video media
  • image — Image media
  • audio — Audio media
  • text — Text content
startTime
number
required
The start time of the element in seconds. Must be >= 0.
duration
number
required
The duration of the element in seconds. Must be > 0.

Element Attributes Reference

Any additional properties included in the element update object will be merged with the existing element. Below is a comprehensive reference of all attributes for each element type.
Element IDs are auto-generated unique strings (e.g., backgroundElement_20260306230202544742ecd40c041449dac21bb737c799201). Always retrieve the actual IDs from the preview job response rather than constructing them manually.

Element Types Summary

ElementelementTypetypeid PatternDescription
Scene BackgroundbackgroundElementvideo, imagebackgroundElement_{uniqueId}Background visual for each scene
Scene TextSceneTexttextSceneText_{uniqueId}Sentence-level text overlay on a scene
Title/Layer TextlayerItemtext{uniqueId}Title text, headings, or overlay text
Layer VisuallayerItemvideo, image{uniqueId}Overlay images, videos, or avatars
Background MusicaudioElementaudiobgMusicBackground music track
Voice-OveraudioElementaudiovoiceOverAI-generated narration audio

Background Element (backgroundElement)

The background element is the full-screen visual behind each scene. One background element exists per scene.

Media Properties

PropertyTypeDescriptionExample
urlstringFull-resolution media URL used for final video rendering"https://cdn.com/video-hd.mp4"
visualUrlstringMedia URL used for preview playback. Can be a lower-resolution video or even a thumbnail image for faster preview loading. When rendering the final video, url is used instead"https://cdn.com/video-preview.mp4" or "https://cdn.com/preview-thumb.jpg"
typestringMedia type of url: video or image"video"
visualTypestringMedia type of visualUrl. Can differ from type — e.g., visualType may be image (thumbnail) while type is video (full render)"image"
backgroundColorstringSolid background color in RGBA format. Used as fallback or when no media URL is set"rgba(0, 0, 0, 1)"

Display Properties

PropertyTypeDefaultDescription
widthstring"100%"Element width as a percentage of the video frame
xPercentstring"0%"Horizontal position offset as percentage
yPercentstring"0%"Vertical position offset as percentage
objectModestring"cover"How the media fits the frame. cover fills and crops to fit, fit letterboxes to show entire media
cursorstring"default"Mouse cursor style in the editor

Video Playback Properties

PropertyTypeDefaultDescription
loopbooleantrueWhether to loop video playback when it reaches the end
mutebooleantrueWhether to mute the video’s built-in audio track
segmentsarray[]Time segments for video clipping. Each segment: { "start": 0, "end": 10 }

Visual Effects

PropertyTypeDescriptionExample
colorOverlayobjectSemi-transparent color overlay on top of the backgroundSee below
colorOverlay.hidebooleanWhether the overlay is hiddenfalse
colorOverlay.bgColorstringOverlay color in RGB format"rgb(22,91,110)"
colorOverlay.opacitynumberOverlay opacity from 0 (transparent) to 1 (opaque)0.65

Metadata

PropertyTypeDescriptionExample
librarystringSource library where the media was selected from"getty"
{
  "id": "backgroundElement_20260306230202544742ecd40c041449dac21bb737c799201",
  "elementType": "backgroundElement",
  "type": "video",
  "url": "https://media.gettyimages.com/id/2262113992/video/professor-lectures.mp4",
  "backgroundColor": "rgba(0, 0, 0, 1)",
  "xPercent": "0%",
  "yPercent": "0%",
  "width": "100%",
  "objectMode": "cover",
  "loop": true,
  "mute": true,
  "segments": [],
  "startTime": 0,
  "duration": 7.6,
  "colorOverlay": {
    "hide": false,
    "bgColor": "rgb(22,91,110)",
    "opacity": 0.65
  },
  "cursor": "default",
  "visualUrl": "https://media.gettyimages.com/id/2262113992/video/professor-lectures.mp4",
  "visualType": "video",
  "library": "getty"
}

Scene Text (SceneText) and Layer Text (layerItem with type: "text")

Text elements display text content on top of scenes. SceneText elements represent the per-sentence text overlay for a scene, while layerItem text elements represent titles, headings, or additional text overlays.

Content Properties

PropertyTypeDescriptionExample
textstringText content to display. Supports <strong> tags to highlight keywords using keywordColor"AI will <strong>save time</strong>"

Font & Styling Properties

PropertyTypeDefaultDescriptionExample
fontFamilystring"Arial"Font family name"Space Grotesk"
fontWeightnumber400Font weight (400 = normal, 700 = bold)400
fontSizestring"16"Font size in pixels"32"
fontColorstringText color in RGB or RGBA format"rgb(255,255,255)"
keywordColorstringColor applied to text wrapped in <strong> tags"rgba(248, 173, 151, 1)"
textAlignstring"left"Text alignment: left, center, or right"center"
decorationarray[]Text decorations. Values: "decor-bold", "decor-italics", "decor-underline", "decor-linethrough"["decor-bold"]
casestring"none"Text case transformation: none, case-uppercase, case-lowercase, case-capitalize, case-smallcapitalize"none"
lineHeightnumber1.3Line height multiplier for spacing between lines1.48

Text Background Properties

PropertyTypeDefaultDescriptionExample
textBackgroundColorstring"rgba(0,0,0,0)"Background color behind the text or as a fill for the full-width box"rgba(22, 91, 110, 1)"
textBackgroundRadiusarray[0,0,0,0]Border radius for the text background box: [topLeft, topRight, bottomRight, bottomLeft][8, 8, 8, 8]
boxBackgroundbooleanfalseWhether text has a visible background boxfalse

Text Shadow Properties

PropertyTypeDefaultDescriptionExample
dropShadowColorstring"rgba(0,0,0,0)"Drop shadow color in RGBA format"rgba(0,0,0,1)"
dropShadowBlurnumber0Shadow blur radius3

Layout & Position Properties

PropertyTypeDefaultDescriptionExample
widthstring"90%"Text box width as percentage of the video frame"70.00%"
fullWidthbooleanfalseWhether text spans the full viewport width with paddingfalse
presetstringPosition preset anchor. See Position Presets"bottom-left"
opacitynumber1Element transparency from 0 (invisible) to 1 (opaque)1
draggablebooleantrueWhether the element can be repositioned in the editortrue
resizablebooleanfalseWhether the element can be resized in the editorfalse
canChangeWidthOnlybooleantrueRestrict resizing to width only (height adjusts automatically)true
snapTobooleantrueSnap to alignment guidelines when draggingtrue
midHandlebooleanfalseUse center handle for resizingfalse
cropablebooleanfalseWhether the element can be croppedfalse

Bullet Properties

PropertyTypeDefaultDescriptionExample
bulletbooleanfalseDisplay a bullet point beside each text linefalse
bulletColorstring"#e30022"Bullet point color"#e30022"
bulletWidthnumber15Bullet point width in pixels15

Animation Properties

PropertyTypeDescriptionExample
animationarrayArray of animation objects for entry and exit effectsSee below
animation[].namestringAnimation name: Blur, Drift, Fade, Wipe, Show, Elastic, Typewriter, TextReveal, Bulletin, None"Blur"
animation[].typearrayAnimation phase: ["entry"] or ["exit"]["entry"]
animation[].writingStylestringHow text animates in: character (per letter), word (per word), line (per line), paragraph (all at once)"paragraph"
animation[].speedobjectAnimation speed configuration{ "value": 2 }
animation[].speed.valuenumberSpeed value (higher = faster)2
animation[].directionstringDirection of animation: up, down, left, right"up"

Computed Properties (read-only)

PropertyTypeDescription
textLinesarrayPre-calculated line break and character position data used by the rendering engine. Each entry contains character positions (charX), highlight flags (h), and line dimensions (ht). This is auto-generated — when updating text content, you must set textLines to an empty array [] so that line breaks and character positions are recalculated during preview and render
{
  "id": "SceneText_202603062302035443dd4953bf1294b4283d4b8ba0259fd1a",
  "elementType": "SceneText",
  "type": "text",
  "text": "By <strong>automating</strong> <strong>tasks</strong> like <strong>content generation</strong>, <strong>visual design</strong>, and <strong>video editing</strong>, AI will <strong>save time</strong> and <strong>enhance consistency</strong>.",
  "fontFamily": "Space Grotesk",
  "fontWeight": 400,
  "fontSize": "32",
  "fontColor": "rgb(255,255,255)",
  "keywordColor": "rgba(248, 173, 151, 1)",
  "textBackgroundColor": "rgba(22, 91, 110, 1)",
  "dropShadowColor": "rgba(0,0,0,0)",
  "dropShadowBlur": 3,
  "textAlign": "left",
  "decoration": [],
  "case": "none",
  "lineHeight": 1.465625,
  "textBackgroundRadius": [0, 0, 0, 0],
  "boxBackground": false,
  "width": "70.00%",
  "preset": "bottom-left",
  "opacity": 1,
  "draggable": true,
  "resizable": false,
  "snapTo": true,
  "midHandle": false,
  "canChangeWidthOnly": true,
  "cropable": false,
  "startTime": 7.6,
  "duration": 11.1,
  "animation": [
    {
      "writingStyle": "line",
      "name": "Drift",
      "type": ["entry"],
      "speed": { "value": 1 },
      "direction": "left"
    },
    {
      "name": "None",
      "type": ["exit"]
    }
  ]
}
{
  "id": "2026030623020497002befca37e444fb880a281abadc0c756",
  "elementType": "layerItem",
  "type": "text",
  "text": "AI's Impact on Educators and Creators",
  "fontFamily": "Space Grotesk",
  "fontWeight": 400,
  "fontSize": "48",
  "fontColor": "rgb(255,255,255)",
  "keywordColor": "rgba(248, 173, 151, 1)",
  "textBackgroundColor": "rgba(0,0,0,0)",
  "dropShadowColor": "rgba(0,0,0,0)",
  "dropShadowBlur": 3,
  "textAlign": "center",
  "decoration": [],
  "case": "none",
  "lineHeight": 1.48125,
  "textBackgroundRadius": [0, 0, 0, 0],
  "boxBackground": false,
  "width": "90.00%",
  "fullWidth": false,
  "preset": "center-center",
  "opacity": 1,
  "draggable": true,
  "resizable": false,
  "snapTo": true,
  "midHandle": false,
  "canChangeWidthOnly": true,
  "cropable": false,
  "startTime": 0,
  "duration": 7.6,
  "animation": [
    {
      "writingStyle": "paragraph",
      "name": "Blur",
      "type": ["entry"],
      "speed": { "value": 2 },
      "direction": "up"
    },
    {
      "name": "None",
      "type": ["exit"]
    }
  ]
}

Audio Element (audioElement)

Audio elements represent background music (bgMusic) or voice-over narration (voiceOver).

Audio Properties

PropertyTypeDescriptionExample
urlstringAudio file URL (MP3 or compatible format)"https://tracks.melod.ie/.../track.mp3"
fadebooleanWhether to apply fade in/out effect to the audio. Typically true for background musictrue

Segments

PropertyTypeDescriptionExample
segmentsarrayArray of audio segment objects. Each segment defines a playback range with its own volume level. Segments correspond to individual scenes in the videoSee below
segments[].startTimenumberStart time of the segment in the video timeline (seconds)0
segments[].durationnumberDuration of the segment (seconds)7.6
segments[].volumenumberVolume level for this segment (0 to 1). Background music typically uses 0.1, voice-over uses 10.1
segments[].audioTimenumberOffset position in the audio file to start playback from (seconds)0
{
  "type": "audio",
  "id": "bgMusic",
  "elementType": "audioElement",
  "fade": true,
  "url": "https://tracks.melod.ie/track_versions/23517/MEL565_15_1_Utopia.mp3",
  "segments": [
    { "startTime": 0, "duration": 7.6, "volume": 0.1, "audioTime": 0 },
    { "startTime": 7.6, "duration": 11.1, "volume": 0.1, "audioTime": 7.6 },
    { "startTime": 18.7, "duration": 7.6, "volume": 0.1, "audioTime": 18.7 },
    { "startTime": 26.3, "duration": 11, "volume": 0.1, "audioTime": 26.3 },
    { "startTime": 37.3, "duration": 8.5, "volume": 0.1, "audioTime": 37.3 },
    { "startTime": 45.8, "duration": 9.1, "volume": 0.1, "audioTime": 45.8 },
    { "startTime": 54.9, "duration": 10.9, "volume": 0.1, "audioTime": 54.9 }
  ],
  "startTime": 0,
  "duration": 100000
}
{
  "type": "audio",
  "id": "voiceOver",
  "elementType": "audioElement",
  "url": "https://audios-prod.pictorycontent.com/polly/production/projects/.../voiceover.mp3",
  "segments": [
    { "startTime": 0, "duration": 7.6, "volume": 1, "audioTime": 0 },
    { "startTime": 7.6, "duration": 11.1, "volume": 1, "audioTime": 7.6 },
    { "startTime": 18.7, "duration": 7.6, "volume": 1, "audioTime": 18.7 },
    { "startTime": 26.3, "duration": 11, "volume": 1, "audioTime": 26.3 },
    { "startTime": 37.3, "duration": 8.5, "volume": 1, "audioTime": 37.3 },
    { "startTime": 45.8, "duration": 9.1, "volume": 1, "audioTime": 45.8 },
    { "startTime": 54.9, "duration": 10.9, "volume": 1, "audioTime": 54.9 }
  ],
  "startTime": 0,
  "duration": 100000
}

Layer Visual Element (layerItem with type: "video" or "image")

Layer visual elements are overlay images or videos displayed on top of the background, such as avatars, logos, or decorative graphics.
PropertyTypeDefaultDescriptionExample
urlstringFull-resolution media URL used for final video rendering"https://cdn.com/avatar-hd.mp4"
visualUrlstringMedia URL used for preview playback. Can be a lower-resolution video or a thumbnail image for faster preview loading"https://cdn.com/avatar-preview.mp4" or "https://cdn.com/avatar-thumb.jpg"
typestringMedia type of url: video or image"video"
visualTypestringMedia type of visualUrl. Can differ from type (e.g., image thumbnail for a video render)"image"
objectModestring"cover"How media fits: cover (fill and crop) or fit (letterbox)"cover"
widthstringElement width as percentage"25%"
heightstringElement height as percentage (optional)"30%"
presetstringPosition preset anchor"bottom-right"
xPercentstringHorizontal position when no preset"70%"
yPercentstringVertical position when no preset"60%"
opacitynumber1Transparency (0 to 1)1
loopbooleantrueLoop video playbacktrue
mutebooleanfalseMute video audiotrue
aspectRationumberWidth/height ratio0.5625
flipHorizontalbooleanfalseMirror the element horizontallyfalse
flipVerticalbooleanfalseMirror the element verticallyfalse
maskShapestring"rectangle"Mask shape: rectangle or circle"circle"
librarystringSource library (e.g., avatar, giphy)"avatar"

Position Presets

The preset property defines a named anchor position for text and layer elements within the video frame:
PresetDescription
top-leftAnchored to top-left corner
top-centerAnchored to top-center
top-rightAnchored to top-right corner
center-leftAnchored to middle-left
center-centerCentered in the frame
center-rightAnchored to middle-right
bottom-leftAnchored to bottom-left corner
bottom-centerAnchored to bottom-center
bottom-rightAnchored to bottom-right corner
full-width-topFull width, anchored to top
full-width-centerFull width, centered vertically
full-width-bottomFull width, anchored to bottom

Text Animations

Text elements support entry and exit animations. The animation array contains animation configuration objects:
Animation NameDescription
BlurText fades in with a blur effect
DriftText slides in from a specified direction
FadeSimple fade in/out
WipeText wipes in from a direction
ShowInstant appearance
ElasticBouncy elastic entrance
TypewriterCharacters appear one by one
TextRevealText reveals progressively
BulletinNews bulletin style animation
NoneNo animation
Writing Styles control the granularity of the animation:
Writing StyleDescription
characterAnimate one character at a time
wordAnimate one word at a time
lineAnimate one line at a time
paragraphAnimate the entire text block at once

Response

// No content returned. The elements have been updated successfully.
A 204 No Content response indicates the elements were updated successfully. The updated elements will be reflected when you:

Code Examples

Replace YOUR_API_KEY with your actual API key and YOUR_JOB_ID with the storyboard preview job ID.

Update Background Visual

curl --request PUT \
  --url https://api.pictory.ai/pictoryapis/v2/video/storyboard/YOUR_JOB_ID/elements \
  --header 'Authorization: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '[
    {
      "id": "backgroundElement_20260306230202544742ecd40c041449dac21bb737c799201",
      "elementType": "backgroundElement",
      "type": "video",
      "startTime": 0,
      "duration": 7.6,
      "url": "https://your-cdn.com/new-background.mp4",
      "visualUrl": "https://your-cdn.com/new-background.mp4",
      "visualType": "video"
    }
  ]'

Update Scene Text

// Find the scene text element to update
const sceneTextElement = renderParams.elements.find(
  el => el.elementType === 'SceneText' && el.startTime === 7.6
);

const response = await fetch(
  `https://api.pictory.ai/pictoryapis/v2/video/storyboard/${jobId}/elements`,
  {
    method: 'PUT',
    headers: {
      'Authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify([
      {
        id: sceneTextElement.id,
        elementType: 'SceneText',
        type: 'text',
        startTime: sceneTextElement.startTime,
        duration: sceneTextElement.duration,
        text: 'By <strong>automating</strong> repetitive <strong>tasks</strong>, AI frees up time for <strong>creative work</strong> and <strong>strategic thinking</strong>.',
        textLines: [] // Clear textLines so line breaks are recalculated
      }
    ])
  }
);

if (response.status === 204) {
  console.log('Scene text updated successfully');
}

Update Background Music

const response = await fetch(
  `https://api.pictory.ai/pictoryapis/v2/video/storyboard/${jobId}/elements`,
  {
    method: 'PUT',
    headers: {
      'Authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify([
      {
        id: 'bgMusic',
        elementType: 'audioElement',
        type: 'audio',
        startTime: 0,
        duration: 100000,
        url: 'https://your-cdn.com/new-background-music.mp3'
      }
    ])
  }
);

if (response.status === 204) {
  console.log('Background music updated successfully');
}

Update Multiple Elements

// Update background visuals, scene text, and music in a single request
const elements = renderParams.elements;

// Find elements by type
const bg1 = elements.find(el => el.elementType === 'backgroundElement' && el.startTime === 0);
const bg2 = elements.find(el => el.elementType === 'backgroundElement' && el.startTime === 7.6);
const sceneText = elements.find(el => el.elementType === 'SceneText' && el.startTime === 7.6);

const response = await fetch(
  `https://api.pictory.ai/pictoryapis/v2/video/storyboard/${jobId}/elements`,
  {
    method: 'PUT',
    headers: {
      'Authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify([
      // Replace scene 1 background with a custom image
      {
        id: bg1.id,
        elementType: 'backgroundElement',
        type: 'image',
        startTime: 0,
        duration: 7.6,
        url: 'https://your-cdn.com/intro-background.jpg',
        visualUrl: 'https://your-cdn.com/intro-background.jpg',
        visualType: 'image'
      },
      // Replace scene 2 background with a custom video
      {
        id: bg2.id,
        elementType: 'backgroundElement',
        type: 'video',
        startTime: 7.6,
        duration: 11.1,
        url: 'https://your-cdn.com/demo-footage.mp4',
        visualUrl: 'https://your-cdn.com/demo-footage.mp4',
        visualType: 'video'
      },
      // Update scene text — set textLines to null so line breaks are recalculated
      {
        id: sceneText.id,
        elementType: 'SceneText',
        type: 'text',
        startTime: 7.6,
        duration: 11.1,
        text: 'Updated scene text with <strong>highlighted keywords</strong> for emphasis.',
        textLines: []
      },
      // Replace background music
      {
        id: 'bgMusic',
        elementType: 'audioElement',
        type: 'audio',
        startTime: 0,
        duration: 100000,
        url: 'https://your-cdn.com/corporate-music.mp3'
      }
    ])
  }
);

if (response.status === 204) {
  console.log('All elements updated successfully');
}

Important Notes

You cannot add new elements to the storyboard. Only elements that already exist in the renderParams.elements array (returned from the storyboard preview job) can be updated. Elements are matched by their unique id.
After creating a storyboard preview and polling the job to completion, the response includes renderParams.elements — an array of all elements with their id values. Element IDs are auto-generated unique strings. Always retrieve the actual IDs from the response rather than constructing them manually.
When you update an element, the properties you provide are merged with the existing element properties. Properties you do not include in the update remain unchanged. For example, updating only the url of a background element will keep its existing loop, mute, objectMode, and other properties.
When updating the text property of a SceneText or layerItem text element, you must set textLines to an empty array []. The textLines array contains pre-calculated line break positions and character coordinates that are specific to the original text. If you change the text but keep the old textLines, the rendering engine will use stale layout data, causing incorrect line breaks and character positioning. Setting textLines to [] ensures the system recalculates the layout during preview and video rendering.
Scene text (SceneText) elements support <strong> tags for keyword highlighting. For example: "This is <strong>important</strong> text" will render “important” with the element’s keywordColor.
Once elements are updated, the changes are saved to the storyboard job. When you subsequently render the video using Render from Preview, the updated elements will be used in the final render.