Add a watermark to a video
A video without a mark on it is a video anyone can re-upload and claim. This endpoint burns a logo into every frame of a clip, consistently, so ownership travels with the file no matter where it ends up.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The moment a clip leaves your control
Once a video is downloaded, it can be re-uploaded, re-shared, and stripped of any context that ever pointed back to where it came from — a caption, a channel name, a description field are all easy to delete. A watermark burned directly into the pixels is a different kind of mark: removing it means editing the video itself, not just deleting a line of text next to it. video.watermark exists for exactly that scenario, where the file is going to travel further than you can track.
How the overlay is applied
POST /video/watermark with the source video and the logo image to overlay, and the response returns immediately as a task_id while the watermarking runs in the background. Once complete, the marked video arrives through a signed webhook call or waits at a signed link valid for 24 hours, depending on how your system checks for finished work.
Why it has to touch every frame
A watermark applied to a single frame or a static overlay layer would vanish the instant someone re-encodes or crops the video, so a real watermark gets composited into every single frame during the encode, becoming part of the video data itself rather than a layer sitting on top of it. This is the same logic broadcasters have used for decades with on-screen channel bugs — a small, persistent, semi-transparent mark in a corner that survives recording, re-encoding and even a moderate crop. The tradeoff is deliberate: visible enough to identify the source, subtle enough not to compete with the content.
Where watermarking fits in a release process
Watermarking is usually one of the last steps before a video goes out the door — after trimming, after resizing, once the file is in its final shape and won't be re-cut. Because pricing is a flat per-request fee plus a per-minute rate on the source, applying it once at the end of a chain, rather than to every intermediate version, keeps a batch release process both cheaper and simpler to reason about, since only the shipped output ever needs a mark on it.
What you can do with it
Preview clips before licensing
A stock footage marketplace watermarks preview versions of its clips so buyers can evaluate quality before purchasing the unmarked original.
Branded distribution across partners
A media company watermarks every clip it syndicates to partner sites, so its logo travels with the content wherever it's re-embedded.
User-generated content protection
A creator platform watermarks exported videos with the creator's handle to discourage uncredited re-uploads on other platforms.
Internal review copies
A production studio watermarks rough cuts shared with external reviewers to make leaked copies traceable back to their source.
FAQ
How do I add a watermark to a video with the API?
POST the source video and the logo image to /video/watermark, keep the returned task_id, and retrieve the watermarked file by webhook or a signed link valid for 24 hours.
Is the video watermark API free?
No, there is no free tier or trial; it costs $0.077 per request plus $0.0045 per minute of video, and a failed watermarking job is never charged.
Can I control where the logo appears on the video?
You supply the logo image to overlay, and the endpoint applies it consistently across the full clip for every frame of the source video.
Does watermarking reduce video quality?
The overlay itself is a small composited addition; any quality change comes from the encode step, which the endpoint handles to keep the rest of the frame intact.
Can a watermark be removed by cropping the video?
Since the mark is composited into every frame during the encode rather than added as a separate layer, a simple crop or re-encode doesn't strip it out on its own.
Is this endpoint live yet?
It's in deployment now, so check the endpoint status before sending production traffic since it isn't accepting jobs at this moment.
Can I watermark many videos in bulk?
Yes, submit one async task per video and collect each watermarked file by webhook as it finishes, which suits batch release pipelines.
Is my video stored after watermarking?
No, the source and watermarked files are deleted after the retention window and are never used for training.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/video/watermark \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"audio":"https://ejemplo.com/audio.mp3"}'const res = await fetch("https://api.kit.forhosting.com/video/watermark", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"audio": "https://ejemplo.com/audio.mp3"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/video/watermark",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"audio": "https://ejemplo.com/audio.mp3"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/video/watermark", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"audio":"https://ejemplo.com/audio.mp3"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"audio":"https://ejemplo.com/audio.mp3"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/video/watermark", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"audio": "https://ejemplo.com/audio.mp3"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "video.watermark",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 500 |
max_minutes | 60 |
max_megapixels | 3.9 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |