CamScanner provides a high-precision document enhancement engine that removes watermarks from PDF documents while preserving the underlying text, images, and original layout. It intelligently detects overlaid watermarks, stamps, and translucent logos across every page and erases them, leaving the document clean and legible. The workflow is a 3-step pipeline: upload the PDF, remove watermark via remove_watermark_pdf, then download the result. For convenience, the remove-watermark step also supports a raw output mode that returns the processed PDF bytes directly, skipping the download step.
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
source_typeOperationEndpointOutputpdfRemove watermark (PDF)remove_watermark_pdf.pdf
FieldRequiredDefaultNotesfile_idyes—The file_id returned by upload_file for the source PDFdpino144Rendering DPI; 144 is the recommended defaulttimeout_secno—Processing timeout in seconds; use 180 for long PDFsoutput_modeyes—"file_id" (then download separately) or "raw" (stream PDF bytes)
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/document.pdf" | jq -r '.tool_result.data.file_id')
Response:
json
{
"code": 200,
"tool": "upload_file",
"tool_result": {
"success": true,
"data": {
"file_id": "file_1741857600_ab12cd34ef56.pdf",
"size": 524288
}
}
}
bash
OUT_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/remove_watermark_pdf/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"dpi\":144,\"timeout_sec\":180,\"output_mode\":\"file_id\"}" \
| jq -r '.tool_result.data.file_id')
Response:
json
{
"code": 200,
"tool": "remove_watermark_pdf",
"tool_result": {
"success": true,
"data": {
"file_id": "file_1741857701_9988aabbccdd.pdf"
}
}
}
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/output.pdf
Critical: The response_mode=raw query parameter is required to get the binary file. Without it, the response is JSON.
If you don't need a reusable file_id for the result, pass "output_mode": "raw" to remove_watermark_pdf and save the response body directly — this combines steps 2 and 3:
bash
curl -sS -X POST "$BASE/v1/tools/remove_watermark_pdf/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"dpi\":144,\"timeout_sec\":180,\"output_mode\":\"raw\"}" \
-o /path/to/output.pdf
Remove watermark from a PDF (three-step, keeps an output file_id):
bash
BASE="https://ai-tools.camscanner.com"
INPUT_PDF="/path/to/document.pdf"
OUTPUT_FILE="/path/to/output.pdf"
# Upload
IN_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/upload_file/execute" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$INPUT_PDF" | jq -r '.tool_result.data.file_id')
# Remove watermark
OUT_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/remove_watermark_pdf/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"dpi\":144,\"timeout_sec\":180,\"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"
Or one-shot (two-step, raw PDF stream straight from remove_watermark_pdf):
bash
BASE="https://ai-tools.camscanner.com"
INPUT_PDF="/path/to/document.pdf"
OUTPUT_FILE="/path/to/output.pdf"
# Upload
IN_FILE_ID=$(curl -sS -X POST "$BASE/v1/tools/upload_file/execute" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$INPUT_PDF" | jq -r '.tool_result.data.file_id')
# Remove watermark + download in one call
curl -sS -X POST "$BASE/v1/tools/remove_watermark_pdf/execute" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$IN_FILE_ID\",\"dpi\":144,\"timeout_sec\":180,\"output_mode\":\"raw\"}" \
-o "$OUTPUT_FILE"
MistakeFixForgetting response_mode=raw on downloadAlways append ?response_mode=raw to the download URLWrong Content-Type on uploadUpload uses application/octet-stream, not multipart/form-dataUsing GET instead of POSTAll endpoints use POSTUsing enhance_image for a PDFPDFs use the dedicated remove_watermark_pdf endpoint, not enhance_imagePassing dpi or timeout_sec as stringsBoth are integers — use 144 and 180, not "144" / "180"Missing output_mode in requestMust be either "file_id" (then download separately) or "raw" (stream out)Timeout on long PDFsIncrease timeout_sec (e.g. 180 or more) for documents with many pagesParsing JSON when output_mode is "raw"With raw, the response body IS the PDF — write it to a file with -oTrying to download a file_id after raw responseraw mode returns no file_id; re-run in file_id mode if you need one
Check each step before proceeding:
bash
# After upload
if [ -z "$IN_FILE_ID" ] || [ "$IN_FILE_ID" = "null" ]; then
echo "Upload failed"; exit 1
fi
# After remove watermark (file_id mode)
if [ -z "$OUT_FILE_ID" ] || [ "$OUT_FILE_ID" = "null" ]; then
echo "Watermark removal failed"; exit 1
fi