Anything to PDF API#

The POST /v1/convert/anything-to-pdf endpoint converts almost any uploaded file — Word, Excel, PowerPoint, OpenDocument, Apple Pages and Numbers, HTML, Markdown, plain text, EPUB, images, and SVG — into a PDF. It auto-detects the format from the file you send, dispatches to the right rendering engine, and returns a single PDF. One endpoint replaces the whole per-format PDF stack: you upload a file, you get a PDF back, whatever the source type.

It is the single-call superset of the format-specific PDF endpoints (html-to-pdf, doc-to-pdf, excel-to-pdf, and the rest) — reach for those when you already know the input type and want fine-grained page control, and reach for this one when the input could be anything. This endpoint is file-based only; to render a live web page to PDF, use url-to-pdf. For the Markdown counterpart that turns any file into clean Markdown, see anything-to-markdown.


Endpoint#

POST /v1/convert/anything-to-pdf

Content-Type: multipart/form-data

Output format: PDF (.pdf, application/pdf). The input type is auto-detected from the uploaded filename's extension and its magic bytes — you do not specify an input format.


Supported input formats#

The input type is detected from the file extension (validated against the file's magic bytes). These are every format the endpoint accepts:

Category Formats Extensions Notes
Word DOCX, DOC .docx, .doc Rendered through LibreOffice, preserving styles, tables, and layout.
Excel XLSX, XLS .xlsx, .xls Spreadsheets rendered to paginated PDF via LibreOffice.
PowerPoint PPTX, PPT .pptx, .ppt One PDF page per slide, via LibreOffice.
OpenDocument ODT, ODS, ODP, OTS .odt, .ods, .odp, .ots Text, spreadsheet, presentation, and spreadsheet-template documents, via LibreOffice.
Apple iWork Pages, Numbers .pages, .numbers Apple Pages and Numbers documents, via LibreOffice.
Rich text / data RTF, CSV .rtf, .csv RTF documents and CSV tables rendered via LibreOffice.
Web / markup HTML, XHTML .html, .htm, .xhtml Rendered with WeasyPrint, honouring the document's own CSS.
Markdown Markdown .md, .markdown, .mdown, .mkd Rendered to a styled PDF with headings, tables, and fenced code.
Plain text Text .txt, .text Rendered in a monospace layout that preserves whitespace.
E-books EPUB .epub Chapters converted in reading (spine) order to a text PDF.
Images PNG, JPEG, GIF, BMP, TIFF, WebP, HEIC .png, .jpg, .jpeg, .gif, .bmp, .tiff, .tif, .webp, .heic, .heif Each image becomes a single-page PDF; transparency is flattened onto white.
Vector SVG .svg Rendered as vector (not rasterised) with CairoSVG.
PDF PDF .pdf Accepted and returned as-is — useful for grayscale normalisation (see pdf_options).
Note: Unlike the format-specific PDF endpoints, page geometry (custom page size, margins, orientation, headers, and footers) is not applied here, because the input format is auto-detected and each type is rendered by a different engine. Only grayscale is honoured on this endpoint. For full page control, send HTML or Markdown to html-to-pdf or markdown-to-pdf instead. To convert a live URL to PDF, use url-to-pdf.

Authentication#

This endpoint supports both private and public key authentication.

Private Key#

Include your secret key in the X-API-Key header. Use this for server-to-server calls where the key is never exposed to the client.

X-API-Key: sk_live_your_private_key

Public Key with JWT#

For client-side usage, first generate a JWT token with your public key, then pass it as a Bearer token.

Step 1 -- Get a token:

POST /v1/auth/token
X-API-Key: pk_live_your_public_key

Step 2 -- Use the token:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

The full flow, including domain locking and token refresh, is in the authentication guide. Each API key carries an allowed-endpoints allowlist — if /v1/convert/anything-to-pdf is not on the key's list, the request is rejected with 403.


Request Parameters#

Send the file as multipart/form-data. The document goes in the file field; the rest are optional form fields.

Parameter Type Required Default Description
file file Yes -- The document, image, or markup file to convert. Its extension must be one of the supported input formats above.
output_filename string No Input name Custom name for the output file. The .pdf extension is added automatically.
direct_download boolean No true Accepted for request-shape parity with the other conversion endpoints.
job_id string No -- Client-provided job ID for timeout recovery. When a sync conversion exceeds reverse-proxy timeout limits, poll GET /v1/convert/status/{job_id} to retrieve the result.
pdf_options string No null JSON string of PDF options. Only grayscale is honoured on this endpoint — see below.

PDF Options#

Pass as a JSON string in the pdf_options form field. Because the input format is auto-detected and each format is rendered by a different engine, only grayscale is applied uniformly here.

Parameter Type Default Description
grayscale boolean false Convert the output PDF to grayscale via Ghostscript post-processing. Applies to every input type, including an already-PDF upload.

For a custom page size, margins, orientation, headers, or footers, convert HTML or Markdown through the format-specific html-to-pdf or markdown-to-pdf endpoints, which accept the full pdf_options schema.


Response#

The conversion runs in-process and the resulting .pdf file is stored, then the endpoint returns a JSON body with a pre-signed download URL:

{
    "presigned_url": "https://spaces.example.com/...signed...",
    "object_key": "env/files/{project_id}/anything-to-pdf/report_20260714_101530123.pdf",
    "filename": "report_20260714_101530123.pdf",
    "file_size": 51240,
    "conversion_time_seconds": 2.1,
    "job_id": null
}

The same values are echoed in response headers (X-Object-Key, X-File-Size, X-Conversion-Time, X-Filename) so you can read them without parsing the body. Download the PDF from presigned_url — the link is short-lived.


How each format is converted#

Every format is normalised into a PDF, so you get one consistent output regardless of the source type.

  • Word / Excel / PowerPoint — Rendered with LibreOffice in headless mode, preserving styles, tables, and layout; presentations produce one page per slide. Legacy binary formats (.doc, .xls, .ppt) are handled by the same engine.
  • OpenDocument, Apple Pages / Numbers, RTF, CSV — Also rendered through LibreOffice, so ODF documents, iWork exports, rich text, and CSV tables all paginate cleanly.
  • HTML / XHTML — Rendered with WeasyPrint, which honours the document's own CSS. External resources referenced by URL may not resolve — inline your CSS and base64-encode images for best results.
  • Markdown — Converted to HTML (headings, GitHub-Flavored tables, fenced code) and rendered with WeasyPrint into a clean, styled PDF.
  • Plain text — Rendered in a monospace layout that preserves whitespace and wraps long lines, so logs and code stay readable.
  • EPUB — Content documents are read in spine (reading) order and rendered chapter by chapter into a text PDF; the navigation document is skipped.
  • Images (PNG, JPEG, GIF, BMP, TIFF, WebP, HEIC) — Each image becomes a single-page PDF via Pillow. Transparency is flattened onto a white background, and only the first frame of a multi-frame image (animated GIF, multi-page TIFF) is used.
  • SVG — Rendered as true vector graphics with CairoSVG, so the result stays crisp at any zoom.
  • PDF — An uploaded PDF is validated and returned unchanged, which makes this endpoint a convenient way to grayscale-normalise an existing PDF.

Output format#

The result is a standard PDF (application/pdf):

  • Documents keep their pagination, headings, tables, and styling from the source rendering engine.
  • Images produce a single page sized to the image; SVG stays vector.
  • Grayscale — when pdf_options.grayscale is true, the finished PDF is desaturated via a Ghostscript post-processing pass.

If you need clean Markdown instead of a PDF — for example to feed an LLM or RAG pipeline — send the same file to anything-to-markdown or the ingest endpoint instead.


Supported formats by endpoint#

The file-upload endpoints share the same format auto-detection but target different outputs. This endpoint (anything-to-pdf) accepts the widest set — all 36 formats below. anything-to-markdown and /v2/ingest accept the same 22 document formats as each other (images, SVG, and the Apple/OTS formats are PDF-only), and /v2/ingest additionally accepts web sources — a URL list, a sitemap, or a crawl — not just files.

Category Extensions anything-to-pdf anything-to-markdown /v2/ingest
PDF .pdf
Word .docx, .doc
Excel .xlsx, .xls
PowerPoint .pptx, .ppt
CSV .csv
Rich text .rtf
OpenDocument .odt, .ods, .odp
ODF template .ots
Apple iWork .pages, .numbers
Web / markup .html, .htm, .xhtml
Markdown / text .md, .markdown, .mdown, .mkd, .txt, .text
E-books .epub
Images .png, .jpg, .jpeg, .gif, .bmp, .tiff, .tif, .webp, .heic, .heif
Vector .svg

A ✓ means the endpoint accepts that format as a file upload; a — means it does not. Images and SVG convert to PDF here but are rejected by the Markdown-output endpoints (image OCR is a separate pipeline). Per-file size limits are plan-dependent (Free: 5 MB) across all three endpoints.


Code Examples#

curl (Private Key)#

curl -X POST https://api.enconvert.com/v1/convert/anything-to-pdf \
  -H "X-API-Key: sk_live_your_private_key" \
  -F "[email protected]"

Python (Private Key)#

import requests

with open("quarterly-report.docx", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/anything-to-pdf",
        headers={"X-API-Key": "sk_live_your_private_key"},
        files={"file": ("quarterly-report.docx", f)},
    )

response.raise_for_status()
result = response.json()

# Download the PDF from the pre-signed URL.
pdf = requests.get(result["presigned_url"]).content
with open("quarterly-report.pdf", "wb") as out:
    out.write(pdf)

Node.js (Private Key)#

import { readFile, writeFile } from "node:fs/promises";

const form = new FormData();
form.append(
    "file",
    new Blob([await readFile("quarterly-report.docx")]),
    "quarterly-report.docx"
);

const response = await fetch(
    "https://api.enconvert.com/v1/convert/anything-to-pdf",
    { method: "POST", headers: { "X-API-Key": "sk_live_your_private_key" }, body: form }
);

const result = await response.json();
const pdf = await fetch(result.presigned_url).then((r) => r.arrayBuffer());
await writeFile("quarterly-report.pdf", Buffer.from(pdf));

PHP (Private Key)#

$ch = curl_init("https://api.enconvert.com/v1/convert/anything-to-pdf");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_live_your_private_key"],
    CURLOPT_POSTFIELDS => [
        "file" => new CURLFile("quarterly-report.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "quarterly-report.docx"),
    ],
]);

$data = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $data["presigned_url"];

Error Responses#

Status Condition
400 Bad Request Unsupported file type, an empty file, or a corrupt/unreadable document (e.g. an invalid image or a malformed EPUB).
400 Bad Request The file's bytes do not match its declared extension (magic-byte mismatch).
400 Bad Request Invalid pdf_options JSON.
401 Unauthorized Missing or invalid API key / JWT token.
402 Payment Required Monthly conversion limit or storage limit reached.
403 Forbidden /v1/convert/anything-to-pdf is not in the API key's allowed endpoints.
413 Payload Too Large The upload exceeds your plan's per-file size limit.
500 Internal Server Error Conversion failed unexpectedly.

The full status-code reference is in the error-codes guide.


Limits#

Limit Value
Maximum upload size Plan-dependent (Free: 5 MB)
Monthly conversions Plan-dependent (Free: 100)
File retention Plan-dependent (Free: 1 hour)
Page geometry options Not applied on this endpoint (only grayscale)
Supported input formats See the supported input formats table

Frequently asked questions#

How do I convert any file to PDF with an API?#

Send a POST request to /v1/convert/anything-to-pdf as multipart/form-data with your file in the file field and your key in the X-API-Key header. The endpoint auto-detects the format, renders it to PDF, and returns JSON with a presigned_url to the finished .pdf. You do not need to tell it the input type — the extension and magic bytes decide.

Which file formats can I convert to PDF?#

Word (.docx, .doc), Excel (.xlsx, .xls), PowerPoint (.pptx, .ppt), OpenDocument (.odt, .ods, .odp, .ots), Apple Pages and Numbers, RTF, CSV, HTML/XHTML, Markdown, plain text, EPUB, images (.png, .jpg, .jpeg, .gif, .bmp, .tiff, .webp, .heic), and SVG. An existing PDF is accepted and returned as-is. The full list with per-format notes is in the supported input formats table.

Can I convert Word, Excel, or PowerPoint to PDF via the API?#

Yes. Office documents — modern (.docx, .xlsx, .pptx) and legacy (.doc, .xls, .ppt) — are rendered with LibreOffice, preserving styles, tables, and layout, with one page per slide for presentations. Upload the file and you get the PDF back.

How do I convert an image such as PNG, JPEG, or HEIC to PDF?#

Upload it to the same endpoint. Each image becomes a single-page PDF, with transparency flattened onto a white background; iPhone .heic/.heif photos and .svg vectors are supported too. For a multi-frame image (animated GIF or multi-page TIFF), the first frame is used.

Can I set a custom page size, margins, or headers on the PDF?#

Not on this endpoint — only grayscale is honoured, because the input format is auto-detected and each type uses a different rendering engine. For full page control (page size, margins, orientation, headers, footers), send HTML or Markdown to the html-to-pdf or markdown-to-pdf endpoints, which accept the complete pdf_options schema.

How is this different from the doc-to-pdf or html-to-pdf endpoints?#

The format-specific endpoints each accept one input type and expose full page-geometry options; anything-to-pdf accepts them all behind a single call and auto-detects the format, which is ideal when the input could be anything. Use a specific endpoint when you know the type and want page control; use this one when you want a single upload path for many formats.