Añadir una marca de agua de texto a un PDF
Estampe hasta tres líneas de texto en las páginas de un PDF, con control de la plantilla, el color y la opacidad.
Añada una marca de agua de texto a un documento PDF. Proporcione hasta tres
líneas de texto y controle la plantilla, el color, la transparencia y el
margen. De forma predeterminada, la marca de agua se estampa en todas las
páginas: use el parámetro pages para apuntar a un
subconjunto. La API es stateless: su documento se procesa en la región y
nunca se almacena.
Endpoint
/v1/add_text_watermarkDisponible en todas las regiones. Consulte Regiones y residencia de datos para el enrutamiento y la residencia de datos.
| Región | URL |
|---|---|
| Global | https://api.pdfblocks.com/v1/add_text_watermark |
| Estados Unidos | https://us.api.pdfblocks.com/v1/add_text_watermark |
| HIPAA de EE. UU. | https://hipaa.api.pdfblocks.com/v1/add_text_watermark |
| Unión Europea | https://eu.api.pdfblocks.com/v1/add_text_watermark |
| Reino Unido | https://uk.api.pdfblocks.com/v1/add_text_watermark |
| Canadá | https://ca.api.pdfblocks.com/v1/add_text_watermark |
| Australia | https://au.api.pdfblocks.com/v1/add_text_watermark |
| Japón | https://jp.api.pdfblocks.com/v1/add_text_watermark |
| India | https://in.api.pdfblocks.com/v1/add_text_watermark |
| Brasil | https://br.api.pdfblocks.com/v1/add_text_watermark |
Autenticación
Autentique cada solicitud con su clave de API secreta en la cabecera
X-API-Key, por HTTPS. Cree y administre sus claves desde el
dashboard. Consulte
Autenticación para más detalles.
Solicitud
El endpoint acepta un cuerpo de solicitud multipart/form-data.
filefilerequiredEl documento PDF de entrada.
line_1stringrequiredLa primera línea del texto de la marca de agua. Máximo 32 caracteres. Use caracteres latinos estándar.
line_2stringLa segunda línea del texto de la marca de agua. Máximo 32 caracteres.
line_3stringLa tercera línea del texto de la marca de agua. Máximo 32 caracteres.
pagesstringLas páginas que se estamparán, escritas como un rango de
páginas tipo 1..3,5. Si se omite, la marca de agua se
aplica a todas las páginas. Máximo 1000 caracteres.
templateintegerdefault:1001La plantilla de la marca de agua, que fija el estilo (relleno o contorno) y la orientación.
colorstringdefault:GrayEl color de la marca de agua. Uno de Red, Blue, Gray o
Black.
transparencyintegerdefault:75El nivel de transparencia, de 0 (totalmente opaco) a 100 (totalmente
transparente).
margindecimaldefault:1.0La distancia, en pulgadas, del borde de la página a la marca de agua. 0 o
mayor.
Plantillas de marca de agua
Cada template combina un estilo, relleno o contorno, con una
orientación. Pase el identificador al parámetro template.
| Plantilla | Estilo | Orientación |
|---|---|---|
1001 |
Relleno | Diagonal, de la esquina inferior izquierda a la superior derecha (predeterminado) |
1002 |
Relleno | Diagonal, de la esquina superior izquierda a la inferior derecha |
1003 |
Relleno | Horizontal |
1004 |
Relleno | Vertical, se lee hacia arriba |
1005 |
Relleno | Vertical, se lee hacia abajo |
1017 |
Contorno | Diagonal, de la esquina inferior izquierda a la superior derecha |
1018 |
Contorno | Diagonal, de la esquina superior izquierda a la inferior derecha |
1019 |
Contorno | Horizontal |
1020 |
Contorno | Vertical, se lee hacia arriba |
1021 |
Contorno | Vertical, se lee hacia abajo |
Vea todas las plantillas representadas en una página de ejemplo en el catálogo visual de plantillas.
Colores
| Valor | Muestra |
|---|---|
Red |
#C00000 |
Blue |
#005DFF |
Gray |
#545454 |
Black |
#000000 |
Seleccionar páginas
El parámetro pages recibe una lista separada por comas de números de página
en base 1 y de rangos. Se trata como un conjunto: el orden y los
duplicados se ignoran, y las páginas siempre se estampan en el orden del
documento.
| Patrón | Selecciona |
|---|---|
| (omitir) | Todas las páginas |
1 |
Solo la primera página |
1..3,5 |
Las páginas 1, 2, 3 y 5 |
2.. |
De la página 2 a la última |
..-2 |
De la primera página a la penúltima |
-1 |
La última página |
Consulte Seleccionar páginas para ver la referencia completa.
Ejemplos
Estampe una marca de agua de dos líneas en las páginas 1 a 3 y en la 5:
curl https://api.pdfblocks.com/v1/add_text_watermark \
-H 'X-API-Key: your_api_key' \
-F file=@input.pdf \
-F line_1='CONFIDENTIAL' \
-F line_2='ACME, Inc.' \
-F template=1001 \
-F color=Red \
-F pages='1..3,5' \
-o watermarked.pdf# pip install requests
import requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/add_text_watermark',
headers={'X-API-Key': 'your_api_key'},
files={'file': file},
data={
'line_1': 'CONFIDENTIAL',
'line_2': 'ACME, Inc.',
'template': 1001,
'color': 'Red',
'pages': '1..3,5',
},
)
response.raise_for_status()
with open('watermarked.pdf', 'wb') as output:
output.write(response.content)// Node.js 18+
import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('line_1', 'CONFIDENTIAL');
body.set('line_2', 'ACME, Inc.');
body.set('template', '1001');
body.set('color', 'Red');
body.set('pages', '1..3,5');
const response = await fetch('https://api.pdfblocks.com/v1/add_text_watermark', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('watermarked.pdf', Buffer.from(await response.arrayBuffer()));<?php
$ch = curl_init('https://api.pdfblocks.com/v1/add_text_watermark');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'line_1' => 'CONFIDENTIAL',
'line_2' => 'ACME, Inc.',
'template' => '1001',
'color' => 'Red',
'pages' => '1..3,5',
],
]);
$pdf = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
file_put_contents('watermarked.pdf', $pdf);
}# gem install http
require 'http'
response = HTTP
.headers('X-API-Key' => 'your_api_key')
.post('https://api.pdfblocks.com/v1/add_text_watermark', form: {
file: HTTP::FormData::File.new('input.pdf'),
line_1: 'CONFIDENTIAL',
line_2: 'ACME, Inc.',
template: '1001',
color: 'Red',
pages: '1..3,5',
})
File.write('watermarked.pdf', response.body) if response.status.success?package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("line_1", "CONFIDENTIAL")
form.WriteField("line_2", "ACME, Inc.")
form.WriteField("template", "1001")
form.WriteField("color", "Red")
form.WriteField("pages", "1..3,5")
form.Close()
req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/add_text_watermark", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
out, _ := os.Create("watermarked.pdf")
defer out.Close()
io.Copy(out, res.Body)
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
using var form = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
{ new StringContent("CONFIDENTIAL"), "line_1" },
{ new StringContent("ACME, Inc."), "line_2" },
{ new StringContent("1001"), "template" },
{ new StringContent("Red"), "color" },
{ new StringContent("1..3,5"), "pages" },
};
var response = await client.PostAsync(
"https://api.pdfblocks.com/v1/add_text_watermark", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
"watermarked.pdf", await response.Content.ReadAsByteArrayAsync());Respuesta
Si todo va bien, la respuesta es 200 OK con el PDF estampado como cuerpo:
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 48213La salida conserva el número de páginas y las dimensiones de la entrada: lo único que se añade es la marca de agua. Escriba el cuerpo directamente en un archivo, como hacen los ejemplos anteriores; en nuestro lado no se almacena nada.
Errores
Las solicitudes fallidas devuelven un cuerpo application/problem+json. El
error más habitual en este endpoint es un 400, que se devuelve cuando un
parámetro no es válido o file no es un PDF legible: el objeto errors
nombra cada campo:
{
"type": "https://www.pdfblocks.com/docs/api/v1/error/400",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"line_1": ["The field line_1 must be a string with a maximum length of 32."]
}
}Una X-API-Key ausente o no válida devuelve un 401. Consulte
Errores para ver todos los códigos de estado y la forma
completa de la respuesta.
Recetas
Variantes habituales. Despliegue una para verla en todos los lenguajes.
Un DRAFT rojo en negrita en todas las páginas
curl https://api.pdfblocks.com/v1/add_text_watermark \
-H 'X-API-Key: your_api_key' \
-F file=@input.pdf \
-F line_1='DRAFT' \
-F color=Red \
-F template=1001 \
-F transparency=40 \
-o draft.pdfimport requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/add_text_watermark',
headers={'X-API-Key': 'your_api_key'},
files={'file': file},
data={'line_1': 'DRAFT', 'color': 'Red', 'template': 1001, 'transparency': 40},
)
response.raise_for_status()
with open('draft.pdf', 'wb') as output:
output.write(response.content)import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('line_1', 'DRAFT');
body.set('color', 'Red');
body.set('template', '1001');
body.set('transparency', '40');
const response = await fetch('https://api.pdfblocks.com/v1/add_text_watermark', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('draft.pdf', Buffer.from(await response.arrayBuffer()));<?php
$ch = curl_init('https://api.pdfblocks.com/v1/add_text_watermark');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'line_1' => 'DRAFT',
'color' => 'Red',
'template' => '1001',
'transparency' => '40',
],
]);
$pdf = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
file_put_contents('draft.pdf', $pdf);
}require 'http'
response = HTTP
.headers('X-API-Key' => 'your_api_key')
.post('https://api.pdfblocks.com/v1/add_text_watermark', form: {
file: HTTP::FormData::File.new('input.pdf'),
line_1: 'DRAFT',
color: 'Red',
template: '1001',
transparency: '40',
})
File.write('draft.pdf', response.body) if response.status.success?package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("line_1", "DRAFT")
form.WriteField("color", "Red")
form.WriteField("template", "1001")
form.WriteField("transparency", "40")
form.Close()
req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/add_text_watermark", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
out, _ := os.Create("draft.pdf")
defer out.Close()
io.Copy(out, res.Body)
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
using var form = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
{ new StringContent("DRAFT"), "line_1" },
{ new StringContent("Red"), "color" },
{ new StringContent("1001"), "template" },
{ new StringContent("40"), "transparency" },
};
var response = await client.PostAsync(
"https://api.pdfblocks.com/v1/add_text_watermark", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
"draft.pdf", await response.Content.ReadAsByteArrayAsync());Un CONFIDENTIAL en contorno en la portada
curl https://api.pdfblocks.com/v1/add_text_watermark \
-H 'X-API-Key: your_api_key' \
-F file=@input.pdf \
-F line_1='CONFIDENTIAL' \
-F template=1017 \
-F pages='1' \
-o confidential.pdfimport requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/add_text_watermark',
headers={'X-API-Key': 'your_api_key'},
files={'file': file},
data={'line_1': 'CONFIDENTIAL', 'template': 1017, 'pages': '1'},
)
response.raise_for_status()
with open('confidential.pdf', 'wb') as output:
output.write(response.content)import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('line_1', 'CONFIDENTIAL');
body.set('template', '1017');
body.set('pages', '1');
const response = await fetch('https://api.pdfblocks.com/v1/add_text_watermark', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('confidential.pdf', Buffer.from(await response.arrayBuffer()));<?php
$ch = curl_init('https://api.pdfblocks.com/v1/add_text_watermark');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'line_1' => 'CONFIDENTIAL',
'template' => '1017',
'pages' => '1',
],
]);
$pdf = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
file_put_contents('confidential.pdf', $pdf);
}require 'http'
response = HTTP
.headers('X-API-Key' => 'your_api_key')
.post('https://api.pdfblocks.com/v1/add_text_watermark', form: {
file: HTTP::FormData::File.new('input.pdf'),
line_1: 'CONFIDENTIAL',
template: '1017',
pages: '1',
})
File.write('confidential.pdf', response.body) if response.status.success?package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("line_1", "CONFIDENTIAL")
form.WriteField("template", "1017")
form.WriteField("pages", "1")
form.Close()
req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/add_text_watermark", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
out, _ := os.Create("confidential.pdf")
defer out.Close()
io.Copy(out, res.Body)
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
using var form = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
{ new StringContent("CONFIDENTIAL"), "line_1" },
{ new StringContent("1017"), "template" },
{ new StringContent("1"), "pages" },
};
var response = await client.PostAsync(
"https://api.pdfblocks.com/v1/add_text_watermark", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
"confidential.pdf", await response.Content.ReadAsByteArrayAsync());Un aviso gris discreto en todas las páginas menos la última
curl https://api.pdfblocks.com/v1/add_text_watermark \
-H 'X-API-Key: your_api_key' \
-F file=@input.pdf \
-F line_1='ACME, Inc.' \
-F line_2='Do not distribute' \
-F color=Gray \
-F transparency=88 \
-F pages='..-2' \
-o notice.pdfimport requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/add_text_watermark',
headers={'X-API-Key': 'your_api_key'},
files={'file': file},
data={
'line_1': 'ACME, Inc.',
'line_2': 'Do not distribute',
'color': 'Gray',
'transparency': 88,
'pages': '..-2',
},
)
response.raise_for_status()
with open('notice.pdf', 'wb') as output:
output.write(response.content)import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('line_1', 'ACME, Inc.');
body.set('line_2', 'Do not distribute');
body.set('color', 'Gray');
body.set('transparency', '88');
body.set('pages', '..-2');
const response = await fetch('https://api.pdfblocks.com/v1/add_text_watermark', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('notice.pdf', Buffer.from(await response.arrayBuffer()));<?php
$ch = curl_init('https://api.pdfblocks.com/v1/add_text_watermark');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'line_1' => 'ACME, Inc.',
'line_2' => 'Do not distribute',
'color' => 'Gray',
'transparency' => '88',
'pages' => '..-2',
],
]);
$pdf = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
file_put_contents('notice.pdf', $pdf);
}require 'http'
response = HTTP
.headers('X-API-Key' => 'your_api_key')
.post('https://api.pdfblocks.com/v1/add_text_watermark', form: {
file: HTTP::FormData::File.new('input.pdf'),
line_1: 'ACME, Inc.',
line_2: 'Do not distribute',
color: 'Gray',
transparency: '88',
pages: '..-2',
})
File.write('notice.pdf', response.body) if response.status.success?package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("line_1", "ACME, Inc.")
form.WriteField("line_2", "Do not distribute")
form.WriteField("color", "Gray")
form.WriteField("transparency", "88")
form.WriteField("pages", "..-2")
form.Close()
req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/add_text_watermark", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
out, _ := os.Create("notice.pdf")
defer out.Close()
io.Copy(out, res.Body)
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
using var form = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
{ new StringContent("ACME, Inc."), "line_1" },
{ new StringContent("Do not distribute"), "line_2" },
{ new StringContent("Gray"), "color" },
{ new StringContent("88"), "transparency" },
{ new StringContent("..-2"), "pages" },
};
var response = await client.PostAsync(
"https://api.pdfblocks.com/v1/add_text_watermark", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
"notice.pdf", await response.Content.ReadAsByteArrayAsync());