API Anything to Markdown#

L'endpoint POST /v1/convert/anything-to-markdown converte quasi ogni documento caricato — file PDF, Word, PowerPoint, Excel, CSV, HTML, EPUB, testo semplice e OpenDocument — in Markdown pulito e strutturato per intestazioni. Rileva automaticamente il formato dal file che invii, lo instrada all'estrattore giusto e restituisce un unico file .md con la struttura di cui le pipeline LLM e RAG hanno davvero bisogno: vere intestazioni #/##/###, tabelle pipe GitHub-Flavored, blocchi di codice recintati e link risolti. È la controparte per file di url-to-markdown, e lo stesso convertitore alimenta l'ingestione di file nell'endpoint di ingest — quindi il Markdown che ottieni qui è esattamente ciò che il chunker semantico consuma.

Un solo endpoint sostituisce uno stack di librerie specifiche per formato (pdfplumber, mammoth, python-pptx, openpyxl): carichi un file, ottieni Markdown, lo passi ai tuoi embedding.


Endpoint#

POST /v1/convert/anything-to-markdown

Content-Type: multipart/form-data

Formato di output: Markdown (.md, UTF-8). Il formato viene rilevato automaticamente dall'estensione del nome del file caricato e dai suoi magic byte — non devi specificare un tipo di input.


Formati di input supportati#

Il tipo di input viene rilevato dall'estensione del file (validata rispetto ai magic byte del file). Questi sono tutti i formati che l'endpoint accetta:

Categoria Formati Estensioni Note
PDF PDF .pdf Intestazioni dedotte dalla dimensione del font; tabelle estratte come tabelle pipe; intestazioni/piè di pagina ricorrenti deduplicati. I PDF scansionati o solo immagine non hanno un livello di testo e vengono rifiutati — l'OCR non viene eseguito.
Word DOCX, DOC .docx, .doc Gli stili di intestazione di Word diventano #/##/###; elenchi e tabelle preservati. Il formato .doc (legacy) è gestito tramite LibreOffice.
Presentazioni PPTX, PPT .pptx, .ppt Una sezione ## Slide N per diapositiva, elenchi puntati del corpo, tabelle e note del relatore. .ppt (legacy) tramite LibreOffice.
Fogli di calcolo XLSX, XLS, CSV .xlsx, .xls, .csv Un'intestazione ## SheetName più una tabella GFM per foglio. I valori delle celle sono mantenuti alla lettera (zeri iniziali e codici non vengono riformattati).
E-book EPUB .epub Capitoli concatenati nell'ordine di lettura (spine); il documento indice/navigazione viene saltato.
Web / markup HTML, XHTML .html, .htm, .xhtml Conversione fedele dell'intero documento (non estrazione del solo articolo).
OpenDocument ODT, ODS, ODP .odt, .ods, .odp Documenti di testo, foglio di calcolo e presentazione, tramite LibreOffice.
Testo formattato RTF .rtf Convertito tramite LibreOffice.
Testo semplice Text, Markdown .txt, .text, .md, .markdown, .mdown, .mkd Passthrough con codifica normalizzata (Markdown è già output valido).
Nota: Le immagini (.png, .jpg e simili) non sono ancora supportate su questo endpoint — l'OCR delle immagini richiede una pipeline separata e soggetta a costi. Il caricamento di un'immagine restituisce un 400 con un messaggio chiaro. Per convertire una pagina web in Markdown invece di un file, usa url-to-markdown.

Autenticazione#

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

Chiave privata#

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

X-API-Key: sk_live_your_private_key

Chiave pubblica con JWT#

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

Passo 1 -- Ottieni un token:

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

Passo 2 -- Usa il token:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Il flusso completo, incluso il blocco per dominio e il refresh del token, è descritto nella guida all'autenticazione. Ogni chiave API contiene una allowlist di endpoint consentiti — se /v1/convert/anything-to-markdown non è nell'elenco della chiave, la richiesta viene rifiutata con 403.


Parametri della richiesta#

Invia il file come multipart/form-data. Il documento va nel campo file; gli altri sono campi form opzionali.

Parametro Tipo Obbligatorio Predefinito Descrizione
file file -- Il documento da convertire. La sua estensione deve essere uno dei formati di input supportati sopra.
output_filename string No Nome input Nome personalizzato per il file di output. L'estensione .md viene aggiunta automaticamente.
direct_download boolean No true Accettato per parità di forma della richiesta con gli altri endpoint di conversione.
job_id string No -- Job ID fornito dal client per il recupero in caso di timeout. Quando una conversione sincrona supera i limiti di timeout del reverse proxy, interroga GET /v1/convert/status/{job_id} per recuperare il risultato.

Risposta#

La conversione viene eseguita in-process e il file .md risultante viene archiviato, poi l'endpoint restituisce un corpo JSON con un URL di download pre-firmato:

{
    "presigned_url": "https://spaces.example.com/...signed...",
    "object_key": "env/files/{project_id}/anything-to-markdown/report_20260714_101530123.md",
    "filename": "report_20260714_101530123.md",
    "file_size": 5124,
    "conversion_time_seconds": 1.8,
    "job_id": null
}

Gli stessi valori sono riportati negli header di risposta (X-Object-Key, X-File-Size, X-Conversion-Time, X-Filename) così puoi leggerli senza analizzare il corpo. Scarica il Markdown da presigned_url — il link ha vita breve.


Come viene convertito ciascun formato#

Ogni formato viene normalizzato nella stessa forma Markdown pulita, così il chunking e l'embedding a valle vedono una struttura coerente indipendentemente dalla sorgente.

  • PDF — Il testo viene estratto con posizionamento a livello di parola. La dimensione del font più comune è trattata come testo del corpo; le dimensioni maggiori diventano intestazioni #/##/### (dalla più grande). Le tabelle vengono rilevate geometricamente ed emesse come tabelle pipe GFM, e il loro testo viene rimosso dal flusso di prosa così nulla viene duplicato. Le righe che si ripetono sulla maggior parte delle pagine (intestazioni/piè di pagina ricorrenti) vengono scartate. Un PDF senza livello di testo (una scansione o un export solo immagine) viene rifiutato con un chiaro 400 — questo endpoint non esegue OCR.
  • DOCX / DOC — Gli stili di paragrafo "Heading 1/2/3" di Word si mappano in modo netto su #/##/###; elenchi, tabelle, grassetto e corsivo sono preservati. Il formato .doc legacy viene prima instradato attraverso LibreOffice.
  • PPTX / PPT — Ogni diapositiva diventa una sezione ## Slide N: Title, i segnaposto del corpo diventano elenchi puntati, le tabelle diventano tabelle pipe e le note del relatore vengono aggiunte come sottosezione ### Notes — così ogni diapositiva è un'unità indipendente e recuperabile.
  • XLSX / XLS / CSV — Ogni foglio di lavoro diventa un'intestazione ## SheetName più una tabella GFM; un CSV è una singola tabella. Le celle vengono lette come stringhe, così ID, codici e zeri iniziali sono preservati esattamente.
  • EPUB — I documenti di contenuto vengono letti nell'ordine spine (di lettura) e convertiti capitolo per capitolo; il documento di navigazione/indice viene saltato così da non inquinare i tuoi chunk.
  • HTML / XHTML — L'intero documento viene convertito fedelmente (non ridotto a un singolo "articolo"), con script/style/noscript rimossi e intestazioni, elenchi, tabelle, link e codice preservati.
  • ODT / ODS / ODP / RTF — Convertiti tramite lo stesso motore LibreOffice che alimenta gli endpoint document-to-PDF.
  • Text / Markdown — I fine riga e la codifica vengono normalizzati; un caricamento .md passa essenzialmente invariato.

Formato di output#

Il risultato è Markdown GitHub-Flavored costruito per il consumo da parte delle macchine:

  • Intestazioni — ATX (#, ##, ###), usate come confini semantici delle sezioni.
  • Tabelle — Tabelle pipe GFM (mantenute atomiche, mai divise), con i | nelle celle preceduti da escape.
  • Codice — Blocchi recintati con indicazione del linguaggio dove rilevabile.
  • Struttura — Paragrafi, elenchi e citazioni preservati; le sezioni per diapositiva e per foglio danno confini reali anche ai formati piatti.

Poiché le intestazioni sono vere intestazioni ATX, questo output alimenta direttamente un chunker che riconosce le intestazioni. Se vuoi i chunk — non solo il Markdown — invia il file all'endpoint di ingest, che esegue esattamente questa conversione e poi suddivide il risultato in JSONL pronto per RAG.


Costruire una pipeline RAG#

Questo endpoint converte un file alla volta in Markdown. Per una pipeline di retrieval completa di solito vuoi i chunk, non il Markdown grezzo, e spesso molti file in una volta:

  • Un file, solo il Markdown — usa questo endpoint, poi suddividilo in chunk da solo.
  • Molti file, suddivisi in JSONL — usa POST /v2/ingest/files. Esegue la stessa conversione su ogni file caricato, suddivide ciascuno in chunk basati sulle intestazioni e assembla un unico file JSONL che si carica direttamente in JSONLoader di LangChain, SimpleDirectoryReader di LlamaIndex o in un database vettoriale.
  • Pagine web invece di file — usa POST /v2/ingest (crawl o elenco di URL) o url-to-markdown per una singola pagina.

Esempi di codice#

curl (chiave privata)#

curl -X POST https://api.enconvert.com/v1/convert/anything-to-markdown \
  -H "X-API-Key: sk_live_your_private_key" \
  -F "[email protected]"

Python (chiave privata)#

import requests

with open("quarterly-report.pdf", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/anything-to-markdown",
        headers={"X-API-Key": "sk_live_your_private_key"},
        files={"file": ("quarterly-report.pdf", f)},
    )

response.raise_for_status()
result = response.json()

# Download the Markdown from the pre-signed URL.
markdown = requests.get(result["presigned_url"]).text
print(markdown)

Node.js (chiave privata)#

import { readFile } from "node:fs/promises";

const form = new FormData();
form.append(
    "file",
    new Blob([await readFile("quarterly-report.pdf")]),
    "quarterly-report.pdf"
);

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

const result = await response.json();
const markdown = await fetch(result.presigned_url).then((r) => r.text());
console.log(markdown);

PHP (chiave privata)#

$ch = curl_init("https://api.enconvert.com/v1/convert/anything-to-markdown");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_live_your_private_key"],
    CURLOPT_POSTFIELDS => [
        "file" => new CURLFile("quarterly-report.pdf", "application/pdf", "quarterly-report.pdf"),
    ],
]);

$data = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $data["presigned_url"];

Risposte di errore#

Stato Condizione
400 Bad Request Tipo di file non supportato, un file vuoto, il caricamento di un'immagine (OCR non supportato) o un documento senza testo estraibile (ad es. un PDF scansionato).
400 Bad Request I byte del file non corrispondono all'estensione dichiarata (mancata corrispondenza dei magic byte).
401 Unauthorized Chiave API / token JWT mancante o non valido.
402 Payment Required Limite mensile di conversioni o limite di archiviazione raggiunto.
403 Forbidden /v1/convert/anything-to-markdown non è tra gli endpoint consentiti della chiave API.
413 Payload Too Large Il caricamento supera il limite di dimensione per file del tuo piano.
500 Internal Server Error La conversione è fallita in modo imprevisto.

Il riferimento completo dei codici di stato è nella guida ai codici di errore.


Limiti#

Limite Valore
Dimensione massima di caricamento Dipende dal piano (Free: 5 MB)
Conversioni mensili Dipende dal piano (Free: 100)
Conservazione dei file Dipende dal piano (Free: 1 ora)
Limite di pagine PDF 2,000 pagine
Formati di input supportati Vedi la tabella dei formati di input supportati

Domande frequenti#

Come converto un PDF in Markdown con un'API?#

Invia una richiesta POST a /v1/convert/anything-to-markdown come multipart/form-data con il PDF nel campo file e la tua chiave nell'header X-API-Key. Ricevi JSON con un presigned_url a un file .md le cui intestazioni derivano dalle dimensioni dei font del PDF e le cui tabelle sono tabelle pipe GitHub-Flavored. I PDF scansionati o solo immagine non hanno un livello di testo e vengono rifiutati — questo endpoint non esegue OCR.

Quali formati di file posso convertire in Markdown?#

PDF, Word (.docx, .doc), PowerPoint (.pptx, .ppt), Excel (.xlsx, .xls), CSV, EPUB, HTML/XHTML, OpenDocument (.odt, .ods, .odp), RTF e testo semplice/Markdown. L'elenco completo con note per ciascun formato è nella tabella dei formati di input supportati. Le immagini non sono ancora supportate.

Posso convertire documenti in Markdown per una pipeline RAG o LLM?#

Sì — è proprio per questo che è costruito l'output: vere intestazioni #/##/###, tabelle pipe atomiche e codice recintato. Per un singolo file ottieni qui il Markdown e lo suddividi in chunk da solo; per molti file suddivisi in JSONL pronto per l'embedding, inviali a POST /v2/ingest/files, che esegue questa stessa conversione e suddivide ciascun file in chunk pronti per RAG.

In cosa differisce da Microsoft MarkItDown o docling?#

Risolve lo stesso problema "qualsiasi file in Markdown" come API in hosting — nessuna installazione locale, nessuna dipendenza ML pesante e output basato sulle intestazioni ottimizzato per il chunking. Si abbina direttamente a /v2/ingest così la stessa conversione alimenta una pipeline RAG end-to-end (conversione → chunk → JSONL) senza dover collegare tu stesso le librerie.

Convertite PDF scansionati o immagini?#

Non su questo endpoint. Un PDF deve avere un vero livello di testo; un PDF scansionato o solo immagine, o un file immagine (.png, .jpg), viene rifiutato con un chiaro 400 perché l'OCR è una pipeline separata e soggetta a costi. I PDF nativi digitali e gli altri formati di documento elencati si convertono senza problemi.