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...
Parametri della richiesta#
Parametri di primo livello#
| Parametro | Tipo | Obbligatorio | Predefinito | Descrizione | Limitazione per piano |
|---|---|---|---|---|---|
url |
string o string[] |
Sì | -- | 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 |
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.
Schema dell'oggetto cookie#
Ogni elemento dell'array cookies deve seguire questa struttura:
| Campo | Tipo | Obbligatorio | Predefinito | Descrizione |
|---|---|---|---|---|
name |
string |
Sì | -- | Nome del cookie. |
value |
string |
Sì | -- | 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)

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 daclass="language-xxx",class="lang-xxx",class="highlight-source-xxx",data-langedata-language - Link:
[text](url)quando è presente il testo di ancoraggio, forma autolink<url>quando l'ancora è vuota; i link solo-ancora (#foo) e i linkjavascript:vengono trasformati in testo semplice - Immagini:
, contitlepreservato quando presente, con fallback adata-srcquandosrcè 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,ide tutti gli attributi degli event handleron*
Preservato:
- Intestazioni, paragrafi, liste, tabelle, blockquote, blocchi di codice
- Link con il loro
hrefe testo di ancoraggio (URL assoluti) - Immagini con
alt,titleesrcassoluto - 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"
}
}
Iniezione di cookie#
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) | Sì | Sì | Sì | Sì |
| Opzioni di viewport e rendering | Sì | Sì | Sì | Sì |
| Modalità asincrona | No | Sì | Sì | Sì |
| Elaborazione batch (più URL) | No | Sì | Sì | Sì |
| Raggruppamento output ZIP | No | No | Sì | Sì |
| Callback webhook | No | No | Sì | Sì |
| HTTP Basic Auth | No | Sì | Sì | Sì |
| Iniezione di cookie | No | Sì | Sì | Sì |
| Header personalizzati | No | Sì | Sì | Sì |
| 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#
- Invia una richiesta con
async_mode=true(oppure passa più URL, che abilita automaticamente la modalità asincrona). - L'API restituisce immediatamente HTTP 202 con un
batch_ide unurl_count. - Ogni URL viene convertito in background, caricato nello storage e monitorato singolarmente.
- 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.