API de URL a Markdown#

El endpoint POST /v1/convert/url-to-markdown convierte cualquier página web de acceso público en Markdown GitHub-Flavored limpio con un bloque de metadatos YAML frontmatter. Cada página se renderiza en un navegador real, se pasa por un extractor de legibilidad que elimina el contenido superfluo (navegación, pies de página, barras laterales, scripts, formularios, botones) y luego se serializa a Markdown con enlaces normalizados, bloques de código delimitados y URLs relativas resueltas a absolutas. Es exactamente lo que necesitan los pipelines de ingesta para LLM y RAG en lugar de HTML sin procesar. Las conversiones se ejecutan de forma síncrona o asíncrona en lote, y los resultados se devuelven como bytes Markdown sin procesar o como una URL de descarga prefirmada.


Endpoint#

POST /v1/convert/url-to-markdown

Content-Type: application/json

Formato de salida: Markdown (.md, UTF-8) con un bloque de metadatos YAML frontmatter al principio del archivo, que contiene los metadatos de la página. El formato de salida no es configurable. Siempre se genera Markdown con YAML frontmatter.


Autenticación#

Este endpoint admite autenticación tanto con clave privada como con clave pública.

Clave privada#

Incluye tu clave secreta en el encabezado X-API-Key. Úsalo para llamadas servidor a servidor donde la clave nunca se expone al cliente.

X-API-Key: sk_your_private_key

Clave pública con JWT#

Para uso del lado del cliente, primero genera un token JWT usando tu clave pública y luego pásalo como token Bearer.

Paso 1 -- Obtener un token:

POST /v1/auth/token
X-API-Key: pk_your_public_key

Paso 2 -- Usar el token:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Nota: Las solicitudes con clave pública están restringidas a una sola URL, modo síncrono y descarga directa. El modo asíncrono, el procesamiento por lotes, los webhooks y los correos de notificación no están disponibles con claves públicas.

Parámetros de la solicitud#

Parámetros de nivel superior#

Parameter Type Required Default Description Plan Gating
url string or string[] -- Una cadena de URL única o un array de URLs para convertir. Varias URLs requieren el modo asíncrono. --
async_mode boolean No false Ejecuta la conversión de forma asíncrona. Devuelve un batch_id inmediatamente para consultar el estado (polling). Obligatorio para lotes (varias URLs). Requiere acceso asíncrono
direct_download boolean No false Devuelve los bytes Markdown sin procesar en el cuerpo de la respuesta en lugar de una respuesta JSON con una URL prefirmada. Se fuerza a true para claves públicas. Incompatible con async_mode y con varias URLs. --
output_format boolean No false Cuando es true con varias URLs, agrupa todos los archivos Markdown de salida en un único archivo ZIP. Requiere varias URLs. Requiere acceso a salida ZIP
output_filename string No Autogenerado Nombre de archivo personalizado para el archivo de salida. La extensión .md se añade automáticamente. Formato predeterminado: {domain}_{timestamp}.md. --
job_id string No -- ID de job proporcionado por el cliente para recuperación ante timeout. Solo claves públicas. Cuando una conversión síncrona supera los límites de timeout del proxy inverso, el cliente puede consultar GET /v1/convert/status/{job_id} para obtener el resultado. Se ignora en claves privadas. --
notification_email string No Correo del propietario del proyecto Dirección de correo electrónico a la que se notifica cuando finaliza un job asíncrono. Solo claves privadas. --
callback_url string No -- URL de webhook que recibe una solicitud POST cuando finaliza la conversión. Solo claves privadas. Requiere acceso a webhooks

Parámetros de navegador y renderizado#

Parameter Type Required Default Description Plan Gating
viewport_width integer No 1920 Ancho del viewport del navegador en píxeles. Afecta al contenido responsive y a qué variante de diseño se captura antes de la extracción. --
viewport_height integer No 1080 Alto del viewport del navegador en píxeles. Se usa como referencia para el renderizado y el cálculo de unidades de viewport. --
load_media boolean No true Espera a que todas las imágenes y videos terminen de cargar antes de la extracción. Cuando es false, la extracción es más rápida, pero las imágenes con carga diferida (lazy-loaded) pueden tener valores src de marcador de posición en la salida Markdown. --
enable_scroll boolean No true Desplaza la página de arriba a abajo para activar el contenido de carga diferida (cargadores basados en IntersectionObserver). --
handle_sticky_header boolean No true Detecta encabezados sticky/fijos y desplaza la página hasta arriba antes de la extracción para preservar correctamente el orden del contenido. --
handle_cookies boolean No true Cierra automáticamente los banners de consentimiento de cookies (OneTrust, Cookiebot, Didomi, Usercentrics y banners genéricos) antes de la extracción. --
wait_for_images boolean No true Espera a que todos los elementos <img> terminen de cargar (timeout de 5 segundos por imagen) para capturar correctamente el texto alt y los valores finales de src. --
wait_for_selector string No null Selector CSS que se espera antes de la extracción. Devuelve 422 si nunca aparece dentro de wait_for_selector_timeout. Útil para SPAs que hidratan el contenido después de la carga. --
wait_for_selector_timeout integer No 10000 Milisegundos de espera para wait_for_selector (máximo 60000). --
block_ads boolean No false Aborta las solicitudes a dominios conocidos de anuncios/rastreadores para que nunca se carguen ni ralenticen la extracción. --
block_media boolean No false Aborta por completo las solicitudes de imágenes y audio/vídeo para un renderizado más rápido y ligero. A diferencia de load_media (que solo controla la espera), esto evita por completo que los medios se descarguen. --

Autenticación y solicitudes personalizadas#

Parameter Type Required Default Description Plan Gating
auth object No null Credenciales de HTTP Basic Auth para la URL de destino. Formato: {"username": "...", "password": "..."}. No se puede usar junto con un encabezado personalizado Authorization. Requiere acceso a autenticación básica
cookies array No null Array de objetos de cookies para inyectar antes de la navegación. Máximo 50 cookies. Cada cookie debe tener name, value, y domain o url. Requiere acceso a autenticación básica
headers object No null Diccionario de encabezados HTTP personalizados que se envían con cada solicitud a la URL de destino. Máximo 20 encabezados. Encabezados bloqueados: host, content-length, transfer-encoding, connection, upgrade, te, trailer. Requiere acceso a autenticación básica
No admitido: Los parámetros single_page y pdf_options del endpoint url-to-pdf se aceptan por paridad en la forma de la solicitud, pero no tienen efecto en la salida Markdown. Markdown no tiene concepto de páginas, márgenes ni orientación.

Cada elemento del array cookies debe seguir esta estructura:

Field Type Required Default Description
name string -- Nombre de la cookie.
value string -- Valor de la cookie.
domain string Condicional -- Dominio de la cookie. Se debe proporcionar domain o url.
url string Condicional -- URL con la que asociar la cookie. Se debe proporcionar domain o url.
path string No "/" Ruta de la cookie. El valor predeterminado es "/" cuando se define domain.

Respuesta#

Síncrono con descarga directa (direct_download=true)#

Clave privada -- devuelve los bytes Markdown sin procesar:

HTTP 200 OK
Content-Type: text/markdown; charset=utf-8
Content-Disposition: inline; filename="example_20260421_123456789.md"
X-Object-Key: env/files/{project_id}/url-to-markdown/example_20260421_123456789.md
X-File-Size: 8421
X-Conversion-Time: 6.3
X-Filename: example_20260421_123456789.md

(UTF-8 Markdown with YAML frontmatter)

Clave pública -- devuelve JSON con una URL prefirmada:

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/url-to-markdown/example_20260421_123456789.md",
    "filename": "example_20260421_123456789.md",
    "file_size": 8421,
    "conversion_time_seconds": 6.3,
    "job_id": "client-provided-id"
}

Síncrono sin descarga directa (direct_download=false)#

Disponible solo con claves privadas.

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/url-to-markdown/example_20260421_123456789.md",
    "filename": "example_20260421_123456789.md",
    "file_size": 8421,
    "conversion_time_seconds": 6.3
}

Modo asíncrono#

Devuelve una respuesta inmediata con un batch_id para consultar el estado (polling).

HTTP 202 Accepted
{
    "status": "processing",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "url_count": 5,
    "output_format": "individual"
}

Cuando output_format=true (agrupación en ZIP):

{
    "status": "processing",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "url_count": 5,
    "output_format": "zip"
}

Consulta del estado del job (solo claves públicas)#

Para recuperación ante timeout con clave pública:

GET /v1/convert/status/{job_id}
Authorization: Bearer <jwt_token>
Status Response
Procesando {"status": "processing"}
Correcto {"status": "success", "presigned_url": "...", "object_key": "..."}
Fallido {"status": "failed", "error": "..."}

Consulta del estado de lote (solo claves privadas)#

Para jobs de lote asíncronos, consulta el estado usando el batch_id de la respuesta 202:

GET /v1/convert/batch/{batch_id}
X-API-Key: sk_your_private_key

Devuelve el estado agregado, el estado por cada URL y las URLs de descarga prefirmadas. Consulta Consulta del estado de lote para ver el esquema completo de la respuesta.

Payload del callback de webhook#

Cuando se proporciona un callback_url, EnConvert envía una solicitud POST a esa URL al finalizar.

Job de una sola URL:

{
    "job_id": "activity_id",
    "status": "success",
    "batch_id": "...",
    "gcs_uri": "object_key",
    "filename": "example_20260421_123456789.md",
    "file_size": 8421
}

Job de lote:

{
    "job_id": "activity_id",
    "status": "success",
    "batch_id": "...",
    "total_tasks": 10,
    "successful_tasks": 8,
    "failed_tasks": 2,
    "tasks": [
        {"url": "https://example.com/page1", "status": "success", "filename": "page1.md"},
        {"url": "https://example.com/page2", "status": "failed", "filename": null}
    ]
}

Formato de salida#

Todo archivo Markdown comienza con un bloque de metadatos YAML frontmatter, seguido del cuerpo del artículo extraído.

---
url: https://example.com/articles/my-post
title: My Post Title
description: A short summary from the meta description or og:description tag.
links:
  - url: https://example.com/related
    text: Related article
  - url: https://example.com/about
    text: About the author
images:
  - url: https://example.com/hero.jpg
    alt: Hero image alt text
  - url: https://example.com/diagram.png
    alt: Architecture diagram
---

# My Post Title

Opening paragraph of the article body, converted to GitHub-Flavored Markdown...

## A Section Heading

- List item one
- List item two

\`\`\`python
def example():
    return "code blocks are fenced with language hints"
\`\`\`

[A link in the body](https://example.com/linked-page)

![An image in the body](https://example.com/inline-image.png)

Campos del frontmatter#

Field Type Description
url string La URL final después de redirecciones (no siempre es la URL que enviaste).
title string El título de la página desde <title>, con reserva al título corto detectado por Readability.
description string El valor de <meta name="description">, con reserva a <meta property="og:description">.
links array Todos los <a href> encontrados en la página, con URLs absolutas y el texto visible del enlace.
images array Todas las <img src> encontradas en la página, con URLs absolutas y texto alt.

Convenciones de Markdown#

  • Estilo de encabezado: ATX (#, ##, ###)
  • Viñetas de lista: -
  • Énfasis: *bold*, *italic* con * y _ escapados en texto literal
  • Saltos de línea suaves: dos espacios al final (se conservan en la salida)
  • Bloques de código: delimitados (```) con pistas de lenguaje detectadas a partir de class="language-xxx", class="lang-xxx", class="highlight-source-xxx", data-lang y data-language
  • Enlaces: [text](url) cuando hay texto de anclaje, forma de autolink <url> cuando el anclaje está vacío; los enlaces solo de anclaje (#foo) y javascript: se convierten en texto plano
  • Imágenes: ![alt](src), conservando title cuando está presente, con reserva a data-src cuando falta src (imágenes de carga diferida)
  • Reglas horizontales: ---

Funcionalidades#

Extracción de contenido limpio#

EnConvert usa el algoritmo Readability (la misma biblioteca que impulsa Firefox Reader View) para aislar el contenido principal del artículo del resto de la página, y luego aplica una segunda pasada de posprocesamiento para producir Markdown limpio.

Eliminado antes de la conversión:

  • Navegación (<nav>), pies de página (<footer>), barras laterales (<aside>)
  • Scripts (<script>, <noscript>), estilos (<style>), iframes, formularios, botones
  • SVG en línea, canvas y elementos template
  • Los atributos style, class, id y todos los manejadores de eventos on*

Conservado:

  • Encabezados, párrafos, listas, tablas, citas en bloque, bloques de código
  • Enlaces con su href y texto de anclaje (URLs absolutas)
  • Imágenes con alt, title y src absoluto
  • Figures y figcaptions (las imágenes en línea se mantienen dentro de estos)

Modo de captura limpia#

Antes de la extracción, la página se renderiza en un navegador real y se limpia de la misma forma que en url-to-pdf:

  • Banners de consentimiento de cookies -- Se cierran automáticamente en la página principal y en los iframes (OneTrust, Cookiebot, Didomi, Usercentrics y banners genéricos).
  • Cierre de modales y popups -- Los overlays se cierran mediante la tecla Escape, botones de cierre ARIA, botones de cierre basados en clases y botones de diálogo basados en roles.
  • Revelado de animaciones de scroll -- Fuerza la visibilidad de elementos ocultos por WOW.js, AOS, ScrollReveal, GSAP ScrollTrigger y clases de animación genéricas.
  • Gestión de encabezados sticky -- Se detectan los encabezados sticky/fijos y la página se desplaza de nuevo hasta arriba para preservar el orden del contenido.

Resolución de URLs absolutas#

Todos los href y src relativos del artículo extraído se resuelven contra la URL final de la página (después de redirecciones), de modo que la salida Markdown siempre contiene enlaces absolutos y clicables, algo útil para los pipelines de ingesta LLM que, de lo contrario, verían rutas relativas rotas.

Los enlaces solo de anclaje (#section), los enlaces javascript:, mailto: y tel: no se reescriben. Los enlaces solo de anclaje y javascript: se convierten en texto plano porque no tienen significado fuera de la página original.

Detección del lenguaje de bloques de código#

Los bloques de código se delimitan con una pista de lenguaje detectada cuando es posible:

<pre><code class="language-python">...</code></pre>    →   ```python
<pre data-lang="js">...</pre>                          →   ```js
<pre><code class="highlight-source-shell">...</code></pre> →   ```shell

Se reconocen las clases que coinciden con language-*, lang-*, highlight-source-* y brush:*, además de los atributos data-lang y data-language tanto en <pre> como en su <code> anidado. Si no se encuentra ninguna pista, el bloque se delimita sin etiqueta de lenguaje.

Autenticación básica HTTP#

Pasa auth con username y password para convertir páginas protegidas con HTTP Basic Authentication.

{
    "url": "https://staging.example.com/docs/article",
    "auth": {
        "username": "admin",
        "password": "secret"
    }
}

Inyección de cookies#

Inyecta hasta 50 cookies antes de que se cargue la página. Útil para convertir páginas de artículos exclusivas para miembros o específicas de una configuración regional (locale).

{
    "url": "https://example.com/members/post",
    "cookies": [
        {"name": "session_id", "value": "abc123", "domain": "example.com"},
        {"name": "locale", "value": "en-US", "domain": "example.com"}
    ]
}

Encabezados personalizados#

Envía hasta 20 encabezados HTTP personalizados con cada solicitud a la página de destino.

{
    "url": "https://example.com/api-docs",
    "headers": {
        "X-Custom-Token": "my-token-value",
        "Accept-Language": "en-US"
    }
}

Carga diferida de imágenes#

Cuando load_media y enable_scroll están habilitados (ambos con valor predeterminado true), el conversor desplaza la página lentamente para activar los cargadores de carga diferida y luego espera a que todas las imágenes terminen de cargar antes de capturar el HTML final. Esto garantiza que los valores data-src se hayan promovido a valores src reales y que la lista images del frontmatter esté completa.

Configura load_media=false para una extracción más rápida cuando solo necesitas el cuerpo de texto. En la salida pueden quedar valores src de marcador de posición.

Funcionalidades adicionales de renderizado#

  • Normalización de unidades de viewport -- Las unidades de viewport de CSS (vh, svh, lvh, dvh) se convierten en valores de píxeles fijos antes de la extracción.
  • Modo sigiloso (stealth) -- Enmascaramiento de la huella digital del navegador para evitar la detección de bots en páginas protegidas.
  • Interceptación de popups -- Cierra automáticamente cualquier pestaña nueva del navegador o popup activado por la página.
  • Bypass de CSP -- Gestiona las restricciones de Content Security Policy y Trusted Types que, de lo contrario, bloquearían la manipulación de la página.

Restricciones según el plan de suscripción#

Feature Founding Indie Studio Enterprise
Conversión básica (una sola URL, síncrona)
Opciones de viewport y renderizado
Modo asíncrono No
Procesamiento por lotes (varias URLs) No
Agrupación de salida en ZIP No No
Callbacks de webhook No No
HTTP Basic Auth No
Inyección de cookies No
Encabezados personalizados No
Conversiones mensuales 100 Según el plan Según el plan Ilimitado
Límite de tamaño de lote 0 Según el plan Según el plan Ilimitado
Retención de archivos 1 hora Según el plan Según el plan Según el plan

Modo asíncrono#

El modo asíncrono es útil para conversiones de larga duración o cuando se convierten varias URLs.

Cómo funciona#

  1. Envía una solicitud con async_mode=true (o pasa varias URLs, lo que habilita el modo asíncrono automáticamente).
  2. La API devuelve HTTP 202 inmediatamente con un batch_id y un url_count.
  3. Cada URL se convierte en segundo plano, se sube al almacenamiento y se rastrea individualmente.
  4. Supervisa la finalización mediante consulta del estado de lote, notificación por correo o callback de webhook.

Notificación por correo#

De forma predeterminada, se envía un correo de finalización a la dirección de correo del propietario del proyecto. Anúlalo con notification_email:

{
    "url": ["https://example.com/page1", "https://example.com/page2"],
    "async_mode": true,
    "notification_email": "[email protected]"
}

Callback de webhook#

Proporciona un callback_url para recibir una notificación POST automática al finalizar:

{
    "url": ["https://example.com/page1", "https://example.com/page2"],
    "async_mode": true,
    "callback_url": "https://your-server.com/webhook/enconvert"
}

El webhook se envía con un timeout de 30 segundos y considera que la entrega fue exitosa con los códigos HTTP 200, 201, 202 y 204.


Procesamiento por lotes y en masa#

Convierte varias URLs en una sola solicitud. Requiere modo asíncrono y una clave privada.

Salida individual (predeterminada)#

Cada URL genera un archivo Markdown independiente:

{
    "url": [
        "https://example.com/post-1",
        "https://example.com/post-2",
        "https://example.com/post-3"
    ],
    "async_mode": true
}

Salida en paquete ZIP#

Agrupa todos los archivos Markdown en un único archivo ZIP:

{
    "url": [
        "https://example.com/post-1",
        "https://example.com/post-2",
        "https://example.com/post-3"
    ],
    "async_mode": true,
    "output_format": true,
    "output_filename": "blog-archive"
}

El archivo ZIP se nombra {output_filename}_{timestamp}.zip o batch_{timestamp}.zip si no se proporciona un nombre personalizado.


Ejemplos de código#

Python (clave privada)#

import requests

response = requests.post(
    "https://api.enconvert.com/v1/convert/url-to-markdown",
    headers={"X-API-Key": "sk_your_private_key"},
    json={
        "url": "https://example.com/articles/my-post",
        "direct_download": True
    }
)

response.raise_for_status()
markdown_text = response.content.decode("utf-8")
print(markdown_text)

PHP (clave privada)#

$ch = curl_init("https://api.enconvert.com/v1/convert/url-to-markdown");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: sk_your_private_key"
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "url" => "https://example.com/articles/my-post"
    ])
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
echo $data["presigned_url"];

Node.js (clave privada)#

const response = await fetch("https://api.enconvert.com/v1/convert/url-to-markdown", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-API-Key": "sk_your_private_key"
    },
    body: JSON.stringify({
        url: "https://example.com/articles/my-post"
    })
});

const data = await response.json();
console.log(data.presigned_url);

Go (clave privada)#

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]interface{}{
        "url": "https://example.com/articles/my-post",
    })

    req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/url-to-markdown", bytes.NewBuffer(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", "sk_your_private_key")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    respBody, _ := io.ReadAll(resp.Body)
    fmt.Println(string(respBody))
}

JavaScript -- navegador (clave pública)#

// Step 1: Get a JWT token
const tokenRes = await fetch("https://api.enconvert.com/v1/auth/token", {
    method: "POST",
    headers: { "X-API-Key": "pk_your_public_key" }
});
const { token } = await tokenRes.json();

// Step 2: Convert URL to Markdown (public keys receive raw bytes)
const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-markdown", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${token}`
    },
    body: JSON.stringify({
        url: "https://example.com/articles/my-post"
    })
});

const markdown = await convertRes.text();
console.log(markdown);

React (clave pública)#

import { useState } from "react";

function UrlToMarkdown() {
    const [loading, setLoading] = useState(false);
    const [markdown, setMarkdown] = useState("");

    async function convertUrl() {
        setLoading(true);
        try {
            // Get JWT token
            const tokenRes = await fetch("https://api.enconvert.com/v1/auth/token", {
                method: "POST",
                headers: { "X-API-Key": "pk_your_public_key" }
            });
            const { token } = await tokenRes.json();

            // Convert
            const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-markdown", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `Bearer ${token}`
                },
                body: JSON.stringify({ url: "https://example.com/articles/my-post" })
            });

            setMarkdown(await convertRes.text());
        } finally {
            setLoading(false);
        }
    }

    return (
        <div>
            <button onClick={convertUrl} disabled={loading}>
                {loading ? "Converting..." : "Convert to Markdown"}
            </button>
            {markdown && <pre>{markdown}</pre>}
        </div>
    );
}

export default UrlToMarkdown;

Respuestas de error#

Status Condition
400 Bad Request Falta el parámetro url o está vacío
400 Bad Request output_format=true con una sola URL (requiere varias URLs)
400 Bad Request direct_download=true con varias URLs
400 Bad Request direct_download=true con async_mode=true
400 Bad Request Objeto auth inválido (falta username o password)
400 Bad Request cookies inválido (no es un array, supera las 50 entradas, faltan campos obligatorios)
400 Bad Request headers inválido (no es un objeto, supera las 20 entradas, nombres de encabezado bloqueados, valores que no son strings)
400 Bad Request Conflicto entre auth y el encabezado personalizado Authorization
400 Bad Request Clave pública intentando usar varias URLs
401 Unauthorized Falta la clave de API / token JWT, o es inválido
402 Payment Required Se agotó la cuota mensual de ops
402 Payment Required El lote superaría la cuota mensual de ops restante
402 Payment Required Se alcanzó el límite de almacenamiento
403 Forbidden El endpoint no está entre los endpoints permitidos de la clave de API
403 Forbidden Funcionalidad no disponible en el plan actual (asíncrono, webhook, ZIP, autenticación básica)
403 Forbidden El tamaño del lote supera el límite de lote del plan
404 Not Found No se encontró el ID de job (al consultar el estado)
500 Internal Server Error La conversión falló (fallo del navegador, error de navegación, fallo en la extracción)

Límites#

Limit Value
Timeout de navegación de página 60 segundos
Timeout de carga por imagen 5 segundos
Timeout de cierre de banner de cookies 3 segundos
Máximo de cookies por solicitud 50
Máximo de encabezados personalizados por solicitud 20
Operaciones mensuales Según el plan (Founding: 500)
Tamaño de lote Según el plan (Founding: deshabilitado)
Retención de archivos Según el plan (Founding: 1 hora)
Timeout de entrega de webhook 30 segundos

Preguntas frecuentes#

¿Cómo convierto una página web a Markdown con una API REST?#

Envía una solicitud POST a /v1/convert/url-to-markdown con un url en el cuerpo JSON y tu clave en el encabezado X-API-Key. Recibes una respuesta JSON con un presigned_url al archivo Markdown, o los bytes Markdown UTF-8 sin procesar cuando defines direct_download=true.

¿Puedo convertir páginas web a Markdown para pipelines de LLM y RAG?#

Sí. La salida está diseñada para la ingesta de LLM. El algoritmo Readability (la misma biblioteca detrás de Firefox Reader View) aísla el artículo principal, se elimina el contenido superfluo como <nav>, <footer>, scripts y formularios, todos los enlaces e imágenes relativos se resuelven a URLs absolutas, y un bloque YAML frontmatter incluye url, title, description, links e images de la página.

¿Puedo convertir varias URLs a Markdown en una sola solicitud a la API?#

Sí. Pasa un array de URLs en url con async_mode=true (requiere una clave privada y un plan con acceso a lotes); la API devuelve HTTP 202 con un batch_id que consultas mediante GET /v1/convert/batch/{batch_id}. Define output_format=true para agrupar todos los archivos Markdown en un único archivo ZIP.

¿Por qué algunas imágenes en mi salida Markdown tienen valores src de marcador de posición?#

Esto ocurre cuando load_media=false. La extracción es más rápida, pero las imágenes con carga diferida pueden conservar valores src de marcador de posición. Mantén load_media y enable_scroll en su valor predeterminado true para que la página se desplace y active los cargadores de carga diferida, y para que todas las imágenes terminen de cargar (timeout de 5 segundos por imagen) antes de la captura.

¿Funciona la API de URL a Markdown en páginas que requieren inicio de sesión?#

Sí, en planes con acceso a autenticación básica: pasa auth con username y password para HTTP Basic Auth, inyecta hasta 50 cookies de sesión, o envía hasta 20 headers personalizados, algo útil para páginas de artículos exclusivas para miembros o de staging.