Edit Video
This page explains how to use the Klap API to apply AI-powered edits to a video. You can add dynamic captions, reframe the content, add emojis and more, without extracting multiple clips.
Overview
Klap’s AI can enhance existing short videos by adding captions, reframing the content, and applying other visual improvements. This is ideal when you already have a well-cut video that just needs enhancements.
API Flow
1. Submit a Video for Editing
First, submit your video to be edited.
Endpoint Used: POST /tasks/video-to-video
const task = await postRequest("/tasks/video-to-video", {
source_video_url: "https://example.com/video.mp4",
language: "en",
editing_options: {
captions: true,
reframe: true,
emojis: true,
intro_title: false
},
dimensions: {
width: 1080,
height: 1920
}
});
console.log(`Task created: ${task.id}`);
This returns a Task object with the ID of your processing job. Your video will be analyzed and the specified edits will be applied.
2. Poll the Task Status
You’ll need to periodically check the status of your processing task until it completes.
Endpoint Used: GET /tasks/{task_id}
// Poll every 30 seconds until the task is complete
let currentTask;
do {
currentTask = await getRequest(`/tasks/${task.id}`);
console.log(`Task status: ${currentTask.status}`);
if (currentTask.status === "processing") {
await new Promise(resolve => setTimeout(resolve, 30000));
}
} while (currentTask.status === "processing");
if (currentTask.status === "error") {
throw new Error("Task processing failed");
}
// Once complete, get the project ID of the edited video
const projectID = currentTask.output_id;
When the task is complete and successful, it will give you an output_id
representing the project ID of your edited video.
3. Preview the Edited Video (Optional)
You can preview the edited video before exporting it.
const previewUrl = `https://klap.app/player/${projectID}`;
This URL can be used to preview the edited video or embed it in your application.
4. Export the Edited Video
When you’re ready to export the final video, create an export task.
Endpoint Used: POST /projects/{project_id}/exports
const exportTask = await postRequest(
`/projects/${projectID}/exports`,
{
watermark: {
src_url: "https://example.com/logo.png",
pos_x: 0.5,
pos_y: 0.5,
scale: 1
}
}
);
console.log(`Export started: ${exportTask.id}`);
This returns an Export object with details about your export job.
5. Poll the Export Status
Like with the initial processing, you need to poll until the export is complete.
Endpoint Used: GET /projects/{project_id}/exports/{export_id}
// Poll until export is complete
let currentExport;
do {
currentExport = await getRequest(
`/projects/${projectID}/exports/${exportTask.id}`
);
console.log(`Export status: ${currentExport.status}`);
if (currentExport.status === "processing") {
await new Promise(resolve => setTimeout(resolve, 15000));
}
} while (currentExport.status === "processing");
if (currentExport.status === "error") {
throw new Error("Export failed");
}
6. Access the Exported Video
When the export is complete, you’ll have a URL to the final video.
const videoUrl = currentExport.src_url;
console.log(`Export complete: ${videoUrl}`);
Complete Example
Here’s a full example of the process:
const API_URL = "https://api.klap.video/v2";
const API_KEY = "<your-api-key>";
const INPUT_VIDEO_URL = "<your-video-url>";
const postRequest = async (url, body = {}) => {
const response = await fetch(`${API_URL}${url}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
},
body: JSON.stringify(body),
});
return response.ok ? response.json() : Promise.reject(await response.json());
};
const getRequest = async (url) => {
const response = await fetch(`${API_URL}${url}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
return response.json();
};
const pollStatus = async (url, checkKey, checkValue) => {
let resJson;
do {
resJson = await getRequest(url);
console.log(
`[${new Date().toLocaleTimeString()}] Polling ${url} while ${checkKey} === ${checkValue}...`
);
await new Promise((r) => setTimeout(r, 30000));
} while (resJson[checkKey] === checkValue);
return resJson;
};
const editVideo = async (inputVideoUrl) => {
// Step 1: Create the editing task
let task = await postRequest("/tasks/video-to-video", {
source_video_url: inputVideoUrl,
language: "en",
editing_options: {
captions: true,
reframe: true,
emojis: true,
intro_title: false
},
dimensions: {
width: 1080,
height: 1920
}
});
console.log(`Task created: ${task.id}. Processing...`);
// Step 2: Poll the task until it's complete
task = await pollStatus(`/tasks/${task.id}`, "status", "processing");
console.log(`Task processing done: ${task.id}.`);
if (task.status === "error") {
throw new Error("Task processing failed");
}
const projectId = task.output_id;
console.log(`Edited video project ID: ${projectId}`);
// Step 3: Export the video
console.log(`Exporting project: ${projectId}...`);
let exportRes = await postRequest(
`/projects/${projectId}/exports`,
{
watermark: {
src_url: "https://example.com/logo.png",
pos_x: 0.5,
pos_y: 0.5,
scale: 1
}
}
);
console.log(`Export started: ${exportRes.id}.`);
// Step 4: Poll the export until it's complete
exportRes = await pollStatus(
`/projects/${projectId}/exports/${exportRes.id}`,
"status",
"processing"
);
if (exportRes.status === "error") {
throw new Error("Export failed");
}
return exportRes;
};
const main = async () => {
try {
const exportResult = await editVideo(INPUT_VIDEO_URL);
console.log(`Export done: ${exportResult.src_url}`);
} catch (error) {
console.error("Error:", error.message);
}
};
main();