curl -X POST "https://api.submagic.co/v1/projects/magic-clips/upload" \
-H "x-api-key: sk-your-api-key-here" \
-F "file=@./video.mp4" \
-F "title=My Magic Clips Upload" \
-F "language=en" \
-F "templateName=Hormozi 2" \
-F "webhookUrl=https://yoursite.com/webhook/submagic" \
-F "minClipLength=15" \
-F "maxClipLength=60" \
-F "faceTracking=true"
const uploadMagicClips = async (file) => {
const formData = new FormData();
formData.append("file", file);
formData.append("title", "My Magic Clips Upload");
formData.append("language", "en");
formData.append("templateName", "Hormozi 2");
formData.append("webhookUrl", "https://yoursite.com/webhook/submagic");
formData.append("minClipLength", "15");
formData.append("maxClipLength", "60");
formData.append("faceTracking", "true");
const response = await fetch(
"https://api.submagic.co/v1/projects/magic-clips/upload",
{
method: "POST",
headers: {
"x-api-key": "sk-your-api-key-here",
},
body: formData,
}
);
const project = await response.json();
console.log("Magic Clips project created:", project.id);
return project;
};
// Usage with file input
const fileInput = document.getElementById("video-file");
fileInput.addEventListener("change", async (event) => {
const file = event.target.files[0];
if (file) {
await uploadMagicClips(file);
}
});
import requests
def upload_magic_clips(file_path):
url = 'https://api.submagic.co/v1/projects/magic-clips/upload'
headers = {
'x-api-key': 'sk-your-api-key-here'
}
with open(file_path, 'rb') as video_file:
files = {
'file': video_file
}
data = {
'title': 'My Magic Clips Upload',
'language': 'en',
'templateName': 'Hormozi 2',
'webhookUrl': 'https://yoursite.com/webhook/submagic',
'minClipLength': '15',
'maxClipLength': '60',
'faceTracking': 'true'
}
response = requests.post(url, headers=headers, files=files, data=data)
project = response.json()
print(f"Magic Clips project created: {project['id']}")
return project
# Usage
project = upload_magic_clips('./video.mp4')
{
"id": "e568c322-7fa5-497a-8fb0-3ba32e9e67d2",
"title": "My Magic Clips Upload",
"language": "en",
"status": "processing",
"webhookUrl": "https://yoursite.com/webhook/submagic",
"templateName": "Hormozi 2",
"userThemeId": null,
"createdAt": "2025-09-24T12:55:56.989Z"
}
API Reference
Upload Magic Clips
Generate short-form video clips by uploading a video file
POST
/
v1
/
projects
/
magic-clips
/
upload
curl -X POST "https://api.submagic.co/v1/projects/magic-clips/upload" \
-H "x-api-key: sk-your-api-key-here" \
-F "file=@./video.mp4" \
-F "title=My Magic Clips Upload" \
-F "language=en" \
-F "templateName=Hormozi 2" \
-F "webhookUrl=https://yoursite.com/webhook/submagic" \
-F "minClipLength=15" \
-F "maxClipLength=60" \
-F "faceTracking=true"
const uploadMagicClips = async (file) => {
const formData = new FormData();
formData.append("file", file);
formData.append("title", "My Magic Clips Upload");
formData.append("language", "en");
formData.append("templateName", "Hormozi 2");
formData.append("webhookUrl", "https://yoursite.com/webhook/submagic");
formData.append("minClipLength", "15");
formData.append("maxClipLength", "60");
formData.append("faceTracking", "true");
const response = await fetch(
"https://api.submagic.co/v1/projects/magic-clips/upload",
{
method: "POST",
headers: {
"x-api-key": "sk-your-api-key-here",
},
body: formData,
}
);
const project = await response.json();
console.log("Magic Clips project created:", project.id);
return project;
};
// Usage with file input
const fileInput = document.getElementById("video-file");
fileInput.addEventListener("change", async (event) => {
const file = event.target.files[0];
if (file) {
await uploadMagicClips(file);
}
});
import requests
def upload_magic_clips(file_path):
url = 'https://api.submagic.co/v1/projects/magic-clips/upload'
headers = {
'x-api-key': 'sk-your-api-key-here'
}
with open(file_path, 'rb') as video_file:
files = {
'file': video_file
}
data = {
'title': 'My Magic Clips Upload',
'language': 'en',
'templateName': 'Hormozi 2',
'webhookUrl': 'https://yoursite.com/webhook/submagic',
'minClipLength': '15',
'maxClipLength': '60',
'faceTracking': 'true'
}
response = requests.post(url, headers=headers, files=files, data=data)
project = response.json()
print(f"Magic Clips project created: {project['id']}")
return project
# Usage
project = upload_magic_clips('./video.mp4')
{
"id": "e568c322-7fa5-497a-8fb0-3ba32e9e67d2",
"title": "My Magic Clips Upload",
"language": "en",
"status": "processing",
"webhookUrl": "https://yoursite.com/webhook/submagic",
"templateName": "Hormozi 2",
"userThemeId": null,
"createdAt": "2025-09-24T12:55:56.989Z"
}
Upload Magic Clips
Generate multiple engaging short-form video clips by uploading a video file directly to Submagic. This endpoint accepts multipart/form-data uploads and creates clips with automatic captions, animations, and effects optimized for social media platforms.This endpoint requires authentication, Magic Clips subscription, and has a
rate limit of 500 requests per hour.
Magic Clips created via API use your regular Magic Clips credits, not API
credits. 1 credit per project.
Authentication
string
required
Your Submagic API key starting with
sk-Request Body (multipart/form-data)
file
required
Video file to upload. Must be in a supported format.
string
required
A descriptive title for your Magic Clips project (1-100 characters)
string
required
Language code for captions (e.g., “en”, “es”, “fr”). Use the languages
endpoint to get available options.
string
URL to receive webhook notifications when processing is complete. Must be a
valid HTTPS URL.
string
Template to apply for styling (max 50 characters). Use the templates
endpoint to get available options. Defaults to
“Sara” if not specified. Cannot be used together with
userThemeId.string
ID of a custom user theme to apply for styling. Must be a valid UUID of a
theme that belongs to you or your team. Cannot be used together with
templateName.number
Minimum clip duration in seconds (15-300 seconds). Defaults to 15 seconds.
number
Maximum clip duration in seconds (15-300 seconds). Defaults to 60 seconds.
boolean
Enable face tracking for the generated clips. If not specified, defaults to
true.Supported Formats & Limits
Supported Formats
- MP4 (.mp4) - MOV (.mov)
File Limits
- Max size: 10GB - Max duration: 120 minutes
Response
string
Unique identifier for the created Magic Clips project (UUID format)
string
The title you provided for the project
string
Language code used for captions
string
Current processing status:
processingstring
Webhook URL if provided in the request
string
Template name applied to the project
string
User theme ID applied to the project
string
ISO 8601 timestamp when the project was created
curl -X POST "https://api.submagic.co/v1/projects/magic-clips/upload" \
-H "x-api-key: sk-your-api-key-here" \
-F "file=@./video.mp4" \
-F "title=My Magic Clips Upload" \
-F "language=en" \
-F "templateName=Hormozi 2" \
-F "webhookUrl=https://yoursite.com/webhook/submagic" \
-F "minClipLength=15" \
-F "maxClipLength=60" \
-F "faceTracking=true"
const uploadMagicClips = async (file) => {
const formData = new FormData();
formData.append("file", file);
formData.append("title", "My Magic Clips Upload");
formData.append("language", "en");
formData.append("templateName", "Hormozi 2");
formData.append("webhookUrl", "https://yoursite.com/webhook/submagic");
formData.append("minClipLength", "15");
formData.append("maxClipLength", "60");
formData.append("faceTracking", "true");
const response = await fetch(
"https://api.submagic.co/v1/projects/magic-clips/upload",
{
method: "POST",
headers: {
"x-api-key": "sk-your-api-key-here",
},
body: formData,
}
);
const project = await response.json();
console.log("Magic Clips project created:", project.id);
return project;
};
// Usage with file input
const fileInput = document.getElementById("video-file");
fileInput.addEventListener("change", async (event) => {
const file = event.target.files[0];
if (file) {
await uploadMagicClips(file);
}
});
import requests
def upload_magic_clips(file_path):
url = 'https://api.submagic.co/v1/projects/magic-clips/upload'
headers = {
'x-api-key': 'sk-your-api-key-here'
}
with open(file_path, 'rb') as video_file:
files = {
'file': video_file
}
data = {
'title': 'My Magic Clips Upload',
'language': 'en',
'templateName': 'Hormozi 2',
'webhookUrl': 'https://yoursite.com/webhook/submagic',
'minClipLength': '15',
'maxClipLength': '60',
'faceTracking': 'true'
}
response = requests.post(url, headers=headers, files=files, data=data)
project = response.json()
print(f"Magic Clips project created: {project['id']}")
return project
# Usage
project = upload_magic_clips('./video.mp4')
{
"id": "e568c322-7fa5-497a-8fb0-3ba32e9e67d2",
"title": "My Magic Clips Upload",
"language": "en",
"status": "processing",
"webhookUrl": "https://yoursite.com/webhook/submagic",
"templateName": "Hormozi 2",
"userThemeId": null,
"createdAt": "2025-09-24T12:55:56.989Z"
}
Webhook Integration
When processing is complete, a webhook notification will be sent to the providedwebhookUrl (if specified). The webhook payload includes information about the main project and all generated clips.
Webhook Payload Structure
{
"projectId": "e568c322-7fa5-497a-8fb0-3ba32e9e67d2",
"status": "completed",
"title": "My Magic Clips Upload",
"duration": 283,
"completedAt": "2025-09-24T12:59:24.880Z",
"magicClips": [
{
"id": "364fe092-b68d-468a-9558-bfca7c4d190e",
"title": "ProMotion Display Breakthrough",
"duration": 21.04,
"viralityScores": {
"total": 89,
"shareability": 23,
"hook_strength": 22,
"story_quality": 21,
"emotional_impact": 23
},
"status": "completed",
"previewUrl": "https://app.submagic.co/view/364fe092-b68d-468a-9558-bfca7c4d190g",
"downloadUrl": "https://app.submagic.co/api/file/download?path=3c6cd7cd-3f5e-4def-b662-69c48a7fc8ce/e568c322-7fa5-497a-8fb0-3ba32e9e67d2/364fe092-b68d-468a-9558-bfca7c4d130e-download.mp4&newFileName=ProMotion%20Display%20Breakthrough.mp4",
"directUrl": "https://dqu1p08d61fh.cloudfront.net/api/9cc52d00-43d7-442f-9a22-050312bkm24f/1ddee5b4-101f-4c1e-a74a-b6b3bcfe206c/video.mp4-download.mp4"
}
]
}
Webhook Response Fields
string
Main project identifier
string
Processing status:
completed or failedstring
Project title
number
Total duration of the original video in seconds
string
ISO 8601 timestamp when processing completed
array
Array of generated clips, each containing: -
id: Unique clip identifier -
title: AI-generated clip title - duration: Clip duration in seconds -
viralityScores: Object containing virality metrics with total, shareability, hook_strength, story_quality, and emotional_impact scores -
status: Clip processing status - previewUrl: URL to preview the clip -
downloadUrl: Direct download URL for the clip - directUrl: Direct URL that
can be embedded on your website or used to play the clip directlyError Responses
object
{
"error": "VALIDATION_ERROR",
"message": "Content-Type must be multipart/form-data"
}
object
{
"error": "VALIDATION_ERROR",
"message": "Invalid request parameters"
}
object
{
"error": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
object
{
"error": "FORBIDDEN",
"message": "Magic Clips subscription required. Please upgrade your plan or purchase Magic Clips credits."
}
object
{
"error": "PAYLOAD_TOO_LARGE",
"message": "File size exceeds maximum allowed size"
}
object
{
"error": "UNSUPPORTED_MEDIA_TYPE",
"message": "Video format not supported"
}
object
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"retryAfter": 60
}
object
{
"error": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred",
"details": {}
}

