←Video Development Kit API
The Scrptly Video Development Kit (VDK) is a powerful JavaScript/TypeScript SDK that allows you to create, customize, and render videos programmatically using code. It provides a high-level interface for defining video projects, adding layers (text, images, audio, TTS, etc.), animating properties over time, and rendering the final output.First Video Example
This minimal example shows how to:
- Create a new Scrptly project
- Add an AI-generated background image
- Animate a text layer
- Generate background TTS
- Render the video
import Scrptly from 'scrptly';
async function makeVideo() {
// 1. Set up API key
Scrptly.setApiSettings({ apiKey: process.env.SCRPTLY_API_KEY });
// 2. Create a new video project (size: 1080×1080)
const $ = new Scrptly({ size: { width: 1080, height: 1080 } });
// 3. Add a background image via AI prompt
const bg = $.addImage(
{ fit: 'cover' }, // ▶ layer properties
{
prompt: 'A misty mountain sunrise over a calm lake',
model: 'falai:fal-ai/ideogram/v3'
} // ▶ layer settings
);
// 4. Animate image blur in over 5 seconds (non-blocking)
bg.animate(
{ filterBlur: 0 },
{ filterBlur: 10 },
{ duration: '5s', wait: false }
);
// 5. Add a “Hello World” text layer with fade-in
const text = $.addText(
{ text: 'Hello, World!', fontSize: 1.5, color: '#ffffff' },
{ fontFamily: 'Noto Sans' } // uses default easing
);
text.animate(
{ opacity: 0 },
{ opacity: 1, scale: 1.2 },
{ duration: '3s', wait: false } // don't wait until it's done
);
// 6. Pause 1 second before TTS
$.wait('1s');
// 7. Add TTS layer and speak
const tts = $.addTTS(
{},
{ model: 'elevenlabs' }
);
tts.say('Welcome to Scrptly!');
// 8. Render and log output URL
const videoInfo = await $.renderVideo();
console.log('Your video is ready:', videoInfo);
}
makeVideo().catch(console.error);
That’s it! You now have a working “Hello World” video rendered via Scrptly. Proceed to Core Concepts to learn about customizing your project settings, layers, timeline actions, and more.
Core Concepts
Scrptly Object
- Creating a Scrptly Instance
Instantiate a new scrptly instance by importingScrptlyand passing optional project settings:
import Scrptly from 'scrptly';
// Create a 1000×1000 project at 30 fps
const $ = new Scrptly({
size: { width: 1000, height: 1000 },
frameRate: 30
});
- Standard variable
By convention, use$to reference your Scrptly instance throughout your script.
Layers
All content in your video is represented by layers. Each layer type (Text, Image, Video, Audio, TTS, Captions) shares the same signature:
$.add[LayerType]( // One of addText, addImage, addVideo...
properties = {}, // animatable properties over time
settings = {}, // static settings (e.g. source, prompt, model)
options = {} // insertion options (index, waitFor)
);
Layer methods
.animate(from, to, options)
Animate properties from one state to another:
textLayer.animate(
{ opacity: 0, scale: 0.5 }, // start state, if a property you want to animate is omitted, it's value will automatically be evaluated from the layer state
{ opacity: 1, scale: 1 }, // end state
{ duration: '2s', wait: true, easing: 'easeInOut' } // options
);
.set(properties)
Set properties immediately without animation:
textLayer.set({ opacity: 0.5, scale: 1.2 });
Static vs AI-Generated Content
- Static assets
Provide a local file or URL insettings.source:
$.addImage(
{},
{ source: '/path/to/myimage.png', sourceType: 'file' }
);
- AI-Generated assets
Supply apromptandmodelinstead ofsource:
$.addImage(
{},
{ prompt: 'A cute picture of a cat.', model: 'openai' }
);
- API keys & caching
- Configure AI providers on your account page: My Scrptly Account
- Make sure to monitor your usage of thirdparty models and rotate keys as needed.
- Scrptly caches generated assets by default. Disable caching
options.cache=trueor manually delete assets to force fresh AI generation.
Timeline Control
Control the flow and timing of your video with these core methods:
.wait(duration)
Pause the script for a specified time or frame count:
$.wait('2s'); // wait 2 seconds
$.wait(60); // wait 60 frames
.parallel([...])
Run multiple actions simultaneously, then resume once all complete:
$.parallel([
() => {
textLayer.animate({ opacity: 0 }, { opacity: 1 }, { duration: '1s' });
textLayer.animate({ opacity: 1 }, { opacity: 0 }, { duration: '1.5s' });
},
() => imageLayer.animate({ scale: 0 }, { scale: 1 }, { duration: '2s' })
]); // waits for both animations to finish before continuing (2.5s in this example)
Rendering
Finalize and produce your project with one of two methods:
-
.renderVideo(options)- Executes in the cloud and returns a URL to the rendered MP4.
- Verbose progress output by default, can be disabled via options.verbose=false
- Automatically uploads and caches local files; invokes AI models where configured.
- Render quotas vary by plan: Pricing
-
.generateProject(options)- Prepares all AI-generated media and uploads assets.
- Returns URL of a Scrptly Project that you can open in your browser and manage with the Scrptly visual editor.
- Ideal for in-browser renders
Both methods accept a RenderOptions object, including:
export type RenderOptions = {
verbose?: boolean; // show live progress (default: true)
};
Layer API
An overview of all available layer types, including interface-only layers (cannot be added directly) and concrete layers (addable via $.add… methods).
For visual properties, most of them are CSS properties, so you can refer to the MDN CSS Reference for more details.
Text Layer
Inherits TextualLayer, VisualLayer and BaseLayer.
$.addText(
{
"text": "Hello, World!", // The text content
},
{
// No extra settings beyond inherited TextualLayerSettings
}
)
Image Layer
Inherits MediaLayer, VisualLayer and BaseLayer.
$.addImage(
{
"fit": "cover" // enum: "contain","cover"
},
{
// Static:
"source": "path/to/image.jpg",
// OR Dynamic:
"prompt": "",
"model": "unsplash | openai | google | falai",// you can choose a specific model for a given provider like this: openai:gpt-image-1
"modelSettings": {}, // additional model parameters when calling the thirdparty API
"cache": true
}
)
Audio Layer
Inherits AuditoryLayer and BaseLayer.
$.addAudio(
{
// No extra properties
},
{
// Static:
"source": "path/to/audio.mp3",
// OR Dynamic:
"prompt": "",
"model": "elevenlabs | falai", // you can choose a specific model for a given provider like this: falai:cassetteai/music-generator
"duration": 5, // duration in seconds
"modelSettings": {}, // additional model parameters when calling the thirdparty API
"cache": true
}
)
Video Layer
Inherits MediaLayer, AuditoryLayer and BaseLayer.
$.addVideo(
{
"fit": "cover" // enum: "contain","cover"
// plus auditory properties: volume?, pan?, pitch?, mute?
},
{
// Static:
"source": "path/to/video.mp4",
// OR Dynamic:
"prompt": "",
"model": "falai | google", // you can choose a specific model for a given provider like this: falai:fal-ai/kling-video/v2.1/master/image-to-video
"modelSettings": {},
"image": { // seed image for generating ai video, only supported by some models
"source": "path/to/image.png"
// OR Dynamic:
"prompt": "",
"model": "unsplash | openai | google | falai",// you can choose a specific model for a given provider like this: openai:gpt-image-1
"modelSettings": {}, // additional model parameters when calling the thirdparty API
"cache": true
},
"cache": true,
"duration": 5 // duration in seconds
}
)
TTS Layer
Inherits AuditoryLayer and BaseLayer. Special method .say(text, {wait?}).
const ttsLayer = $.addTTS(
{
// No extra properties
},
{
"model": "",
"voice": "default | voiceId",
"modelSettings": {}, // additional model parameters when calling the thirdparty API
"cache": true
}
)
ttsLayer.say("Hello, this is a text-to-speech layer!", { wait: true /* wether to wait for the audio to complete before moving on to the next action */ });
Captions Layer
Inherits TextualLayer and BaseLayer.
$.addCaptions(
{
// No extra properties
},
{
"source": "string",
"maxCharsPerLine": number,
"maxLines": number
}
)
Interface-only layers
BaseLayer
This layer cannot be added directly. All layers inherit from it.
Properties:
{}
Settings:
{
// Optional name for the layer
"name": "string",
// Whether the layer is enabled (default: true)
"enabled": "boolean",
// Whether the layer is locked (default: false)
"locked": "boolean",
// When the layer starts (seconds, default: 0)
"startTime": "number",
// When the layer ends (false or seconds, default: false)
"endTime": "false | number",
// Playback speed (default: 1)
"speed": "number"
}
VisualLayer
This layer cannot be added directly, but other layers inherit from it.
Properties:
{
"visible": true,
"opacity": 1,
"position": [0.5, 0.5],
"scale": 1,
"rotation": 0,
"anchor": [0.5, 0.5],
"backgroundColor": "transparent",
"borderWidth": 0,
"borderStyle": "solid", // enum: "none","solid","dashed","dotted","double","groove","ridge","inset","outset"
"borderColor": "#000000",
"borderRadius": 0,
"boxShadow": false,
"boxShadowBlur": 0,
"boxShadowOffset": [0,0],
"boxShadowSpread": 0,
"boxShadowColor": "#000000",
"outlineWidth": 0,
"outlineStyle": "none", // same enum as borderStyle
"outlineColor": "#000000",
"outlineOffset": 0,
"filterBlur": 0,
"filterBrightness": 1,
"filterContrast": 1,
"filterGrayscale": 0,
"filterSepia": 0,
"filterInvert": 0,
"filterHueRotate": 0,
"filterSaturate": 1,
"blendMode": "normal", // enum: see definition
"perspective": 2000
}
Settings:
{
"name": "string",
"enabled": true,
"locked": false,
"startTime": 0,
"endTime": false,
"speed": 1
}
TextualLayer
This layer cannot be added directly. Inherits VisualLayer.
Properties:
{
"fontSize": 1.0,
"fontFamily": "Noto Sans",
"fontWeight": 600,
"fontStyle": "normal", // enum: "normal","italic"
"fontStretch": 100, // units: "%"
"color": "#FFFFFF",
"textAlign": "center", // enum: "left","right","center","justify"
"verticalAlign": "middle", // enum: "top","middle","bottom"
"padding": 0,
"textStroke": false,
"textStrokeWidth": 0,
"textStrokeColor": "#000000",
"textShadow": false,
"textShadowColor": "#000000",
"textShadowOffset": [0,0],
"textShadowBlur": 0,
"letterSpacing": "0em",
"lineHeight": 1,
"textTransform": "none", // enum: "none","capitalize","uppercase","lowercase"
"textDecoration": "none", // enum: "none","underline","overline","line-through"
"wordSpacing": 0,
"textIndent": 0,
"direction": "ltr" // enum: "ltr","rtl"
}
Settings:
{
"name": "string",
"enabled": true,
"locked": false,
"startTime": 0,
"endTime": false,
"speed": 1
}
MediaLayer
This layer cannot be added directly. Inherits VisualLayer.
Properties:
{
"fit": "contain" // enum: "contain","cover"
}
Settings (two implementations):
// Static source
{
"source": "string",
}
// Dynamic AI generation
{
"prompt": "string",
"model": "unsplash | openai | google | falai | string",
"modelSettings": {},
"cache": true
}
AuditoryLayer
This layer cannot be added directly. Inherits BaseLayer.
Properties:
{
"volume": 1,
"pan": 0,
"pitch": 1,
"mute": false
}
Settings:
{
"name": "string",
"enabled": true,
"locked": false,
"startTime": 0,
"endTime": false,
"speed": 1
}