JavaScript

Convert PDF, DOCX, images, and more to Markdown using JavaScript. Code examples with fetch and axios for LLM and RAG pipelines.

No SDK needed — use the standard fetch API or axios to call the Markdown Anything REST API.

Installation

No dependencies required for fetch (built into Node.js 18+ and all modern browsers). For axios:

npm install axios

Sync Conversion

async function convertFile(filePath, token) {
    const form = new FormData();
    form.append('file', new Blob([await fs.promises.readFile(filePath)]), 'document.pdf');
    form.append('include_metadata', 'true');

    const response = await fetch('https://markdownanything.com/api/v1/convert', {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${token}`,
        },
        body: form,
    });

    if (!response.ok) {
        const error = await response.json();
        throw new Error(`${error.error}: ${error.message}`);
    }

    const data = await response.json();
    console.log(data.markdown);
    console.log(`Credits remaining: ${data.credits_remaining}`);

    return data;
}
import axios from 'axios';
import fs from 'fs';
import FormData from 'form-data';

async function convertFile(filePath, token) {
    const form = new FormData();
    form.append('file', fs.createReadStream(filePath));
    form.append('include_metadata', 'true');

    const { data } = await axios.post(
        'https://markdownanything.com/api/v1/convert',
        form,
        {
            headers: {
                'Authorization': `Bearer ${token}`,
                ...form.getHeaders(),
            },
        }
    );

    console.log(data.markdown);
    console.log(`Credits remaining: ${data.credits_remaining}`);

    return data;
}

Async Conversion with Polling

For large files, submit asynchronously and poll for the result:

async function convertAsync(filePath, token) {
    const form = new FormData();
    form.append('file', new Blob([await fs.promises.readFile(filePath)]), 'document.pdf');
    form.append('webhook_url', 'https://your-server.com/webhooks/conversions');

    const response = await fetch('https://markdownanything.com/api/v1/convert', {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${token}` },
        body: form,
    });

    const { id, status_url } = await response.json();
    console.log(`Conversion ${id} queued`);

    // Poll for result
    return pollConversion(status_url, token);
}

async function pollConversion(statusUrl, token, maxAttempts = 30) {
    for (let i = 0; i < maxAttempts; i++) {
        const response = await fetch(statusUrl, {
            headers: { 'Authorization': `Bearer ${token}` },
        });

        const data = await response.json();

        if (data.status === 'completed') {
            return data;
        }

        if (data.status === 'failed') {
            throw new Error(`Conversion failed: ${data.error}`);
        }

        // Wait 2 seconds between polls
        await new Promise(resolve => setTimeout(resolve, 2000));
    }

    throw new Error('Polling timed out');
}

Enhanced AI

Enable Enhanced AI for scanned documents, images, audio, and other complex content:

const form = new FormData();
form.append('file', fileBlob, 'scanned-document.pdf');
form.append('use_enhanced_ai', 'true');

const response = await fetch('https://markdownanything.com/api/v1/convert', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${token}` },
    body: form,
});

Enhanced AI costs 2-3 credits depending on your plan. See credit costs.

Error Handling

async function safeConvert(filePath, token) {
    try {
        const form = new FormData();
        form.append('file', new Blob([await fs.promises.readFile(filePath)]), 'document.pdf');

        const response = await fetch('https://markdownanything.com/api/v1/convert', {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` },
            body: form,
        });

        if (response.status === 402) {
            const { credits_required, credits_available } = await response.json();
            console.error(`Insufficient credits: need ${credits_required}, have ${credits_available}`);
            return null;
        }

        if (response.status === 429) {
            const retryAfter = response.headers.get('Retry-After');
            console.error(`Rate limited. Retry after ${retryAfter}s`);
            return null;
        }

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.message);
        }

        return await response.json();
    } catch (error) {
        console.error('Conversion error:', error.message);
        throw error;
    }
}