A FastAPI-based REST API service that converts various file formats to Markdown using Microsoft's MarkItDown library.
- Convert single files to Markdown format
- Batch conversion support
- Download converted files or get JSON response
- Fetch and convert files directly from remote URLs
- Smart pre-processing with Google Magika to skip unnecessary conversions for plain text
- Graceful error handling for LLM rate limits (429) and provider outages (503)
- Image OCR support (requires OpenAI API key)
- Support for multiple file formats:
- Documents: PDF, DOCX, PPTX, XLSX
- Images: PNG, JPG, JPEG, GIF, BMP, TIFF
- Audio: MP3, WAV, M4A, OGG
- Web: HTML, XML
- Data: CSV, JSON
- Text: TXT, MD, RTF
- Other: EPUB, ZIP
This project uses modern development tools for improved developer experience:
We use Task instead of traditional Makefiles for task automation. Task provides:
- Cross-platform compatibility (works on Windows, macOS, Linux)
- YAML syntax that's more readable than Makefiles
- Built-in variable support and dependency management
- Better error handling and output formatting
API testing is done with Hurl instead of traditional curl scripts or Postman collections:
- Tests are written in plain text files that are easy to version control
- Human-readable format that serves as living documentation
- Built-in assertions and JSON path support
- Can be integrated into CI/CD pipelines
- Faster than UI-based testing tools
- Create virtual environment and install dependencies:
task installOr manually:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtStart the server:
task startOr manually:
python main.pyThe API will be available at http://localhost:8000
Create a .env file (see .env.example):
MODEL_PROVIDER- Optional:openai(default),azure, oropenai-compatibleMODEL- Optional: Default model/deployment name for OpenAI-compatible providers (gpt-4oby default)OPENAI_API_KEY- Optional: API key for the default OpenAI provider (also used as fallback for other providers and to enable OCR)AZURE_OPENAI_API_KEY,AZURE_OPENAI_ENDPOINT,AZURE_OPENAI_DEPLOYMENT,AZURE_OPENAI_API_VERSION- Required whenMODEL_PROVIDER=azureOPENAI_BASE_URL,OPENAI_API_KEY- Required whenMODEL_PROVIDER=openai-compatible(Groq, LiteLLM, etc.). Legacy variablesOPENAI_COMPATIBLE_BASE_URL/OPENAI_COMPATIBLE_API_KEYare also supported.OPENAI_API_KEY_PROVIDER- Optional: set tooauth2to fetch API tokens via client credentials (currently supported withMODEL_PROVIDER=openai-compatible). RequiresOAUTH_TOKEN_URL,OAUTH_CLIENT_ID, andOAUTH_CLIENT_SECRET.
OpenAI (default):
MODEL_PROVIDER=openai
OPENAI_API_KEY=sk-...
MODEL=gpt-4oAzure OpenAI:
MODEL_PROVIDER=azure
AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_OPENAI_DEPLOYMENT=gpt-4o-mini
AZURE_OPENAI_API_VERSION=2024-02-15-previewGroq or other OpenAI-compatible providers (via LiteLLM, etc.):
MODEL_PROVIDER=openai-compatible
OPENAI_BASE_URL=https://api.groq.com/openai/v1
OPENAI_API_KEY=gsk-...
MODEL=meta-llama/llama-4-maverick-17b-128e-instructOpenAI-compatible provider with OAuth2 client credentials (see Taskfile.apollo.yaml):
MODEL_PROVIDER=openai-compatible
OPENAI_BASE_URL=https://api.partner.com/openai/v1
OPENAI_API_KEY_PROVIDER=oauth2
OAUTH_TOKEN_URL=https://auth.partner.com/oauth/token
OAUTH_CLIENT_ID=...
OAUTH_CLIENT_SECRET=...
MODEL=my-modelAll providers share the same conversion endpoints and benefit from the built-in rate limit (429) and outage (503) handling.
POST /api/v1/convertUpload a file to convert to Markdown. Optional query parameters:
download=trueto download the result as a.mdfilefile_urlto fetch and convert a remote file (HTTP/HTTPS, ≤50 MB)
Example:
curl -X POST "http://localhost:8000/api/v1/convert" \
-F "file=@document.pdf"Convert using a remote URL:
curl -X POST "http://localhost:8000/api/v1/convert" \
-d "file_url=https://example.com/document.pdf"POST /api/v1/convert/batchConvert multiple files in a single request.
Example:
curl -X POST "http://localhost:8000/api/v1/convert/batch" \
-F "files=@doc1.pdf" \
-F "files=@doc2.docx"GET /healthInteractive API documentation available at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
All API tests are written in Hurl format and located in tests/hurl/. Tests serve as both validation and documentation.
Run all tests:
task testTest specific endpoints:
task test:health # Health endpoints
task test:convert # Conversion endpoints
task test:image # Image OCR (requires OPENAI_API_KEY)View all available tasks:
task --listCommon development tasks:
task install # Install dependencies
task start # Start the API server
task dev # Start with auto-reload
task test # Run all testsBuild and run with Docker:
# Build the image
docker build -t markitdown-api .
# Run the container
docker run -p 8000:8000 markitdown-api
# With environment variables
docker run -p 8000:8000 -e OPENAI_API_KEY=your_key markitdown-api{
"filename": "document.pdf",
"original_format": ".pdf",
"markdown_content": "# Converted content...",
"metadata": {
"file_size": 12345,
"converted_at": 1234567890.123,
"detection": {
"label": "pdf",
"mime_type": "application/pdf",
"group": "document",
"is_text": false,
"score": 0.997
}
},
"conversion_time": 0.234
}{
"successful_conversions": [...],
"errors": [...],
"total_files": 3,
"successful": 2,
"failed": 1
}