Inicio rápido
Tres pasos hasta tu primera llamada a la API.
- Crea una clave API desde Cuenta › Claves API
- Envía un POST multipart/form-data a uno de los endpoints v1 con una cabecera Authorization: Bearer.
- Inspecciona la respuesta JSON — las llamadas correctas devuelven una URL de descarga firmada válida durante 15 minutos.
URL base
Autenticación
Cada petición debe incluir una cabecera Authorization con tu clave API como token Bearer.
Authorization: Bearer pdn_live_a1b2c3d4e5f6...Formatos de clave
pdn_live_<32 hex>— Clave de producción. Cuenta para el límite de uso de tu plan.pdn_test_<32 hex>— Clave de prueba. Mismo límite; útil para distinguir entornos en los registros.
Límites de uso
Los límites se calculan por usuario, en una ventana móvil de 1 hora. Cada respuesta incluye cabeceras X-RateLimit-* para que planifiques los reintentos.
| Plan | Peticiones / hora |
|---|---|
| Free | 10 |
| Premium | 1,000 |
| Business | 5,000 |
| Enterprise | Ilimitado |
Cabeceras de respuesta
X-RateLimit-Limit— El tope horario de tu plan.X-RateLimit-Remaining— Llamadas restantes en la ventana actual.X-RateLimit-Reset— Marca de tiempo Unix cuando se reinicia la ventana.Retry-After— Segundos a esperar; solo se envía en respuestas 429.
Errores
Todos los errores se devuelven como JSON con un código estable y un mensaje legible.
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded for your plan (free: 10/hour)."
},
"meta": { "request_id": "8f9a2b3c1d4e5f6a" }
}Códigos de error
| Code | HTTP | Significado |
|---|---|---|
unauthorized | 401 | Clave API ausente, mal formada o revocada. |
rate_limited | 429 | Has superado el límite horario de tu plan. |
invalid_input | 400 | El cuerpo o los parámetros de la petición no superaron la validación. |
payload_too_large | 413 | El archivo o la carga combinada supera el límite de tamaño de tu plan. |
internal_error | 500 | Error inesperado del servidor. Seguro reintentar con espera incremental. |
POST /compress
Comprime un PDF usando Ghostscript cuando esté disponible, con FPDI como alternativa. Devuelve una URL de descarga firmada.
Parámetros (multipart/form-data)
| Nombre | Tipo | Descripción |
|---|---|---|
| file * | file | Archivo PDF a comprimir. |
| level | string | Preajuste de compresión. low, medium, high |
Ejemplos de código
curl -X POST https://whatapdf.com/api/v1/compress \
-H "Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "level=medium"const form = new FormData();
form.append('file', fileInput.files[0]);
form.append('level', 'medium');
const res = await fetch('https://whatapdf.com/api/v1/compress', {
method: 'POST',
headers: { 'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' },
body: form,
});
const json = await res.json();
console.log(json.data.download.url);import requests
with open('input.pdf', 'rb') as f:
r = requests.post(
'https://whatapdf.com/api/v1/compress',
headers={'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
files={'file': f},
data={'level': 'medium'},
)
print(r.json())<?php
$ch = curl_init('https://whatapdf.com/api/v1/compress');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'level' => 'medium',
],
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($res);Respuesta de ejemplo
{
"data": {
"filename": "report_compressed.pdf",
"original_size": 5242880,
"compressed_size": 2621440,
"savings_percent": 50.0,
"method": "ghostscript",
"download": {
"url": "/api/get-pdf.php?file=...&exp=...&sig=...",
"expires_in": 900
}
},
"meta": { "request_id": "8f9a2b3c1d4e5f6a" }
}POST /merge
Une de 2 a 20 PDFs en un único documento, en el orden de subida.
Parámetros
| Nombre | Tipo | Descripción |
|---|---|---|
| files[] * | file[] | Dos o más archivos PDF (array multipart). |
Ejemplos de código
curl -X POST https://whatapdf.com/api/v1/merge \
-H "Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "files[][email protected]" \
-F "files[][email protected]" \
-F "files[][email protected]"const form = new FormData();
for (const f of fileInput.files) form.append('files[]', f);
const res = await fetch('https://whatapdf.com/api/v1/merge', {
method: 'POST',
headers: { 'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' },
body: form,
});
console.log(await res.json());import requests
files = [
('files[]', open('a.pdf', 'rb')),
('files[]', open('b.pdf', 'rb')),
('files[]', open('c.pdf', 'rb')),
]
r = requests.post(
'https://whatapdf.com/api/v1/merge',
headers={'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
files=files,
)
print(r.json())<?php
$ch = curl_init('https://whatapdf.com/api/v1/merge');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'],
CURLOPT_POSTFIELDS => [
'files[0]' => new CURLFile('a.pdf', 'application/pdf'),
'files[1]' => new CURLFile('b.pdf', 'application/pdf'),
'files[2]' => new CURLFile('c.pdf', 'application/pdf'),
],
]);
echo curl_exec($ch);
curl_close($ch);POST /split
Divide un PDF en una o más partes por rangos de páginas. Cada parte se devuelve con su propia URL de descarga firmada.
Parámetros
| Nombre | Tipo | Descripción |
|---|---|---|
| file * | file | PDF de origen. |
| ranges * | string | Rangos de páginas separados por comas. Un rango = una parte de salida. e.g. 1-3,5,7-9 |
Ejemplos de código
curl -X POST https://whatapdf.com/api/v1/split \
-H "Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "ranges=1-3,5,7-9"const form = new FormData();
form.append('file', fileInput.files[0]);
form.append('ranges', '1-3,5,7-9');
const res = await fetch('https://whatapdf.com/api/v1/split', {
method: 'POST',
headers: { 'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' },
body: form,
});
console.log(await res.json());import requests
with open('input.pdf', 'rb') as f:
r = requests.post(
'https://whatapdf.com/api/v1/split',
headers={'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
files={'file': f},
data={'ranges': '1-3,5,7-9'},
)
for part in r.json()['data']['parts']:
print(part['pages'], part['download']['url'])<?php
$ch = curl_init('https://whatapdf.com/api/v1/split');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'ranges' => '1-3,5,7-9',
],
]);
print_r(json_decode(curl_exec($ch), true));
curl_close($ch);POST /ocr
Extrae texto de una imagen usando Tesseract OCR. Compatible con más de 20 idiomas.
Parámetros
| Nombre | Tipo | Descripción |
|---|---|---|
| image * | file | Imagen para OCR (PNG, JPEG, TIFF, WebP o BMP). |
| language | string | Código de idioma de Tesseract. Por defecto eng |
Ejemplos de código
curl -X POST https://whatapdf.com/api/v1/ocr \
-H "Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "language=eng"const form = new FormData();
form.append('image', imageInput.files[0]);
form.append('language', 'eng');
const res = await fetch('https://whatapdf.com/api/v1/ocr', {
method: 'POST',
headers: { 'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' },
body: form,
});
const { data } = await res.json();
console.log(data.text);import requests
with open('scan.png', 'rb') as f:
r = requests.post(
'https://whatapdf.com/api/v1/ocr',
headers={'Authorization': 'Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
files={'image': f},
data={'language': 'eng'},
)
print(r.json()['data']['text'])<?php
$ch = curl_init('https://whatapdf.com/api/v1/ocr');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer pdn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'],
CURLOPT_POSTFIELDS => [
'image' => new CURLFile('scan.png', 'image/png'),
'language' => 'eng',
],
]);
$res = json_decode(curl_exec($ch), true);
echo $res['data']['text'];
curl_close($ch);