When you want to automate this

One video per product, straight from your catalog.

1
See it
OutputMP4
Size1920 × 1080 (16:9)
Length18s
Frame rate25 fps
Tracks / clips79 / 113
Assets used1 audio, 19 image, 34 luma, 24 rich-text, 35 svg
Soundtrackno
Merge fields22
2
Make it yours

Send a merge array with your values for these fields:

FieldDefault value
{{ BRAND_NAME }}Luxury Time
{{ TITLE }}Product Highlights
{{ LOGO }}https://templates.shotstack.io/bold-promo-highlight-social-media-template/cef9f3c4-6fbb-4099-92ed-2dc9d1f7efaf/source.png
{{ Social_Media }}@luxurytime
{{ PROFILE_PIC }}https://templates.shotstack.io/bold-promo-highlight-social-media-template/1e9f2ef4-cd77-46be-9767-a002db8074f4/source.png
{{ S1_TITLE }}Water Resistance
{{ S1_DESCRIPTION }}Protects the watch from damage caused by water exposure, making it suitable for daily wear, swimming, or diving depending on its rating.
{{ WEBSITE }}www.luxurytime.com
{{ White_FONT_COLOR }}#ffffff
{{ Purple_BACKGROUND_COLOR }}#702bb6
{{ Pink_BACKGROUND_COLOR_2 }}#f2e5ff
{{ Black_FONT_COLOR_2 }}#000000
{{ S1_IMAGE_SRC }}https://templates.shotstack.io/bold-promo-highlight-social-media-template/27182608-cae1-4710-aad9-f93064d5b524/source.jpg
{{ S2_TITLE }}Durable Build
{{ S2_DESCRIPTION }}Built with high-quality materials to withstand daily wear and tear, shocks, and rough conditions — ensuring long-lasting performance whether you're at work, at the gym, or outdoors.
{{ S2_IMAGE_SRC }}https://templates.shotstack.io/bold-promo-highlight-social-media-template/3dff9faf-9b5a-499b-8c66-fd320ac48413/shotstack-proxy.webp
{{ S3_TITLE }}Luxurious Quality
{{ S3_DESCRIPTION }}Crafted with premium materials and refined detailing, offering a sophisticated look and feel that elevates your style — perfect for formal occasions, business settings, or everyday elegance.
{{ S3_IMAGE_SRC }}https://templates.shotstack.io/bold-promo-highlight-social-media-template/72863350-ecf5-4681-9f72-9016cfde7ab4/shotstack-proxy.webp
{{ DarkPurple_BACKGROUND_COLOR }}#471f70
{{ CTA }}Visit Our Store
{{ AUDIO_SRC }}https://templates.shotstack.io/bold-promo-highlight-social-media-template/8ea9c824-e6fe-4c28-82b0-b9fc5cb5e847/source.mp3
Edit and save to your account
3
Run it once

Save the JSON above as template.json, then render in the free sandbox:

# Save the JSON above as template.json, then:
curl -X POST https://api.shotstack.io/edit/stage/render \
  -H "x-api-key: $SHOTSTACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d @template.json

# Poll until status is "done", then download response.url
curl https://api.shotstack.io/edit/stage/render/RENDER_ID -H "x-api-key: $SHOTSTACK_API_KEY"
import { readFileSync } from 'node:fs';

const headers = { 'x-api-key': process.env.SHOTSTACK_API_KEY, 'Content-Type': 'application/json' };
const edit = JSON.parse(readFileSync('template.json', 'utf8'));

const { response } = await fetch('https://api.shotstack.io/edit/stage/render', {
  method: 'POST', headers, body: JSON.stringify(edit)
}).then((r) => r.json());

let render;
do {
  await new Promise((r) => setTimeout(r, 3000));
  render = (await fetch(`https://api.shotstack.io/edit/stage/render/${response.id}`, { headers }).then((r) => r.json())).response;
} while (!['done', 'failed'].includes(render.status));

console.log(render.status, render.url);
import json, os, time, requests

headers = {"x-api-key": os.environ["SHOTSTACK_API_KEY"]}
with open("template.json") as f:
    edit = json.load(f)

render_id = requests.post("https://api.shotstack.io/edit/stage/render", json=edit, headers=headers).json()["response"]["id"]

while True:
    render = requests.get(f"https://api.shotstack.io/edit/stage/render/{render_id}", headers=headers).json()["response"]
    if render["status"] in ("done", "failed"):
        break
    time.sleep(3)

print(render["status"], render.get("url"))
npm install -g @shotstack/cli
export SHOTSTACK_API_KEY=your_sandbox_key

shotstack validate template.json          # offline schema check, free
shotstack render template.json --env stage --watch

Sandbox renders are free and watermarked. Production: the v1 endpoint and key. SDKs

4
Automate it

Loop over your product feed and render a promo per SKU — prices and images always current.

Paste into Claude, ChatGPT or Cursor — your AI assistant builds the workflow around your data.

Node.js, one render per CSV row, wired to this template's 22 merge fields. Setup steps in the header.

Guides: Bulk-create from a CSV · Webhooks · Templates endpoint · Render your first video

AI assistants: Markdown () · · · CLI skill: SKILL.md () · MCP server

Common questions

How do I change the text and media without editing the JSON?

Use the 22 merge fields listed above. Send a merge array with your own values for each field and the API swaps them in at render time, so one template can produce thousands of unique videos.

Can I render this in full HD or 4K for YouTube?

Yes. This template renders 1920×1080 by default. Set output.resolution to "1080" or output.size to a larger 16:9 size in the JSON; the layout scales with it.

Can I use my own photos?

Yes. The template uses 19 images; replace each image asset's src with a public URL of your own file (JPG, PNG or WebP). Keep the timing and effects, or adjust them per clip.

How do I change the text and fonts?

Edit the text on each rich-text asset in the JSON. Fonts come from the timeline fonts list or the asset's font family; add your own font file URL to timeline.fonts to use a brand typeface.