PDF Blocks
PreciosSoporte
Empezar gratis
Ir a la página

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

POST
/v1/add_text_watermark

Disponible 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.

filefilerequired

El documento PDF de entrada.

line_1stringrequired

La primera línea del texto de la marca de agua. Máximo 32 caracteres. Use caracteres latinos estándar.

line_2string

La segunda línea del texto de la marca de agua. Máximo 32 caracteres.

line_3string

La tercera línea del texto de la marca de agua. Máximo 32 caracteres.

pagesstring

Las 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:1001

La plantilla de la marca de agua, que fija el estilo (relleno o contorno) y la orientación.

colorstringdefault:Gray

El color de la marca de agua. Uno de Red, Blue, Gray o Black.

transparencyintegerdefault:75

El nivel de transparencia, de 0 (totalmente opaco) a 100 (totalmente transparente).

margindecimaldefault:1.0

La 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:

cURLbash
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
Pythonpython
# 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.jsjavascript
// 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()));
PHPphp
<?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);
}
Rubyruby
# 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?
Gogo
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)
}
C#csharp
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: 48213

La 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
cURLbash
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.pdf
Pythonpython
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': 'DRAFT', 'color': 'Red', 'template': 1001, 'transparency': 40},
    )

response.raise_for_status()
with open('draft.pdf', 'wb') as output:
    output.write(response.content)
Node.jsjavascript
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()));
PHPphp
<?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);
}
Rubyruby
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?
Gogo
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)
}
C#csharp
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
cURLbash
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.pdf
Pythonpython
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', 'template': 1017, 'pages': '1'},
    )

response.raise_for_status()
with open('confidential.pdf', 'wb') as output:
    output.write(response.content)
Node.jsjavascript
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()));
PHPphp
<?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);
}
Rubyruby
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?
Gogo
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)
}
C#csharp
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
cURLbash
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.pdf
Pythonpython
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': '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)
Node.jsjavascript
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()));
PHPphp
<?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);
}
Rubyruby
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?
Gogo
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)
}
C#csharp
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());

Acciones relacionadas