API da URL a Markdown#

L'endpoint POST /v1/convert/url-to-markdown converte qualsiasi pagina web pubblicamente accessibile in Markdown GitHub-Flavored pulito, con un blocco di metadati frontmatter YAML. Ogni pagina viene renderizzata in un browser reale, passata attraverso un estrattore di leggibilità che rimuove il boilerplate (navigazione, footer, aside, script, form, pulsanti), quindi serializzata in Markdown con link normalizzati, blocchi di codice delimitati e URL relativi risolti in assoluti. È esattamente ciò che serve alle pipeline di ingestione LLM e RAG al posto dell'HTML grezzo. Le conversioni vengono eseguite in modo sincrono o asincrono in batch, e i risultati vengono restituiti come byte Markdown grezzi o come URL di download prefirmato.


Endpoint#

POST /v1/convert/url-to-markdown

Content-Type: application/json

Formato di output: Markdown (.md, UTF-8) con un blocco frontmatter YAML in cima al file contenente i metadati della pagina. Il formato di output non è configurabile. Viene sempre prodotto Markdown con frontmatter YAML.


Autenticazione#

Questo endpoint supporta l'autenticazione sia con chiave privata che con chiave pubblica.

Chiave privata#

Includi la tua chiave segreta nell'header X-API-Key. Usala per chiamate server-to-server in cui la chiave non è mai esposta al client.

X-API-Key: sk_your_private_key

Chiave pubblica con JWT#

Per l'uso lato client, genera prima un token JWT usando la tua chiave pubblica, poi passalo come token Bearer.

Passo 1 -- Ottieni un token:

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

Passo 2 -- Usa il token:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Nota: Le richieste con chiave pubblica sono limitate a un singolo URL, alla modalità sincrona e al download diretto. La modalità asincrona, l'elaborazione batch, i webhook e le email di notifica non sono disponibili con le chiavi pubbliche.

Parametri della richiesta#

Parametri di primo livello#

Parametro Tipo Obbligatorio Predefinito Descrizione Limitazione per piano
url string o string[] -- Una singola stringa URL o un array di URL da convertire. Più URL richiedono la modalità asincrona. --
async_mode boolean No false Esegue la conversione in modo asincrono. Restituisce immediatamente un batch_id per il polling. Obbligatorio per il batch (più URL). Richiede accesso asincrono
direct_download boolean No false Restituisce i byte Markdown grezzi nel corpo della risposta invece di una risposta JSON con un URL prefirmato. Forzato a true per le chiavi pubbliche. Incompatibile con async_mode e con più URL. --
output_format boolean No false Quando è true con più URL, raggruppa tutti i file Markdown di output in un unico archivio ZIP. Richiede più URL. Richiede accesso all'output ZIP
output_filename string No Generato automaticamente Nome file personalizzato per il file di output. L'estensione .md viene aggiunta automaticamente. Formato predefinito: {domain}_{timestamp}.md. --
job_id string No -- ID del job fornito dal client per il recupero in caso di timeout. Solo chiavi pubbliche. Quando una conversione sincrona supera i limiti di timeout del reverse proxy, il client può interrogare GET /v1/convert/status/{job_id} per recuperare il risultato. Ignorato per le chiavi private. --
notification_email string No Email del proprietario del progetto Indirizzo email da notificare al completamento di un job asincrono. Solo chiavi private. --
callback_url string No -- URL webhook che riceve una richiesta POST al completamento della conversione. Solo chiavi private. Richiede accesso ai webhook

Parametri del browser e del rendering#

Parametro Tipo Obbligatorio Predefinito Descrizione Limitazione per piano
viewport_width integer No 1920 Larghezza del viewport del browser in pixel. Influisce sui contenuti responsive e su quale variante di layout viene catturata prima dell'estrazione. --
viewport_height integer No 1080 Altezza del viewport del browser in pixel. Usata come riferimento per il rendering e per il calcolo delle unità viewport. --
load_media boolean No true Attende il caricamento completo di tutte le immagini e i video prima dell'estrazione. Quando è false, l'estrazione è più veloce ma le immagini con lazy-loading possono avere valori src segnaposto nell'output Markdown. --
enable_scroll boolean No true Scorre la pagina dall'alto verso il basso per attivare il contenuto con lazy-loading (loader basati su IntersectionObserver). --
handle_sticky_header boolean No true Rileva header sticky/fissi e riporta lo scroll in cima prima dell'estrazione, così l'ordine dei contenuti viene preservato correttamente. --
handle_cookies boolean No true Chiude automaticamente i banner di consenso cookie (OneTrust, Cookiebot, Didomi, Usercentrics e banner generici) prima dell'estrazione. --
wait_for_images boolean No true Attende che tutti gli elementi <img> finiscano di caricarsi (timeout di 5 secondi per immagine) in modo che il testo alt e i valori finali di src vengano catturati correttamente. --
wait_for_selector string No null Selettore CSS da attendere prima dell'estrazione. Restituisce 422 se non compare mai entro wait_for_selector_timeout. Utile per le SPA che idratano il contenuto dopo il caricamento. --
wait_for_selector_timeout integer No 10000 Millisecondi di attesa per wait_for_selector (massimo 60000). --
block_ads boolean No false Interrompe le richieste ai domini noti di pubblicità/tracker in modo che non vengano mai caricati o rallentino l'estrazione. --
block_media boolean No false Interrompe completamente le richieste di immagini e audio/video per un rendering più veloce e leggero. A differenza di load_media (che controlla solo l'attesa), questo impedisce del tutto il download dei media. --

Autenticazione e richieste personalizzate#

Parametro Tipo Obbligatorio Predefinito Descrizione Limitazione per piano
auth object No null Credenziali HTTP Basic Auth per l'URL di destinazione. Formato: {"username": "...", "password": "..."}. Non può essere usato insieme a un header personalizzato Authorization. Richiede accesso basic auth
cookies array No null Array di oggetti cookie da iniettare prima della navigazione. Massimo 50 cookie. Ogni cookie deve avere name, value e almeno uno tra domain o url. Richiede accesso basic auth
headers object No null Dizionario di header HTTP personalizzati inviati con ogni richiesta all'URL di destinazione. Massimo 20 header. Header bloccati: host, content-length, transfer-encoding, connection, upgrade, te, trailer. Richiede accesso basic auth
Non supportato: I parametri single_page e pdf_options dell'endpoint url-to-pdf sono accettati per mantenere la stessa forma della richiesta, ma non hanno alcun effetto sull'output Markdown. Markdown non ha alcun concetto di pagine, margini o orientamento.

Ogni elemento dell'array cookies deve seguire questa struttura:

Campo Tipo Obbligatorio Predefinito Descrizione
name string -- Nome del cookie.
value string -- Valore del cookie.
domain string Condizionale -- Dominio del cookie. Deve essere fornito almeno uno tra domain o url.
url string Condizionale -- URL da associare al cookie. Deve essere fornito almeno uno tra domain o url.
path string No "/" Percorso del cookie. Il valore predefinito è "/" quando domain è impostato.

Risposta#

Sincrona con download diretto (direct_download=true)#

Chiave privata -- restituisce byte Markdown grezzi:

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)

Chiave pubblica -- restituisce JSON con un URL prefirmato:

{
    "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"
}

Sincrona senza download diretto (direct_download=false)#

Disponibile solo con chiavi private.

{
    "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
}

Modalità asincrona#

Restituisce immediatamente un batch_id per il polling.

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

Quando output_format=true (raggruppamento ZIP):

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

Polling dello stato del job (solo chiavi pubbliche)#

Per il recupero in caso di timeout con chiave pubblica:

GET /v1/convert/status/{job_id}
Authorization: Bearer <jwt_token>
Stato Risposta
In elaborazione {"status": "processing"}
Successo {"status": "success", "presigned_url": "...", "object_key": "..."}
Fallito {"status": "failed", "error": "..."}

Polling dello stato del batch (solo chiavi private)#

Per i job batch asincroni, esegui il polling con il batch_id ricevuto nella risposta 202:

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

Restituisce lo stato aggregato, gli stati per singolo URL e gli URL di download prefirmati. Consulta Polling dello stato del batch per lo schema completo della risposta.

Payload di callback del webhook#

Quando viene fornito un callback_url, EnConvert invia una richiesta POST a quell'URL al completamento.

Job con singolo URL:

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

Job batch:

{
    "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 di output#

Ogni file Markdown inizia con un blocco frontmatter YAML contenente i metadati della pagina, seguito dal corpo dell'articolo estratto.

---
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)

Campi del frontmatter#

Campo Tipo Descrizione
url string L'URL finale dopo i redirect (non sempre l'URL che hai inviato).
title string Il titolo della pagina preso da <title>, con fallback al titolo breve rilevato da Readability.
description string Il valore di <meta name="description">, con fallback a <meta property="og:description">.
links array Ogni <a href> trovato sulla pagina, con URL assoluti e testo di ancoraggio visibile.
images array Ogni <img src> trovato sulla pagina, con URL assoluti e testo alt.

Convenzioni Markdown#

  • Stile delle intestazioni: ATX (#, ##, ###)
  • Punti elenco: -
  • Enfasi: *bold*, *italic* con * e _ escaped nel testo letterale
  • Interruzioni di riga leggere: due spazi finali (preservati nell'output)
  • Blocchi di codice: delimitati (```) con suggerimenti di linguaggio rilevati da class="language-xxx", class="lang-xxx", class="highlight-source-xxx", data-lang e data-language
  • Link: [text](url) quando è presente il testo di ancoraggio, forma autolink <url> quando l'ancora è vuota; i link solo-ancora (#foo) e i link javascript: vengono trasformati in testo semplice
  • Immagini: ![alt](src), con title preservato quando presente, con fallback a data-src quando src è assente (immagini con lazy-loading)
  • Linee orizzontali: ---

Funzionalità#

Estrazione pulita dei contenuti#

EnConvert usa l'algoritmo Readability (la stessa libreria che alimenta Firefox Reader View) per isolare il contenuto principale dell'articolo dal resto della pagina, poi applica un secondo passaggio di post-elaborazione per produrre Markdown pulito.

Rimosso prima della conversione:

  • Navigazione (<nav>), footer (<footer>), aside (<aside>)
  • Script (<script>, <noscript>), stili (<style>), iframe, form, pulsanti
  • SVG inline, canvas ed elementi template
  • Gli attributi style, class, id e tutti gli attributi degli event handler on*

Preservato:

  • Intestazioni, paragrafi, liste, tabelle, blockquote, blocchi di codice
  • Link con il loro href e testo di ancoraggio (URL assoluti)
  • Immagini con alt, title e src assoluto
  • Figure e figcaption (le immagini inline vengono mantenute al loro interno)

Modalità di cattura pulita#

Prima dell'estrazione, la pagina viene renderizzata in un browser reale e ripulita nello stesso modo di url-to-pdf:

  • Banner di consenso cookie -- Chiusi automaticamente sulla pagina principale e negli iframe (OneTrust, Cookiebot, Didomi, Usercentrics e banner generici).
  • Chiusura di modali e popup -- Overlay chiusi tramite tasto Escape, pulsanti di chiusura ARIA, pulsanti di chiusura basati su classe e pulsanti di dialogo basati su role.
  • Rivelazione delle animazioni allo scroll -- Forza la visibilità degli elementi nascosti da WOW.js, AOS, ScrollReveal, GSAP ScrollTrigger e classi di animazione generiche.
  • Gestione degli header sticky -- Gli header sticky/fissi vengono rilevati e la pagina viene riportata in cima in modo da preservare l'ordine dei contenuti.

Risoluzione degli URL assoluti#

Ogni href e src relativo nell'articolo estratto viene risolto rispetto all'URL finale della pagina (dopo i redirect), quindi l'output Markdown contiene sempre link assoluti e cliccabili, il che è utile per le pipeline di ingestione LLM che altrimenti vedrebbero percorsi relativi non funzionanti.

I link solo-ancora (#section), i link javascript:, mailto: e tel: non vengono riscritti. I link solo-ancora e javascript: vengono trasformati in testo semplice perché non hanno significato al di fuori della pagina originale.

Rilevamento del linguaggio dei blocchi di codice#

I blocchi di codice vengono delimitati con un suggerimento di linguaggio rilevato, quando possibile:

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

Vengono riconosciute le classi corrispondenti a language-*, lang-*, highlight-source-* e brush:*, oltre agli attributi data-lang e data-language sia su <pre> che sul suo <code> annidato. Se non viene trovato alcun suggerimento, il blocco viene delimitato senza etichetta di linguaggio.

HTTP Basic Auth#

Passa auth con username e password per convertire pagine protette da HTTP Basic Authentication.

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

Inietta fino a 50 cookie prima del caricamento della pagina. Utile per convertire pagine di articoli riservate ai membri o specifiche per una determinata lingua/area geografica.

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

Header personalizzati#

Invia fino a 20 header HTTP personalizzati con ogni richiesta alla pagina di destinazione.

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

Caricamento lazy delle immagini#

Quando load_media e enable_scroll sono abilitati (entrambi hanno come valore predefinito true), il convertitore scorre la pagina lentamente per attivare i loader lazy, poi attende che tutte le immagini finiscano di caricarsi prima di catturare l'HTML finale. Questo garantisce che i valori data-src siano stati promossi a valori src reali e che l'elenco images del frontmatter sia completo.

Imposta load_media=false per un'estrazione più veloce quando ti serve solo il corpo testuale. Nell'output potrebbero però rimanere valori src segnaposto.

Funzionalità di rendering aggiuntive#

  • Normalizzazione delle unità viewport -- Le unità viewport CSS (vh, svh, lvh, dvh) vengono convertite in valori fissi in pixel prima dell'estrazione.
  • Modalità stealth -- Mascheramento del fingerprint del browser per evitare il rilevamento bot su pagine protette.
  • Intercettazione dei popup -- Chiude automaticamente eventuali nuove schede del browser o popup attivati dalla pagina.
  • Bypass CSP -- Gestisce le restrizioni di Content Security Policy e Trusted Types che altrimenti bloccherebbero la manipolazione della pagina.

Limitazioni per piano di abbonamento#

Funzionalità Founding Indie Studio Enterprise
Conversione di base (singolo URL, sincrona)
Opzioni di viewport e rendering
Modalità asincrona No
Elaborazione batch (più URL) No
Raggruppamento output ZIP No No
Callback webhook No No
HTTP Basic Auth No
Iniezione di cookie No
Header personalizzati No
Conversioni mensili 100 In base al piano In base al piano Illimitate
Limite dimensione batch 0 In base al piano In base al piano Illimitato
Conservazione dei file 1 ora In base al piano In base al piano In base al piano

Modalità asincrona#

La modalità asincrona è utile per conversioni di lunga durata o quando si convertono più URL.

Come funziona#

  1. Invia una richiesta con async_mode=true (oppure passa più URL, che abilita automaticamente la modalità asincrona).
  2. L'API restituisce immediatamente HTTP 202 con un batch_id e un url_count.
  3. Ogni URL viene convertito in background, caricato nello storage e monitorato singolarmente.
  4. Monitora il completamento tramite polling dello stato del batch, notifica email o callback webhook.

Notifica email#

Per impostazione predefinita, viene inviata un'email di completamento all'indirizzo email del proprietario del progetto. Sovrascrivi con notification_email:

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

Callback webhook#

Fornisci un callback_url per ricevere una notifica POST automatica al completamento:

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

Il webhook viene inviato con un timeout di 30 secondi e considera HTTP 200, 201, 202 e 204 come consegna riuscita.


Elaborazione batch e in blocco#

Converti più URL in un'unica richiesta. Richiede la modalità asincrona e una chiave privata.

Output individuale (predefinito)#

Ogni URL produce un file Markdown separato:

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

Output raggruppato in ZIP#

Raggruppa tutti i file Markdown in un unico archivio 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"
}

Il file ZIP viene chiamato {output_filename}_{timestamp}.zip oppure batch_{timestamp}.zip se non viene fornito alcun nome personalizzato.


Esempi di codice#

Python (chiave privata)#

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 (chiave privata)#

$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 (chiave privata)#

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 (chiave privata)#

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 -- Browser (chiave pubblica)#

// 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 (chiave pubblica)#

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;

Risposte di errore#

Stato Condizione
400 Bad Request Parametro url mancante o vuoto
400 Bad Request output_format=true con un singolo URL (richiede più URL)
400 Bad Request direct_download=true con più URL
400 Bad Request direct_download=true con async_mode=true
400 Bad Request Oggetto auth non valido (username o password mancanti)
400 Bad Request cookies non valido (non è un array, supera le 50 voci, campi obbligatori mancanti)
400 Bad Request headers non valido (non è un oggetto, supera le 20 voci, nomi di header bloccati, valori non stringa)
400 Bad Request Conflitto tra auth e l'header personalizzato Authorization
400 Bad Request Chiave pubblica che tenta di usare più URL
401 Unauthorized Chiave API / token JWT mancante o non valido
402 Payment Required Quota mensile di ops esaurita
402 Payment Required Il batch supererebbe la quota mensile di ops residua
402 Payment Required Limite di storage raggiunto
403 Forbidden Endpoint non incluso tra quelli consentiti dalla chiave API
403 Forbidden Funzionalità non disponibile nel piano attuale (asincrono, webhook, ZIP, basic auth)
403 Forbidden La dimensione del batch supera il limite del piano
404 Not Found ID del job non trovato (durante il polling dello stato)
500 Internal Server Error Conversione fallita (crash del browser, errore di navigazione, errore di estrazione)

Limiti#

Limite Valore
Timeout di navigazione pagina 60 secondi
Timeout di caricamento per immagine 5 secondi
Timeout di chiusura banner cookie 3 secondi
Numero massimo di cookie per richiesta 50
Numero massimo di header personalizzati per richiesta 20
Operazioni mensili Dipende dal piano (Founding: 500)
Dimensione batch Dipende dal piano (Founding: disabilitato)
Conservazione dei file Dipende dal piano (Founding: 1 ora)
Timeout di consegna webhook 30 secondi

Domande frequenti#

Come converto una pagina web in Markdown con una REST API?#

Invia una richiesta POST a /v1/convert/url-to-markdown con un url nel corpo JSON e la tua chiave nell'header X-API-Key. Ricevi come risposta un JSON con un presigned_url verso il file Markdown, oppure i byte Markdown UTF-8 grezzi se imposti direct_download=true.

Posso convertire pagine web in Markdown per pipeline LLM e RAG?#

Sì. L'output è pensato per l'ingestione LLM. L'algoritmo Readability (la stessa libreria dietro Firefox Reader View) isola l'articolo principale, il boilerplate come <nav>, <footer>, script e form viene rimosso, ogni link e URL immagine relativo viene risolto in un URL assoluto, e un blocco frontmatter YAML porta con sé url, title, description, links e images della pagina.

Posso convertire più URL in Markdown in un'unica richiesta API?#

Sì. Passa un array di URL in url con async_mode=true (richiede una chiave privata e un piano con accesso al batch); l'API restituisce HTTP 202 con un batch_id che interroghi tramite GET /v1/convert/batch/{batch_id}. Imposta output_format=true per raggruppare tutti i file Markdown in un unico archivio ZIP.

Perché alcune immagini nel mio output Markdown hanno valori src segnaposto?#

Succede quando load_media=false. L'estrazione è più veloce, ma le immagini con lazy-loading possono mantenere valori src segnaposto. Mantieni load_media e enable_scroll sul valore predefinito true in modo che la pagina venga scorsa per attivare i loader lazy e che ogni immagine finisca di caricarsi (timeout di 5 secondi per immagine) prima della cattura.

L'API da URL a Markdown funziona su pagine protette da login?#

Sì, sui piani con accesso basic auth: passa auth con username e password per l'HTTP Basic Auth, inietta fino a 50 cookies di sessione, oppure invia fino a 20 headers personalizzati, il che è utile per pagine di articoli riservate ai membri o in staging.