Add a watermark
A logo dragged onto a photo one file at a time is fine for a single post, but a content operation publishing hundreds of images a day needs that mark applied the same way, in the same place, every single time. This endpoint stamps a watermark onto any supported image through one call, turning brand protection into an automated step instead of a recurring design chore.
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.
Why watermarking is still a real need
Stock photo libraries, course platforms, photographers protecting preview galleries, and news outlets crediting original imagery all rely on watermarking to make unauthorized reuse obvious and to keep attribution visible even after an image is copied off the original site. It's not a decorative flourish, it's a lightweight, persistent claim of origin that travels with the file wherever it ends up.
What the endpoint actually does
It takes a base image and a watermark, typically a logo or text mark, and composites the mark onto the image at the position and opacity you specify, so the same brand element lands consistently whether the source photo is a tall portrait or a wide landscape. Because the placement logic is applied programmatically rather than eyeballed each time, a batch of a thousand images comes out with the mark in exactly the same relative position on every one.
Sending the request
Call POST /image/watermark with the source image and the watermark asset, and you'll get a task_id back immediately since watermarking runs asynchronously like every job on the platform. The finished, branded image is delivered through a signed webhook, the practical choice for a publishing pipeline, or a signed link that stays valid for 24 hours for manual pickup.
A practice older than digital images
Watermarking takes its name from the actual technique of pressing a faint design into paper during manufacturing, used for centuries on currency and official documents to prove authenticity before anyone had heard of a JPEG. Digital watermarking inherited both the name and the purpose, a mark that proves origin and discourages misuse, just applied to pixels instead of paper fiber.
Built for continuous publishing
A watermark job that fails is never billed; three automatic retries run before you ever see a clear error message, so a temporary hiccup never turns into a charge for nothing. There's no free tier and no trial gate to get past, prepaid balance runs the job right away, and a 402 response is the plain, honest signal when access isn't active, which keeps the endpoint fast and predictable for anyone running a real publishing pipeline.
What you can do with it
Stock photo protection
A stock photography site watermarks every preview image before it's publicly browsable, keeping full-resolution files reserved for paying customers.
Course and tutorial platforms
An online education platform stamps its logo onto instructor-submitted screenshots and diagrams automatically before they're published in a lesson.
News and editorial attribution
A newsroom watermarks original photography with a credit mark before syndicating images to partner outlets.
Social content branding
A creator tool applies a consistent logo watermark to every exported video thumbnail and social graphic to reinforce brand recognition.
FAQ
How does the image watermark API work?
You send a source image and a watermark asset to POST /image/watermark, specifying position and opacity, and the branded image is returned asynchronously via webhook or a 24-hour signed link.
Is there a free tier for the watermark API?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How much does watermarking an image cost?
Each call costs $0.002 per request plus $0.005 per image, and billing only happens when the watermark is applied successfully.
Can I control where the watermark is placed?
Yes, you specify the position and opacity of the mark, so it can sit in a corner, centered, or wherever your brand guidelines require.
What happens if a watermark request fails?
You're never charged. The system retries automatically up to three times before returning a clear error.
Can I watermark a large batch of images at once?
Yes, submit each image as its own asynchronous call and they process independently, so you can fan out a full catalog without waiting on one job to finish before starting the next.
What kind of watermark can I use, logo or text?
You can composite an image-based mark such as a logo; check the current endpoint reference for the exact accepted watermark asset formats.
How do I download the watermarked result?
Through a signed webhook, recommended for automated pipelines, or a signed link valid for 24 hours, after which the file is deleted and 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/image/watermark \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/imagen.jpg"}'const res = await fetch("https://api.kit.forhosting.com/image/watermark", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/imagen.jpg"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/watermark",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/imagen.jpg"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/watermark", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/imagen.jpg"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/imagen.jpg"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/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
{
"image": "https://ejemplo.com/imagen.jpg"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.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 | 15 |
max_megapixels | 12 |
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. |