API de Markdown a PDF#

La API de Markdown a PDF convierte un archivo Markdown en un documento PDF con estilo mediante POST /v1/convert/markdown-to-pdf. Tu archivo .md o .markdown se renderiza primero a HTML, con soporte para tablas, bloques de código delimitados con resaltado de sintaxis y tabla de contenidos. Después se convierte a PDF con WeasyPrint. La respuesta son los bytes del PDF en bruto por defecto, o metadatos JSON con una URL de descarga prefirmada cuando direct_download=false; los tamaños de página personalizados, márgenes, encabezados, pies de página y la salida en escala de grises están disponibles vía pdf_options.


Endpoint#

POST /v1/convert/markdown-to-pdf

Content-Type: multipart/form-data

Entrada aceptada: archivos .md o .markdown (codificados en UTF-8)

Formato de salida: .pdf (application/pdf)


Autenticación#

Requiere una clave API privada o un token JWT emitido a partir 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 Requerido Por defecto Descripción
file file -- El archivo .md o .markdown 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 en bruto. Con false, devuelve metadatos JSON con una URL de descarga prefirmada.
pdf_options string No null Cadena JSON con las opciones de configuración del PDF. Ver abajo.

Opciones de PDF#

Pásalas como cadena JSON en el campo de formulario pdf_options. Todos los campos son opcionales.

Parámetro Tipo Por defecto Descripción
page_size string "A4" Tamaño de página con nombre.
page_width float null Ancho de página personalizado en milímetros. Ancho y alto deben definirse juntos.
page_height float null Alto de página personalizado en milímetros.
orientation string "portrait" "portrait" u "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.
header object null Encabezado de página. Formato: {"content": "<text>", "height": 15}.
footer object null Pie de página. Mismo formato que el encabezado.

Tamaños de página soportados: A0-A6, B0-B5, Letter, Legal, Tabloid, Ledger

Variables de plantilla para encabezado/pie de página: {{page}}, {{total_pages}}, {{date}}, {{title}}, {{url}}


Detalles de la conversión#

La conversión es un proceso de dos pasos:

  1. Markdown a HTML usando Python-Markdown con las extensiones:
  2. tables -- tablas delimitadas por barras verticales
  3. fenced_code -- bloques de código con triple backtick
  4. codehilite -- resaltado de sintaxis
  5. toc -- tabla de contenidos mediante el marcador [TOC]
  6. attr_list -- atributos HTML mediante la sintaxis {.class #id}

  7. HTML a PDF usando WeasyPrint con una hoja de estilos integrada que proporciona:

  8. Pila de fuentes del sistema, layout centrado con ancho máximo de 800px
  9. Bloques de código, tablas, citas e imágenes con estilo
  10. Dimensionado responsivo de imágenes (max-width: 100%)

Las pdf_options se inyectan como reglas CSS @page antes del renderizado.


Respuesta#

Descarga directa (direct_download=true, por defecto)#

HTTP 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="readme_20260405_123456789.pdf"

Respuesta con metadatos (direct_download=false)#

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/markdown-to-pdf/readme_20260405_123456789.pdf",
    "filename": "readme_20260405_123456789.pdf",
    "file_size": 34567,
    "conversion_time_seconds": 0.8
}

Ejemplos de código#

Python#

import requests
import json

with open("README.md", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/markdown-to-pdf",
        headers={"X-API-Key": "sk_your_private_key"},
        files={"file": ("README.md", f, "text/markdown")},
        data={
            "pdf_options": json.dumps({
                "page_size": "Letter",
                "margins": {"top": 25, "bottom": 25, "left": 20, "right": 20},
                "footer": {"content": "Page {{page}} of {{total_pages}}", "height": 10}
            })
        }
    )

with open("README.pdf", "wb") as out:
    out.write(response.content)

Node.js#

const form = new FormData();
form.append("file", fs.createReadStream("README.md"));
form.append("pdf_options", JSON.stringify({
    page_size: "Letter",
    footer: { content: "Page {{page}} of {{total_pages}}", height: 10 }
}));

const response = await fetch("https://api.enconvert.com/v1/convert/markdown-to-pdf", {
    method: "POST",
    headers: { "X-API-Key": "sk_your_private_key" },
    body: form
});

fs.writeFileSync("README.pdf", Buffer.from(await response.arrayBuffer()));

PHP#

$ch = curl_init("https://api.enconvert.com/v1/convert/markdown-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("README.md", "text/markdown"),
        "pdf_options" => json_encode(["page_size" => "Letter", "grayscale" => true])
    ]
]);
$pdf = curl_exec($ch);
curl_close($ch);
file_put_contents("README.pdf", $pdf);

Go#

body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

part, _ := writer.CreateFormFile("file", "README.md")
file, _ := os.Open("README.md")
io.Copy(part, file)

writer.WriteField("pdf_options", `{"page_size":"Letter","grayscale":true}`)
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/markdown-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 .md ni .markdown
400 Bad Request Codificación de Markdown inválida (se espera UTF-8)
400 Bad Request La conversión de Markdown a PDF falló
400 Bad Request JSON de pdf_options inválido
401 Unauthorized Clave API o token JWT ausente o invá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 de archivo del plan

Límites#

Límite Valor
Tamaño máximo de archivo Depende del plan (Founding: 5 MB)
Codificación de entrada Solo UTF-8
Extensiones aceptadas .md, .markdown
Contenido de encabezado/pie de página 2000 caracteres máx.
Conversiones mensuales Depende del plan

Preguntas frecuentes#

¿Cómo convierto un archivo Markdown a PDF con una API REST?#

Envía una solicitud multipart/form-data a POST /v1/convert/markdown-to-pdf con tu archivo .md o .markdown (codificado en UTF-8) en el campo file, autenticada vía X-API-Key o un JWT Bearer. Por defecto se devuelven directamente los bytes del PDF en bruto.

¿La conversión de Markdown a PDF soporta tablas y resaltado de sintaxis de código?#

Sí. El Markdown se renderiza con extensiones de Python-Markdown, incluyendo tables para tablas delimitadas por barras verticales, fenced_code para bloques de código con triple backtick y codehilite para el resaltado de sintaxis, y después se estiliza con una hoja de estilos integrada.

¿Puedo añadir una tabla de contenidos al PDF generado?#

Sí. Coloca un marcador [TOC] en tu Markdown y la extensión toc lo renderiza como una tabla de contenidos en el documento de salida.

¿Cómo añado números de página a un PDF de Markdown?#

Define un footer (o header) en el JSON de pdf_options, p. ej. {"content": "Page {{page}} of {{total_pages}}", "height": 10}. Las variables de plantilla soportadas son {{page}}, {{total_pages}}, {{date}}, {{title}} y {{url}}.

¿Por qué mi solicitud devuelve 400 Bad Request?#

Causas comunes: el archivo no es .md ni .markdown, el contenido no está codificado en UTF-8, el campo pdf_options no es JSON válido, o la conversión en sí falló. Revisa el mensaje de error específico en el cuerpo de la respuesta.