Anything to Markdown API#

Der Endpoint POST /v1/convert/anything-to-markdown wandelt nahezu jedes hochgeladene Dokument — PDF, Word, PowerPoint, Excel, CSV, HTML, EPUB, reinen Text und OpenDocument-Dateien — in sauberes, überschriftenbewusstes Markdown um. Er erkennt das Format automatisch anhand der gesendeten Datei, leitet es an den passenden Extraktor weiter und gibt eine einzige .md-Datei mit genau der Struktur zurück, die LLM- und RAG-Pipelines tatsächlich brauchen: echte #/##/###-Überschriften, GitHub-Flavored Pipe-Tabellen, eingezäunte Codeblöcke und aufgelöste Links. Er ist das Datei-Gegenstück zu url-to-markdown, und derselbe Konverter treibt die Datei-Ingestion im Ingest-Endpoint an — das Markdown, das du hier erhältst, ist also genau das, was der semantische Chunker verarbeitet.

Ein einziger Endpoint ersetzt einen ganzen Stapel formatspezifischer Bibliotheken (pdfplumber, mammoth, python-pptx, openpyxl): Datei hochladen, Markdown erhalten, an deine Embeddings weiterreichen.


Endpoint#

POST /v1/convert/anything-to-markdown

Content-Type: multipart/form-data

Ausgabeformat: Markdown (.md, UTF-8). Das Format wird automatisch anhand der Dateiendung des hochgeladenen Namens und der Magic Bytes erkannt — du gibst keinen Eingabetyp an.


Unterstützte Eingabeformate#

Der Eingabetyp wird anhand der Dateiendung erkannt (und gegen die Magic Bytes der Datei validiert). Dies sind alle Formate, die der Endpoint akzeptiert:

Kategorie Formate Endungen Hinweise
PDF PDF .pdf Überschriften werden aus der Schriftgröße abgeleitet; Tabellen als Pipe-Tabellen extrahiert; laufende Kopf-/Fußzeilen dedupliziert. Gescannte/reine Bild-PDFs haben keine Textebene und werden abgelehnt — es wird keine OCR durchgeführt.
Word DOCX, DOC .docx, .doc Word-Überschriftenformatvorlagen werden zu #/##/###; Listen und Tabellen bleiben erhalten. .doc (Legacy) wird über LibreOffice verarbeitet.
Präsentationen PPTX, PPT .pptx, .ppt Ein ## Slide N-Abschnitt pro Folie, Textaufzählungen, Tabellen und Sprechernotizen. .ppt (Legacy) über LibreOffice.
Tabellenkalkulationen XLSX, XLS, CSV .xlsx, .xls, .csv Eine ## SheetName-Überschrift plus eine GFM-Tabelle pro Blatt. Zellwerte bleiben unverändert erhalten (führende Nullen und Codes werden nicht umformatiert).
E-Books EPUB .epub Kapitel werden in Lese- (Spine-)Reihenfolge aneinandergereiht; das Inhaltsverzeichnis-/Navigationsdokument wird übersprungen.
Web / Markup HTML, XHTML .html, .htm, .xhtml Originalgetreue Konvertierung des gesamten Dokuments (keine reine Artikel-Extraktion).
OpenDocument ODT, ODS, ODP .odt, .ods, .odp Text-, Tabellen- und Präsentationsdokumente, über LibreOffice.
Rich Text RTF .rtf Wird über LibreOffice konvertiert.
Reiner Text Text, Markdown .txt, .text, .md, .markdown, .mdown, .mkd Kodierungs-normalisierter Passthrough (Markdown ist bereits gültige Ausgabe).
Hinweis: Bilder (.png, .jpg und ähnliche) werden auf diesem Endpoint noch nicht unterstützt — Bild-OCR erfordert eine separate, kostengesteuerte Pipeline. Das Hochladen eines Bildes gibt einen 400 mit einer klaren Meldung zurück. Um eine Webseite statt einer Datei in Markdown umzuwandeln, verwende url-to-markdown.

Authentifizierung#

Dieser Endpoint unterstützt sowohl private als auch öffentliche Schlüssel-Authentifizierung.

Privater Schlüssel#

Füge deinen geheimen Schlüssel in den X-API-Key-Header ein. Verwende dies für Server-zu-Server-Aufrufe, bei denen der Schlüssel niemals dem Client offengelegt wird.

X-API-Key: sk_live_your_private_key

Öffentlicher Schlüssel mit JWT#

Für die clientseitige Nutzung erzeuge zuerst ein JWT-Token mit deinem öffentlichen Schlüssel und übergib es dann als Bearer-Token.

Schritt 1 -- Token abrufen:

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

Schritt 2 -- Token verwenden:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Der vollständige Ablauf, inklusive Domain-Sperre und Token-Erneuerung, steht im Authentifizierungs-Leitfaden. Jeder API-Schlüssel trägt eine Allowlist erlaubter Endpoints — wenn /v1/convert/anything-to-markdown nicht auf der Liste des Schlüssels steht, wird die Anfrage mit 403 abgelehnt.


Anfrageparameter#

Sende die Datei als multipart/form-data. Das Dokument gehört in das Feld file; die übrigen sind optionale Formularfelder.

Parameter Typ Erforderlich Standard Beschreibung
file Datei Ja -- Das zu konvertierende Dokument. Seine Endung muss eines der oben unterstützten Eingabeformate sein.
output_filename string Nein Eingabename Eigener Name für die Ausgabedatei. Die Endung .md wird automatisch angehängt.
direct_download boolean Nein true Wird aus Gründen der Konsistenz der Anfragestruktur mit den anderen Konvertierungs-Endpoints akzeptiert.
job_id string Nein -- Vom Client bereitgestellte Job-ID zur Timeout-Wiederherstellung. Wenn eine synchrone Konvertierung die Timeout-Grenzen des Reverse-Proxys überschreitet, frage GET /v1/convert/status/{job_id} ab, um das Ergebnis abzurufen.

Antwort#

Die Konvertierung läuft in-process, die resultierende .md-Datei wird gespeichert, und dann gibt der Endpoint einen JSON-Body mit einer vorsignierten Download-URL zurück:

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

Dieselben Werte werden in Response-Headern gespiegelt (X-Object-Key, X-File-Size, X-Conversion-Time, X-Filename), sodass du sie lesen kannst, ohne den Body zu parsen. Lade das Markdown von presigned_url herunter — der Link ist nur kurz gültig.


Wie jedes Format konvertiert wird#

Jedes Format wird in dieselbe saubere Markdown-Form normalisiert, sodass nachgelagertes Chunking und Embedding unabhängig von der Quelle eine einheitliche Struktur sehen.

  • PDF — Text wird mit Positionierung auf Wortebene extrahiert. Die häufigste Schriftgröße gilt als Fließtext; größere Größen werden zu #/##/###-Überschriften (die größte zuerst). Tabellen werden geometrisch erkannt und als GFM-Pipe-Tabellen ausgegeben, und ihr Text wird aus dem Fließtext-Strom entfernt, damit nichts doppelt vorkommt. Zeilen, die sich auf den meisten Seiten wiederholen (laufende Kopf-/Fußzeilen), werden verworfen. Ein PDF ohne Textebene (ein Scan oder rein bildbasierter Export) wird mit einem klaren 400 abgelehnt — dieser Endpoint führt keine OCR aus.
  • DOCX / DOC — Words Absatzformatvorlagen „Heading 1/2/3“ werden sauber auf #/##/### abgebildet; Listen, Tabellen, Fett und Kursiv bleiben erhalten. Legacy-.doc wird zuerst über LibreOffice geleitet.
  • PPTX / PPT — Jede Folie wird zu einem ## Slide N: Title-Abschnitt, Textplatzhalter werden zu Aufzählungen, Tabellen zu Pipe-Tabellen, und Sprechernotizen werden als ### Notes-Unterabschnitt angehängt — so ist jede Folie eine eigenständige, abrufbare Einheit.
  • XLSX / XLS / CSV — Jedes Arbeitsblatt wird zu einer ## SheetName-Überschrift plus einer GFM-Tabelle; eine CSV ist eine einzige Tabelle. Zellen werden als Strings gelesen, sodass IDs, Codes und führende Nullen exakt erhalten bleiben.
  • EPUB — Inhaltsdokumente werden in Spine- (Lese-)Reihenfolge gelesen und Kapitel für Kapitel konvertiert; das Navigations-/Inhaltsverzeichnisdokument wird übersprungen, damit es deine Chunks nicht verunreinigt.
  • HTML / XHTML — Das gesamte Dokument wird originalgetreu konvertiert (nicht auf einen einzelnen „Artikel“ reduziert), wobei script/style/noscript entfernt und Überschriften, Listen, Tabellen, Links und Code erhalten bleiben.
  • ODT / ODS / ODP / RTF — Werden über dieselbe LibreOffice-Engine konvertiert, die auch die Dokument-zu-PDF-Endpoints antreibt.
  • Text / Markdown — Zeilenenden und Kodierung werden normalisiert; ein .md-Upload wird im Wesentlichen unverändert durchgereicht.

Ausgabeformat#

Das Ergebnis ist GitHub-Flavored Markdown, gebaut für die maschinelle Verarbeitung:

  • Überschriften — ATX (#, ##, ###), verwendet als semantische Abschnittsgrenzen.
  • Tabellen — GFM-Pipe-Tabellen (atomar gehalten, nie geteilt), mit maskiertem | in Zellen.
  • Code — Eingezäunte Blöcke mit Sprachhinweisen, wo erkennbar.
  • Struktur — Absätze, Listen und Blockzitate bleiben erhalten; Abschnitte pro Folie und pro Blatt geben selbst flachen Formaten echte Grenzen.

Weil die Überschriften echte ATX-Überschriften sind, fließt diese Ausgabe direkt in einen überschriftenbewussten Chunker. Wenn du die Chunks willst — nicht nur das Markdown — sende die Datei stattdessen an den Ingest-Endpoint, der genau diese Konvertierung ausführt und das Ergebnis dann in RAG-fertiges JSONL aufteilt.


Eine RAG-Pipeline aufbauen#

Dieser Endpoint konvertiert jeweils eine Datei in Markdown. Für eine vollständige Retrieval-Pipeline willst du meist Chunks statt rohem Markdown, und oft viele Dateien auf einmal:

  • Eine Datei, nur das Markdown — verwende diesen Endpoint und chunke es dann selbst.
  • Viele Dateien, in JSONL gechunkt — verwende POST /v2/ingest/files. Es führt dieselbe Konvertierung für jede hochgeladene Datei aus, teilt jede in überschriftenbewusste Chunks auf und stellt eine einzige JSONL-Datei zusammen, die sich direkt in LangChain JSONLoader, LlamaIndex SimpleDirectoryReader oder eine Vektordatenbank lädt.
  • Webseiten statt Dateien — verwende POST /v2/ingest (Crawl oder URL-Liste) oder url-to-markdown für eine einzelne Seite.

Codebeispiele#

curl (Privater Schlüssel)#

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 (Privater Schlüssel)#

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 (Privater Schlüssel)#

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 (Privater Schlüssel)#

$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"];

Fehlerantworten#

Status Bedingung
400 Bad Request Nicht unterstützter Dateityp, eine leere Datei, ein Bild-Upload (OCR nicht unterstützt) oder ein Dokument ohne extrahierbaren Text (z. B. ein gescanntes PDF).
400 Bad Request Die Bytes der Datei stimmen nicht mit der angegebenen Endung überein (Magic-Byte-Diskrepanz).
401 Unauthorized Fehlender oder ungültiger API-Schlüssel / JWT-Token.
402 Payment Required Monatliches Konvertierungslimit oder Speicherlimit erreicht.
403 Forbidden /v1/convert/anything-to-markdown ist nicht in den erlaubten Endpoints des API-Schlüssels.
413 Payload Too Large Der Upload überschreitet das Dateigrößenlimit deines Tarifs.
500 Internal Server Error Die Konvertierung ist unerwartet fehlgeschlagen.

Die vollständige Statuscode-Referenz steht im Fehlercodes-Leitfaden.


Limits#

Limit Wert
Maximale Upload-Größe Tarifabhängig (Free: 5 MB)
Monatliche Konvertierungen Tarifabhängig (Free: 100)
Dateiaufbewahrung Tarifabhängig (Free: 1 Stunde)
PDF-Seitenlimit 2,000 Seiten
Unterstützte Eingabeformate Siehe die Tabelle unterstützte Eingabeformate

Häufig gestellte Fragen#

Wie konvertiere ich ein PDF mit einer API in Markdown?#

Sende eine POST-Anfrage an /v1/convert/anything-to-markdown als multipart/form-data mit dem PDF im Feld file und deinem Schlüssel im X-API-Key-Header. Du erhältst JSON mit einer presigned_url zu einer .md-Datei, deren Überschriften aus den Schriftgrößen des PDFs stammen und deren Tabellen GitHub-Flavored Pipe-Tabellen sind. Gescannte/reine Bild-PDFs haben keine Textebene und werden abgelehnt — dieser Endpoint führt keine OCR aus.

Welche Dateiformate kann ich in Markdown konvertieren?#

PDF, Word (.docx, .doc), PowerPoint (.pptx, .ppt), Excel (.xlsx, .xls), CSV, EPUB, HTML/XHTML, OpenDocument (.odt, .ods, .odp), RTF und reiner Text/Markdown. Die vollständige Liste mit Hinweisen je Format steht in der Tabelle unterstützte Eingabeformate. Bilder werden noch nicht unterstützt.

Kann ich Dokumente für eine RAG- oder LLM-Pipeline in Markdown konvertieren?#

Ja — genau dafür ist die Ausgabe gebaut: echte #/##/###-Überschriften, atomare Pipe-Tabellen und eingezäunter Code. Für eine einzelne Datei erhältst du hier das Markdown und chunkst es selbst; für viele Dateien, gechunkt in einbettungsfertiges JSONL, sende sie an POST /v2/ingest/files, das genau diese Konvertierung ausführt und jede Datei in RAG-fertige Chunks aufteilt.

Wie unterscheidet sich das von Microsoft MarkItDown oder docling?#

Es löst dasselbe Problem „jede Datei zu Markdown“ als gehostete API — keine lokale Installation, keine schweren ML-Abhängigkeiten und überschriftenbewusste Ausgabe, die aufs Chunking abgestimmt ist. Es lässt sich direkt mit /v2/ingest kombinieren, sodass dieselbe Konvertierung eine End-to-End-RAG-Pipeline speist (konvertieren → chunken → JSONL), ohne dass du Bibliotheken selbst zusammenstöpseln musst.

Konvertiert ihr gescannte PDFs oder Bilder?#

Nicht auf diesem Endpoint. Ein PDF muss eine echte Textebene haben; ein gescanntes/rein bildbasiertes PDF oder eine Bilddatei (.png, .jpg) wird mit einem klaren 400 abgelehnt, weil OCR eine separate, kostengesteuerte Pipeline ist. Nativ digitale PDFs und die anderen aufgelisteten Dokumentformate konvertieren sauber.