API de HTML a PDF#
La API de HTML a PDF convierte un archivo HTML subido en un PDF de alta calidad usando el renderizado de WeasyPrint. Envía un archivo .html o .htm a POST /v1/convert/html-to-pdf y el PDF renderizado se devuelve de forma síncrona: como bytes sin procesar por defecto, o como metadatos JSON con una URL de descarga prefirmada cuando direct_download=false. El tamaño de página, los márgenes, la orientación, los encabezados, los pies de página y la salida en escala de grises se controlan mediante pdf_options.
Endpoint#
POST /v1/convert/html-to-pdf
Content-Type: multipart/form-data
Entrada aceptada: archivos .html o .htm (codificados en UTF-8)
Formato de salida: .pdf (application/pdf)
Autenticación#
Requiere una clave API privada o un token JWT obtenido de una clave pública.
X-API-Key: sk_your_private_key
O bien:
Authorization: Bearer <jwt_token>
Parámetros de la solicitud#
| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|---|---|---|---|---|
file |
file | Sí | -- | El archivo .html o .htm a convertir. Debe estar codificado en UTF-8. |
output_filename |
string |
No | Nombre del archivo de entrada | Nombre de archivo de salida personalizado. La extensión .pdf se añade automáticamente. |
direct_download |
boolean |
No | true |
Con true, devuelve los bytes del PDF sin procesar. Con false, devuelve metadatos JSON con una URL de descarga prefirmada. |
pdf_options |
string |
No | null |
Cadena JSON con opciones de configuración del PDF. Ver más abajo. |
Opciones de PDF#
Pásalas como una cadena JSON en el campo de formulario pdf_options. Todos los campos son opcionales.
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
page_size |
string |
"A4" |
Tamaño de página con nombre. Se ignora cuando page_width y page_height están definidos a la vez. |
page_width |
float |
null |
Ancho de página personalizado en milímetros. page_width y page_height deben definirse juntos. |
page_height |
float |
null |
Alto de página personalizado en milímetros. |
orientation |
string |
"portrait" |
"portrait" o "landscape". |
margins |
object |
{"top": 10, "bottom": 10, "left": 10, "right": 10} |
Márgenes de página en milímetros. |
grayscale |
boolean |
false |
Convierte la salida a escala de grises mediante posprocesado con Ghostscript. |
header |
object |
null |
Encabezado de página. Formato: {"content": "<text>", "height": 15}. Admite variables de plantilla. |
footer |
object |
null |
Pie de página. Mismo formato que el encabezado. |
Tamaños de página admitidos: A0, A1, A2, A3, A4, A5, A6, B0, B1, B2, B3, B4, B5, Letter, Legal, Tabloid, Ledger
Variables de plantilla para encabezado/pie: {{page}}, {{total_pages}}, {{date}}, {{title}}, {{url}}
Detalles de la conversión#
- Usa WeasyPrint para el renderizado de PDF basado en CSS
- Las
pdf_optionsse traducen a reglas CSS@pageque se inyectan en el HTML antes del renderizado - WeasyPrint respeta los estilos CSS propios del documento además de las reglas de página inyectadas
- Todo el renderizado es síncrono y del lado del servidor
Respuesta#
Descarga directa (direct_download=true, predeterminado)#
HTTP 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="document_20260405_123456789.pdf"
Devuelve los bytes del PDF sin procesar.
Respuesta con metadatos (direct_download=false)#
{
"presigned_url": "https://spaces.example.com/...",
"object_key": "env/files/{project_id}/html-to-pdf/document_20260405_123456789.pdf",
"filename": "document_20260405_123456789.pdf",
"file_size": 45678,
"conversion_time_seconds": 1.2
}
Ejemplos de código#
Python#
import requests
import json
with open("report.html", "rb") as f:
response = requests.post(
"https://api.enconvert.com/v1/convert/html-to-pdf",
headers={"X-API-Key": "sk_your_private_key"},
files={"file": ("report.html", f, "text/html")},
data={
"pdf_options": json.dumps({
"page_size": "A4",
"orientation": "portrait",
"margins": {"top": 20, "bottom": 20, "left": 15, "right": 15}
})
}
)
with open("report.pdf", "wb") as out:
out.write(response.content)
Node.js#
const form = new FormData();
form.append("file", fs.createReadStream("report.html"));
form.append("pdf_options", JSON.stringify({
page_size: "A4",
orientation: "portrait",
margins: { top: 20, bottom: 20, left: 15, right: 15 }
}));
const response = await fetch("https://api.enconvert.com/v1/convert/html-to-pdf", {
method: "POST",
headers: { "X-API-Key": "sk_your_private_key" },
body: form
});
fs.writeFileSync("report.pdf", Buffer.from(await response.arrayBuffer()));
PHP#
$ch = curl_init("https://api.enconvert.com/v1/convert/html-to-pdf");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: sk_your_private_key"],
CURLOPT_POSTFIELDS => [
"file" => new CURLFile("report.html", "text/html"),
"pdf_options" => json_encode([
"page_size" => "A4",
"margins" => ["top" => 20, "bottom" => 20, "left" => 15, "right" => 15]
])
]
]);
$pdf = curl_exec($ch);
curl_close($ch);
file_put_contents("report.pdf", $pdf);
Go#
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "report.html")
file, _ := os.Open("report.html")
io.Copy(part, file)
writer.WriteField("pdf_options", `{"page_size":"A4","margins":{"top":20,"bottom":20,"left":15,"right":15}}`)
writer.Close()
req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/html-to-pdf", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_your_private_key")
resp, _ := http.DefaultClient.Do(req)
Respuestas de error#
| Estado | Condición |
|---|---|
400 Bad Request |
El archivo no es un archivo .html o .htm |
400 Bad Request |
Codificación HTML no válida (se espera UTF-8) |
400 Bad Request |
La conversión de HTML a PDF falló |
400 Bad Request |
JSON de pdf_options no válido |
401 Unauthorized |
Clave API o token JWT ausente o no válido |
402 Payment Required |
Cuota mensual de ops agotada |
402 Payment Required |
Límite de almacenamiento alcanzado |
413 Payload Too Large |
El archivo supera el tamaño máximo del plan |
Límites#
| Límite | Valor |
|---|---|
| Tamaño máximo de archivo | Según el plan (Founding: 5 MB) |
| Codificación de entrada | Solo UTF-8 |
| Contenido de encabezado/pie | Máximo 2000 caracteres |
| Rango de escala | 0.1 -- 2.0 |
| Conversiones mensuales | Según el plan |
Preguntas frecuentes#
¿Cómo convierto HTML a PDF con una API REST?#
Envía una solicitud multipart/form-data a POST /v1/convert/html-to-pdf con tu archivo .html o .htm en el campo file, autenticándote mediante X-API-Key o un JWT Bearer. Por defecto, la respuesta son los bytes del PDF sin procesar con Content-Type: application/pdf.
¿Puedo establecer un tamaño de página, márgenes u orientación personalizados para el PDF?#
Sí. Pasa una cadena JSON en el campo de formulario pdf_options con page_size (p. ej. A4, Letter, Legal), margins en milímetros y orientation (portrait o landscape). Para dimensiones no estándar, define page_width y page_height juntos en milímetros.
¿Cómo añado números de página o encabezados y pies de página al PDF generado?#
Define header o footer en pdf_options como {"content": "<text>", "height": 15}. El contenido admite las variables de plantilla {{page}}, {{total_pages}}, {{date}}, {{title}} y {{url}}, y está limitado a 2000 caracteres.
¿Por qué faltan imágenes, fuentes u hojas de estilo en mi PDF de salida?#
Los recursos externos referenciados por URL en el HTML pueden no resolverse durante el renderizado del lado del servidor. Usa CSS en línea e imágenes codificadas en base64, o asegúrate de que todos los recursos referenciados sean accesibles públicamente.
¿Puedo obtener una URL de descarga en lugar de los bytes del PDF sin procesar?#
Sí. Establece direct_download=false y el endpoint devuelve metadatos JSON que incluyen presigned_url, object_key, filename, file_size y conversion_time_seconds en lugar del cuerpo del PDF.