# DOCX, PPTX & XLSX to Markdown Converter (`ridgeline_apps/document-to-markdown`) Actor

Convert DOCX, PPTX, XLSX, XLS, CSV and HTML files to clean Markdown for AI, RAG and search. Keeps headings, lists, tables, slide notes and image alt text. Optional chunking with token estimates.

- **URL**: https://apify.com/ridgeline_apps/document-to-markdown.md
- **Developed by:** [Promise Land Provision LLC](https://apify.com/ridgeline_apps) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 documents

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## DOCX, PPTX & XLSX to Markdown Converter

Convert office documents to clean Markdown: paste file links or upload files and get Markdown back, ready for AI models, RAG pipelines, search indexes and knowledge bases. It reads .docx documents, .pptx presentations, .xlsx/.xls spreadsheets, .csv, .html and plain text.

**Built for:** loading company documents into chatbots and vector databases, feeding AI agents, migrating content into wikis and docs sites, and bulk text extraction in Make, Zapier or n8n.

### What you get

- **Structure kept.** Headings, bold and italic text, links, bulleted and numbered lists, and tables become proper Markdown.
- **Presentations slide by slide.** Each slide gets a `## Slide N: Title` heading with its bullet levels, tables and (optionally) speaker notes.
- **Spreadsheets as Markdown tables,** one section per sheet, with real dates and numbers.
- **Web pages cleaned.** Scripts, styles, menus, forms and footers are removed; the main content is kept.
- **Image descriptions.** Where an image has alt text, you get `[Image: description]`. Image files are never embedded.
- **Ready for RAG.** Optional chunking splits each document at paragraph and line boundaries, with overlap and an approximate token count per chunk.
- **Fair billing.** Unsupported, damaged, password-protected and empty documents are never charged. The run stops cleanly at your maximum cost per run.

### How to use

1. Add document links (one per line) or upload files in **Documents**.
2. Optional: set a **Chunk size** for RAG, or turn speaker notes and image descriptions off.
3. Click **Start**, then download results as JSON, CSV, XLSX or HTML, or fetch them with the API.

```bash
curl -X POST "https://api.apify.com/v2/acts/ridgeline_apps~document-to-markdown/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"files": ["https://example.com/handbook.docx"], "chunkSize": 2000}'
```

### Input

| Field | Description | Default |
|---|---|---|
| `files` | Document URLs or uploaded files | required |
| `chunkSize` | Characters per chunk for RAG; 0 = no chunks | 0 |
| `chunkOverlap` | Characters repeated between chunks | 200 |
| `includeSpeakerNotes` | Add speaker notes to slides | `true` |
| `includeImageAltText` | Add `[Image: …]` descriptions | `true` |
| `sheets` | Spreadsheet sheets to include (empty = all) | all |
| `maxRowsPerSheet` | Rows per sheet converted to a table | 2,000 |
| `maxFileSizeMb` | Larger files are skipped (free) | 50 |

### Output

```json
{
  "url": "https://example.com/deck.pptx",
  "fileName": "deck.pptx",
  "status": "ok",
  "format": "pptx",
  "title": "Launch Plan",
  "slides": 3,
  "wordCount": 41,
  "markdown": "## Slide 1: Launch Plan\n\nRidgeline Apps 2026\n\n## Slide 2: Goals\n\n- Grow users\n  - Ten paying customers\n\n> Speaker notes: Mention the pricing test.",
  "chunks": [
    { "index": 0, "text": "## Slide 1: Launch Plan ...", "charCount": 1987, "approxTokens": 496 }
  ]
}
```

Files that can't be converted come back with `"status": "error"` and a plain-English `error`. They are never charged.

### Pricing

Pay per document converted, with no subscription. Unsupported, failed and empty documents are free. The exact price is on the Pricing tab, and you can set a maximum cost per run in the run options.

### FAQ

**PDF files?** Not here. Use a PDF text extractor for PDFs.

**Old .doc and .ppt files, .odt, .epub?** These aren't supported. Save as .docx or .pptx and try again; they're reported as errors and not charged.

**Images, charts and diagrams?** Images are not included; their alt text is, when present. Charts and diagrams are not converted.

**Where do my files go?** Files are downloaded into your own Apify run and processed there. Nothing is sent to any third-party service.

### Legal

Only process documents you have the right to use. You're responsible for the documents you submit and how you use the converted text.

Built on open-source software: mammoth (BSD-2-Clause), python-pptx (MIT), openpyxl (MIT), xlrd (BSD), markdownify (MIT), Beautiful Soup (MIT), charset-normalizer (MIT) and httpx (BSD-3-Clause).

Questions or a feature request? Open an issue on the **Issues** tab.

# Actor input Schema

## `files` (type: `array`):

Paste document URLs (one per line) or upload files. Supports .docx, .pptx, .xlsx, .xlsm, .xls, .csv, .html and plain text.

## `chunkSize` (type: `integer`):

Also split each document into chunks of up to this many characters, breaking at paragraphs and lines, for RAG and embeddings. 0 = no chunks.

## `chunkOverlap` (type: `integer`):

Characters repeated from the end of one chunk at the start of the next.

## `includeSpeakerNotes` (type: `boolean`):

For PPTX files, add each slide's speaker notes below the slide content.

## `includeImageAltText` (type: `boolean`):

Add \[Image: description] where an image has alt text. Images themselves are not included.

## `sheets` (type: `array`):

For XLSX and XLS files: sheet names to convert (not case-sensitive). Leave empty for all sheets.

## `maxRowsPerSheet` (type: `integer`):

Rows converted to a Markdown table per spreadsheet sheet or CSV file.

## `maxFileSizeMb` (type: `integer`):

Larger files are skipped and not charged.

## Actor input object example

```json
{
  "files": [
    "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.docx",
    "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.pptx"
  ],
  "chunkSize": 0,
  "chunkOverlap": 200,
  "includeSpeakerNotes": true,
  "includeImageAltText": true,
  "maxRowsPerSheet": 2000,
  "maxFileSizeMb": 50
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "files": [
        "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.docx",
        "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.pptx"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ridgeline_apps/document-to-markdown").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "files": [
        "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.docx",
        "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.pptx",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ridgeline_apps/document-to-markdown").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "files": [
    "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.docx",
    "https://raw.githubusercontent.com/microsoft/markitdown/main/packages/markitdown/tests/test_files/test.pptx"
  ]
}' |
apify call ridgeline_apps/document-to-markdown --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ridgeline_apps/document-to-markdown"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/pLWpnpRnbMDmShkTp/builds/PLob0uVavMAK8vGQO/openapi.json
