CamScanner applies a full-page tiled text watermark to an image. The watermark text is repeated in a diagonal grid pattern across the entire image. The workflow is a 3-step pipeline: upload the image, apply watermark, then download the result.
Important: Privacy & Data Flow Notice
- Third-party service: This skill sends your files to CamScanner's official servers (
ai-tools.camscanner.com) for processing.- Data retention: CamScanner servers process your files in real-time. Files are not permanently stored on the server.
- Local files: Output files are saved to your local filesystem at the path you specify.
Base URL: https://ai-tools.camscanner.com
ParameterRequiredTypeDefaultDescriptionfile_idYesstring—Uploaded image file_idtextYesstring—Watermark text (max 200 chars)colorNostring#000000Hex color, e.g. #FF0000 for redopacityNonumber0.4Transparency 0-1 (0=invisible, 1=opaque)sizeNointeger36Font size 1-200
Do NOT pass mode, x, y, width, height, or rotation — these are fixed internally for tiled watermark layout.
bash
BASE="https://ai-tools.camscanner.com"
IN_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/upload_file/execute" \
-H "Content-Type: application/octet-stream" \
--data-binary "@/path/to/image.jpg" | jq -r '.tool_result.data.file_id')
Response:
json
{
"code": 200,
"tool": "upload_file",
"tool_result": {
"success": true,
"data": {
"file_id": "file_1741857600_ab12cd34ef56",
"size": 24576
}
}
}
Minimal call (recommended — uses sensible defaults):
bash
OUT_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/watermark_image/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"text\":\"Copyright 2026\",\"output_mode\":\"file_id\"}" \
| jq -r '.tool_result.data.file_id')
With custom styling (only add fields the user explicitly requests):
bash
OUT_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/watermark_image/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"text\":\"Confidential\",\"color\":\"#FF0000\",\"opacity\":0.5,\"size\":60,\"output_mode\":\"file_id\"}" \
| jq -r '.tool_result.data.file_id')
Response:
json
{
"code": 200,
"tool": "watermark_image",
"tool_result": {
"success": true,
"data": {
"file_id": "file_1741857701_9988aabbccdd.jpg",
"target_type": ""
},
"metadata": {
"engine": "imageprocess"
}
}
}
bash
curl -sS -X POST "$BASE/v1/tools/download_file/execute?response_mode=raw" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$OUT_FILE_ID\"}" \
-o /path/to/watermarked.jpg
Critical: The response_mode=raw query parameter is required to get the binary file. Without it, the response is JSON.
bash
BASE="https://ai-tools.camscanner.com"
INPUT_IMAGE="/path/to/image.jpg"
TEXT="Copyright 2026"
OUTPUT_FILE="/path/to/watermarked.jpg"
# Upload
IN_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/upload_file/execute" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$INPUT_IMAGE" | jq -r '.tool_result.data.file_id')
# Watermark
OUT_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/watermark_image/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"text\":\"$TEXT\",\"output_mode\":\"file_id\"}" \
| jq -r '.tool_result.data.file_id')
# Download
curl -sS -X POST "$BASE/v1/tools/download_file/execute?response_mode=raw" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$OUT_FILE_ID\"}" \
-o "$OUTPUT_FILE"
MistakeFixForgetting response_mode=raw on downloadAlways append ?response_mode=raw to the download URLMissing text parametertext is required — ask the user what text to usePassing internal params like mode, x, yNever pass these — they are fixed for tiled layoutColor without # prefixBoth FF0000 and #FF0000 work, but always use 6 hex digitsRGBA PNG input (4-channel with alpha)May cause 500 error from upstream — convert to JPEG first if this happensWrong Content-Type on uploadUpload uses application/octet-stream, not multipart/form-data
bash
# After upload
if [ -z "$IN_FILE_ID" ] || [ "$IN_FILE_ID" = "null" ]; then
echo "Upload failed"; exit 1
fi
# After watermark
if [ -z "$OUT_FILE_ID" ] || [ "$OUT_FILE_ID" = "null" ]; then
echo "Watermark failed"; exit 1
fi
sips -s format jpeg input.png --out input.jpg on macOS).