API Documentation
Getting Started
Installation
Install the Scrptly package from npm:
npm install scrptly
# or using yarn
yarn add scrptly
Authentication
Before you can interact with the Scrptly API, you need to configure your API key. Call Scrptly.setApiSettings()
once at the top of your script:
import Scrptly from 'scrptly';
Scrptly.setApiSettings({
apiKey: 'YOUR_API_KEY_HERE', // ← Replace with your real key
});
You can get your API key from the Scrptly account page after signing up.
Make sure you guard your API key (e.g. via environment variables) and rotate it if it ever gets exposed.
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 importingScrptly
and 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 aprompt
andmodel
instead 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=true
or 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
}