Convert Word (DOCX) to Markdown

Convert a Word document to Markdown via the Mdkit REST API — headings, lists, tables and even equations come out as clean Markdown structure.

Last updated

Accepted format .docx only (application/vnd.openxmlformats-officedocument.wordprocessingml.document)
Sync upload cap 8 MB per file; 50 MB on the async lane

Word documents (.docx) convert synchronously on POST /v1/convert: upload the file as multipart form data and the response carries the Markdown. This is the most faithful conversion Mdkit does, because a Word file already states its own structure rather than leaving it to be inferred from font sizes. Styled headings become #/## levels, numbered and bulleted lists become Markdown lists, and Word tables become pipe tables — exactly the shape an LLM prompt or a RAG chunker wants, which is why a Word source rarely needs the slower high-fidelity lane.

curl

The DOCX MIME type is long — set it explicitly so the upload passes the content-type check:

curl -F "file=@spec.docx;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
  https://api.mdkit.online/v1/convert

The markdown field holds the converted document; meta carries the source filename (and a title when the file declares one):

{"markdown": "# Specification\n\n## Scope\n…", "meta": {"filename": "spec.docx"}}

Python — convert a folder of documents

import pathlib

import httpx

DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"


def docx_to_markdown(path: pathlib.Path) -> str:
    with path.open("rb") as fh:
        resp = httpx.post(
            "https://api.mdkit.online/v1/convert",
            files={"file": (path.name, fh, DOCX)},
            headers={"X-API-Key": "YOUR_KEY"},  # optional — raises the rate limit
            timeout=60,
        )
    resp.raise_for_status()
    return resp.json()["markdown"]


for doc in sorted(pathlib.Path("specs").glob("*.docx")):
    target = doc.with_suffix(".md")
    target.write_text(docx_to_markdown(doc), encoding="utf-8")
    print(f"{doc.name} → {target.name}")

What survives the conversion

  • Headings, lists and tables — taken from the document's own styles and table markup, not guessed from formatting.
  • Equations — Word's OMML formulas, including those in footnotes and endnotes, are converted to LaTeX: inline as $…$ and display as $$…$$, so a technical document keeps its maths as readable text.
  • Images — not extracted; the output is text. When you need to know a picture or a table was there and where it sat on the page, run the document through the async lane and read the format=json output, which lists those items with their page provenance.

Limits

  • Sync uploads are capped at 8 MB; bigger files go through async jobs (up to 50 MB).
  • Unsupported types are rejected with 415 — accepted types are PDF, DOCX, PPTX, XLSX, HTML and plain text.
  • Anonymous calls are rate-limited per IP; send an X-API-Key header to lift the limit. Each synchronous conversion costs 1 credit.

Try it

Drop a .docx into the free converter — no signup, up to 4 MB, and it runs the same conversion the API does.

FAQ

How do I convert a Word document to Markdown?
Upload the .docx to POST /v1/convert exactly as you would a PDF — the endpoint takes the file type from the upload, so no format parameter is needed.
Are headings, lists and tables preserved from Word?
Yes. DOCX carries explicit structure, so heading levels, lists and tables map cleanly onto Markdown — Word is one of the most faithful conversions Mdkit does.
What happens to images embedded in a Word file?
The Markdown output is text, so pictures do not become files you can fetch. If you need to know a picture was there and on which page, submit the document through the async lane and fetch the result with format=json.
Can I convert a legacy .doc file?
No — only the modern .docx format is accepted, and anything else is rejected with 415. Re-save the document as .docx (Word, LibreOffice and Google Docs all export it) and the conversion works normally.