xAI
Create an xAI video edit
Use POST /grok/v1/videos/edits to edit a source video with a text prompt, preserve motion, and get a request_id for async polling results.
POST
/
grok
/
v1
/
videos
/
edits
cURL
curl https://api.cometapi.com/grok/v1/videos/edits \
-H "Authorization: Bearer $COMETAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-video",
"prompt": "Add snow to the scene.",
"video": {"url": "https://your-video-host/source.mp4"}
}'import os
import requests
response = requests.post(
"https://api.cometapi.com/grok/v1/videos/edits",
headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
json={
"model": "grok-imagine-video",
"prompt": "Add snow to the scene.",
"video": {"url": "https://your-video-host/source.mp4"},
},
)
task = response.json()
print(task["request_id"]) # poll GET /grok/v1/videos/{request_id}
const response = await fetch("https://api.cometapi.com/grok/v1/videos/edits", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.COMETAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "grok-imagine-video",
prompt: "Add snow to the scene.",
video: { url: "https://your-video-host/source.mp4" },
}),
});
const task = await response.json();
console.log(task.request_id); // poll GET /grok/v1/videos/{request_id}
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cometapi.com/grok/v1/videos/edits",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => 'Add snow to the scene.',
'video' => [
'url' => 'https://example.com/source.mp4'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cometapi.com/grok/v1/videos/edits"
payload := strings.NewReader("{\n \"prompt\": \"Add snow to the scene.\",\n \"video\": {\n \"url\": \"https://example.com/source.mp4\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cometapi.com/grok/v1/videos/edits")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"Add snow to the scene.\",\n \"video\": {\n \"url\": \"https://example.com/source.mp4\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cometapi.com/grok/v1/videos/edits")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"Add snow to the scene.\",\n \"video\": {\n \"url\": \"https://example.com/source.mp4\"\n }\n}"
response = http.request(request)
puts response.read_body{
"request_id": "<request_id>"
}Use this endpoint to edit an existing MP4 with a text instruction. The output stays closer to the source clip’s timing and composition than a fresh generation request.
Before you send the request
- Provide a reachable
video.url - Keep the source clip short; xAI’s own guidance caps edits at about 8.7 seconds
- Use a focused instruction that describes one clear change
- Save the returned
request_id, because edits use the same polling flow as generation
Editing flow
1
Submit the edit request
Send the source video URL, edit prompt, and
model: grok-imagine-video.2
Poll for the final result
Call Get xAI video results until the job is finished.
3
Store the edited asset
Download the finished output or move the returned URL into your own storage pipeline.
What changes on CometAPI
xAI documents video editing as the same async lifecycle as generation, just with a source video instead of an optional source image. CometAPI keeps that behavior and the same polling endpoint, so your edit workflow is still start -> poll -> download.Body
application/json
Last modified on June 23, 2026
⌘I
cURL
curl https://api.cometapi.com/grok/v1/videos/edits \
-H "Authorization: Bearer $COMETAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-video",
"prompt": "Add snow to the scene.",
"video": {"url": "https://your-video-host/source.mp4"}
}'import os
import requests
response = requests.post(
"https://api.cometapi.com/grok/v1/videos/edits",
headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
json={
"model": "grok-imagine-video",
"prompt": "Add snow to the scene.",
"video": {"url": "https://your-video-host/source.mp4"},
},
)
task = response.json()
print(task["request_id"]) # poll GET /grok/v1/videos/{request_id}
const response = await fetch("https://api.cometapi.com/grok/v1/videos/edits", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.COMETAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "grok-imagine-video",
prompt: "Add snow to the scene.",
video: { url: "https://your-video-host/source.mp4" },
}),
});
const task = await response.json();
console.log(task.request_id); // poll GET /grok/v1/videos/{request_id}
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cometapi.com/grok/v1/videos/edits",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => 'Add snow to the scene.',
'video' => [
'url' => 'https://example.com/source.mp4'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cometapi.com/grok/v1/videos/edits"
payload := strings.NewReader("{\n \"prompt\": \"Add snow to the scene.\",\n \"video\": {\n \"url\": \"https://example.com/source.mp4\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cometapi.com/grok/v1/videos/edits")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"Add snow to the scene.\",\n \"video\": {\n \"url\": \"https://example.com/source.mp4\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cometapi.com/grok/v1/videos/edits")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"Add snow to the scene.\",\n \"video\": {\n \"url\": \"https://example.com/source.mp4\"\n }\n}"
response = http.request(request)
puts response.read_body{
"request_id": "<request_id>"
}