DEV Community

Geo
Geo

Posted on

Convert Office documents to PDF in code — a REST API tutorial with headless LibreOffice

If you have ever needed to turn Word, Excel, or PowerPoint files into PDFs programmatically, you know the options are all mildly painful: install Microsoft Office on a server, script a fragile libreoffice --headless container of your own, or sign up for a proprietary conversion SaaS with a credit card before you can test a single file.

This tutorial shows a fourth path: converting Office documents to PDF through a pay-per-use REST API backed by headless LibreOffice — no Office licenses, no container to babysit, plain JSON in and PDF links out.

The problem with the usual approaches

  • Desktop Office + scripted export — needs licenses, a GUI-less VM, and constant babysitting. A licensing audit on an automation server is nobody's idea of fun.
  • Roll-your-own LibreOffice container — you own font hell, crash recovery, concurrency, and timeouts. It works, but it is a project, not a feature.
  • Proprietary converters — often require an account and a payment method just to evaluate, and per-page pricing adds up fast on real document volumes.

The sweet spot for most teams: an API that takes document URLs and returns finished PDFs, priced per document, with nothing to maintain.

How the conversion API works

The Office-to-PDF & Universal Document Converter runs LibreOffice headless inside the actor's container. You send a list of public document URLs:

{
  "documentUrls": [
    "https://example.com/quarterly-report.docx",
    "https://example.com/sales-tracking.xlsx"
  ],
  "outputFilenameStyle": "source",
  "conversionTimeoutSecs": 120
}
Enter fullscreen mode Exit fullscreen mode

Each document comes back as one dataset item:

{
  "status": "ok",
  "source": "https://example.com/quarterly-report.docx",
  "filename": "quarterly-report.docx",
  "key": "quarterly-report.pdf",
  "outputUrl": "https://api.apify.com/v2/key-value-stores/xxx/records/quarterly-report.pdf?signature=...",
  "pages": 9,
  "inputBytes": 1311881,
  "outputBytes": 105526
}
Enter fullscreen mode Exit fullscreen mode

Supported inputs include DOCX, DOC, XLSX, XLS, XLSM, PPTX, PPT, PPS, PPSX, ODT, ODS, ODP, RTF, CSV, TXT, and HTML — anything LibreOffice can open. Unsupported formats, oversized files (100 MB cap), and password-protected documents return a structured error item with a reason; error items are never charged.

Calling it from your code

Every Apify actor is a REST API. Start a run with your token:

curl -X POST "https://api.apify.com/v2/acts/gp005~office-to-pdf/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"documentUrls":["https://example.com/quarterly-report.docx"]}'
Enter fullscreen mode Exit fullscreen mode

Then fetch the dataset items for that run — each carries the outputUrl of the finished PDF, signed for direct download.

The same surface works from Python (requests or the apify-client), Node, Make, n8n, or any HTTP client. Agents can call it too, through Apify's MCP server — useful when an AI workflow needs to produce a human-readable PDF as its final artifact.

Real-world patterns

  • Archiving — collect email attachments or uploaded files, convert them to PDF, store the PDFs for retention.
  • Report generation — your pipeline produces XLSX or DOCX; convert to PDF for distribution to stakeholders who should not edit the numbers.
  • Legacy migration — batch-convert old .doc/.xls files before a downstream process that only accepts PDF.
  • Agent workflows — an AI agent that drafts a report in DOCX hands the finished PDF to a human reviewer.

Pricing

Pay-per-event, no subscription:

Event Price
Run start $0.005
Document converted $0.02

One file costs $0.005 + $0.02 = $0.025. A 100-document batch runs about $0.005 + 100 × $0.02 = $2.005. Failed conversions are never charged — a corrupt or unsupported file costs nothing.

Gotchas

  • Files must be reachable by URL — the actor fetches public URLs; it does not accept uploads or local paths. If your files are private, host them temporarily with a signed URL.
  • 100 MB per file — larger inputs are rejected with a structured error, not charged.
  • No password-protected files — LibreOffice cannot open encrypted Office documents headlessly.
  • Not a "scraper" — this actor is pure compute on files you supply. No crawling, no data collection.

FAQ

Do I need Microsoft Office or Word?

No. Conversion runs on open-source LibreOffice (MPL-2.0) inside the container — no Microsoft Office licenses, desktop apps, or activation needed.

Does the conversion preserve formatting?

Yes for standard cases — fonts, tables, charts, headers/footers render faithfully. For best fidelity use standard fonts or embed them in the source.

Can I convert many files in one run?

Yes — pass any number of URLs. Each file converts independently and reports its own status, so one bad file does not fail the batch.

How fast is it?

Smoke test on a real 9-page DOCX returned the signed PDF link with fonts and tables intact. conversionTimeoutSecs lets you set a per-file ceiling (default 120 s) — files exceeding it return a timeout error item rather than hanging the run.

The actor is live on Apify — free platform credits cover most first runs: https://apify.com/gp005/office-to-pdf

Top comments (0)