Convert a file
POST /v1/convert converts one document to Markdown. The format is detected from the file’s bytes, never from its name or Content-Type.
curl -X POST https://api.md.tlelabs.com/v1/convert \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -F "file=@report.pdf" \ -F "ocr=auto" \ -F "ocr_model=auto"Request
Section titled “Request”Content-Type: multipart/form-data with these fields:
| Field | Required | Value |
|---|---|---|
file |
yes | The document. Up to 50 MB. |
ocr |
no | auto (default), force or off. See OCR modes. |
ocr_model |
no | auto (default) or a model id such as openparser/mistral-ocr-4. See OCR models. |
preserve_images |
no | true (default) or false. See Picture placeholders. |
Supported formats: PDF (.pdf), DOCX (.docx), PPTX (.pptx), XLSX (.xlsx), HTML (.html, .htm). Anything else gets 415 unsupported_format. A field with an invalid value gets 400 invalid_request with error.details.field naming it; for ocr_model the allowed ids are in error.details.allowed.
Headers: Authorization (required) and Accept — application/json (default) or text/markdown.
OCR modes
Section titled “OCR modes”ocr |
Behavior |
|---|---|
auto |
OCR only what the file cannot give as text: pictures inside DOCX, PPTX, XLSX and HTML (data: pictures), scanned PDF pages, PDF pages whose text layer is missing or garbled, and large pictures on PDF pages with text. |
force |
PDF only: every non-blank page is read by the OCR model even when it has a text layer (useful for handwriting on typed pages). Other formats behave like auto. |
off |
No OCR. Pictures keep only their placeholder. A PDF with no text at all fails with 422 parse_failed. |
Content the converter reads from the file itself — text, tables, charts, SmartArt, text inside SVG and EMF/WMF pictures — is always included and costs 1 credit per page, even with ocr=off. See Formats, pages and pricing.
An OCR failure does not fail the request: the affected picture or page is left without OCR text, you are charged a text page for it, and warnings says what happened. Only a document that ends up with no text at all because OCR failed gets 502 ocr_provider_error, and nothing is charged.
Picture placeholders
Section titled “Picture placeholders”With preserve_images=true each picture leaves a placeholder such as  where it was, followed by its OCR text as a quote:
Revenue grew  this quarter.
> Q1 120 · Q2 134 · Q3 151With preserve_images=false only the text remains. Picture bytes are never stored or returned: the placeholder only marks the position.
Response: JSON
Section titled “Response: JSON”200 OK, Content-Type: application/json:
{ "markdown": "# Quarterly report\n\n…", "format": "pdf", "usage": { "pages": 10, "ocr_pages": 3, "credits_charged": 16, "credits_remaining": 9984, "ocr_page_credits": 3 }, "metadata": { "byte_size": 524288, "duration_ms": 1842, "ocr_model": "auto", "ocr_models_used": ["openparser/paddleocr-vl-1.6"] }, "warnings": []}| Field | Meaning |
|---|---|
usage.pages |
Billed pages (how pages are counted). |
usage.ocr_pages |
Pages charged at the OCR price (OCR succeeded on them). |
usage.credits_charged |
(pages − ocr_pages) × 1 + ocr_pages × ocr_page_credits. |
usage.credits_remaining |
Wallet balance after this charge. |
usage.ocr_page_credits |
Price of one OCR page with the chosen model. |
metadata.ocr_model |
The ocr_model you sent, auto when omitted. |
metadata.ocr_models_used |
Models that returned at least one OCR result, in order of first use (shows auto fallbacks); [] without OCR. |
warnings |
Non-fatal problems, for example a picture whose OCR timed out. |
Response: Markdown
Section titled “Response: Markdown”With Accept: text/markdown the body is the Markdown itself (Content-Type: text/markdown; charset=utf-8) and the usage comes in headers:
HTTP/1.1 200 OKContent-Type: text/markdown; charset=utf-8X-Pages: 10X-OCR-Pages: 3X-Credits-Charged: 16X-Credits-Remaining: 9984X-Format: pdfX-Duration-Ms: 1842X-OCR-Model: autoX-OCR-Models-Used: openparser/paddleocr-vl-1.6X-OCR-Page-Credits: 3Warnings are only in the JSON response.
Charging
Section titled “Charging”Before converting, the most the file can cost is reserved from your available credits (402 insufficient_credits when there are not enough). After the conversion you are charged only for the pages actually converted and the rest of the reservation is released. Any error releases the whole reservation. See Errors for the one exception (503 with a request_id).
Limits per request — file size, pages, slides, sheets and pictures to OCR — are listed in Formats, pages and pricing. Base URL: https://api.md.tlelabs.com; files up to 50 MB.