curl --request POST \
--url https://api.goenhance.ai/api/v1/videos/generations \
--header 'Content-Type: application/json' \
--data '
{
"model": "video-watermark-remover",
"video_url": "https://your-cdn.com/clip.mp4",
"detection_prompt": "Sora logo"
}
'import requests
url = "https://api.goenhance.ai/api/v1/videos/generations"
payload = {
"model": "video-watermark-remover",
"video_url": "https://your-cdn.com/clip.mp4",
"detection_prompt": "Sora logo"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'video-watermark-remover',
video_url: 'https://your-cdn.com/clip.mp4',
detection_prompt: 'Sora logo'
})
};
fetch('https://api.goenhance.ai/api/v1/videos/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.goenhance.ai/api/v1/videos/generations",
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([
'model' => 'video-watermark-remover',
'video_url' => 'https://your-cdn.com/clip.mp4',
'detection_prompt' => 'Sora logo'
]),
CURLOPT_HTTPHEADER => [
"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.goenhance.ai/api/v1/videos/generations"
payload := strings.NewReader("{\n \"model\": \"video-watermark-remover\",\n \"video_url\": \"https://your-cdn.com/clip.mp4\",\n \"detection_prompt\": \"Sora logo\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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.goenhance.ai/api/v1/videos/generations")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"video-watermark-remover\",\n \"video_url\": \"https://your-cdn.com/clip.mp4\",\n \"detection_prompt\": \"Sora logo\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.goenhance.ai/api/v1/videos/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"video-watermark-remover\",\n \"video_url\": \"https://your-cdn.com/clip.mp4\",\n \"detection_prompt\": \"Sora logo\"\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"msg": "Success",
"data": {
"img_uuid": "c12b656c-747a-44fd-9c80-add79b0c52d5",
"cost": 11
}
}Video Watermark Remover
Remove watermarks and logos from an existing video, including marks that move around the frame such as the Sora logo. Watermark regions are detected on every frame and filled in with matching background. The resolution and the original audio track are kept, and the result is an MP4.
Pricing — per second of the source video (USD at $0.02/token):
| tokens/s | USD/s |
|---|---|
| 1 | $0.02 |
⚠️ There is no duration parameter. The source video is measured server-side and the whole clip is processed; the measured length, rounded up to whole seconds, is what you are charged for. For example, a 10.2-second clip is billed as 11 seconds:
- 11 tokens
- = $0.22
Limits — requests outside these are rejected before any tokens are deducted:
| limit | |
|---|---|
video_url | https:// only, up to 100MB, av1 is not supported |
| Length | 1-60s |
| Resolution | up to 1080p (shorter side at most 1080 pixels) |
Output: same resolution as the source, original audio preserved. The frame rate is capped at 30fps: a faster source keeps an even subset of its frames (60fps becomes 30fps, 50fps becomes 25fps), so the duration and the audio stay in sync. Slower sources keep their own frame rate.
Processing time: slower than real time — expect roughly 3 minutes for a 10-second 30fps clip. Use custom_callback_url rather than tight polling for longer clips.
detection_prompt and max_bbox_percent work the same way as in the image Watermark Remover: name the mark (for example Sora logo) when the default watermark misses it, and keep max_bbox_percent low so a false positive cannot erase a large part of the frame.
Returns an img_uuid; poll GET /api/v1/jobs/detail (or use custom_callback_url) to get the result.
curl --request POST \
--url https://api.goenhance.ai/api/v1/videos/generations \
--header 'Content-Type: application/json' \
--data '
{
"model": "video-watermark-remover",
"video_url": "https://your-cdn.com/clip.mp4",
"detection_prompt": "Sora logo"
}
'import requests
url = "https://api.goenhance.ai/api/v1/videos/generations"
payload = {
"model": "video-watermark-remover",
"video_url": "https://your-cdn.com/clip.mp4",
"detection_prompt": "Sora logo"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'video-watermark-remover',
video_url: 'https://your-cdn.com/clip.mp4',
detection_prompt: 'Sora logo'
})
};
fetch('https://api.goenhance.ai/api/v1/videos/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.goenhance.ai/api/v1/videos/generations",
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([
'model' => 'video-watermark-remover',
'video_url' => 'https://your-cdn.com/clip.mp4',
'detection_prompt' => 'Sora logo'
]),
CURLOPT_HTTPHEADER => [
"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.goenhance.ai/api/v1/videos/generations"
payload := strings.NewReader("{\n \"model\": \"video-watermark-remover\",\n \"video_url\": \"https://your-cdn.com/clip.mp4\",\n \"detection_prompt\": \"Sora logo\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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.goenhance.ai/api/v1/videos/generations")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"video-watermark-remover\",\n \"video_url\": \"https://your-cdn.com/clip.mp4\",\n \"detection_prompt\": \"Sora logo\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.goenhance.ai/api/v1/videos/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"video-watermark-remover\",\n \"video_url\": \"https://your-cdn.com/clip.mp4\",\n \"detection_prompt\": \"Sora logo\"\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"msg": "Success",
"data": {
"img_uuid": "c12b656c-747a-44fd-9c80-add79b0c52d5",
"cost": 11
}
}Headers
Body
Model name. Must be video-watermark-remover.
video-watermark-remover Source video URL. Must be an https:// link that is publicly reachable. Up to 100MB, 1-60s long, at most 1080p (shorter side 1080 pixels or less); av1 is not supported. The whole clip is processed and its measured duration is the billing basis.
What to detect and remove, in English. Defaults to watermark. Naming the mark (for example Sora logo) improves detection of small or low-contrast watermarks.
200Largest region to remove, as a percentage of the frame area. Detected regions above this size are treated as false positives and left untouched. Defaults to 10.
x <= 100Optional. A publicly accessible HTTPS URL. When the task status changes (processing / success / failed), GoEnhance sends a POST request to this URL. The request body is identical to the response of GET /api/v1/jobs/detail. If your server does not respond with HTTP 200, the notification is retried up to 3 times, with a 3-second timeout per attempt.
"https://your-server.com/goenhance/callback"
