A docx to pdf api on RelayPDF is POST /v1/convert with a base64 .docx (or a local path through the SDK), sourceFilename ending in .docx, and to: pdf. LibreOffice is the default engine. Chromium on POST /v1/pdf does not open Word. Product page: https://relaypdf.com/office-to-pdf. Request contract: https://relaypdf.com/docs/convert.
Wrong endpoint, right worker
POST /v1/pdf is Chromium. It accepts exactly one of html, url, markdown, or templateId. A .docx is none of those. Sending Office bytes there fails validation. Merge is also not this path — that is POST /v1/pdf/merge (2–20 PDFs). Office conversion runs on the document worker (LibreOffice / wkhtmltopdf), not in the print pipeline that handles invoices and screenshots.
Provide exactly one of html, url, or file. file requires sourceFilename with an extension so LibreOffice knows the filter. file is base64; an optional data URI prefix is allowed. engine defaults to libreoffice. Do not set engine: wkhtmltopdf for Word — that engine only supports html or url to pdf, plus options.toc.
| Field | DOCX to PDF value | Notes |
|---|---|---|
| file | Base64 of the .docx | Required when the source is a file |
| sourceFilename | letter.docx | Extension is the format hint |
| to | pdf (default) | Also docx, xlsx, html, png |
| engine | libreoffice (default) | wkhtmltopdf is not for Word |
| filename | optional output name | Content-Disposition on binary |
| response | binary, url, or async | Same modes as /v1/pdf |
| options.toc | wkhtml only | Not a LibreOffice Word option |
Supported sources on the Office page are Word, Excel, PowerPoint, text, images, email files, and other LibreOffice-openable formats. Targets listed in OpenAPI and docs: pdf, docx, xlsx, html, png (thumbnail). This post stays on Word in, PDF out.
Fonts
ConvertRequest has no font, fonts, embedFonts, or webfont field. There is no documented upload of a .ttf alongside the document. Typefaces come from the .docx and from whatever the document worker already has installed. Chromium options (format, margin, headerTemplate, waitUntil) are not on this schema and do not restyle a Word file.
If a letterhead must keep a licensed face, embed that face in the Word file before you encode it. If the face is only referenced and not embedded, LibreOffice will substitute from the worker set. That substitution is not a RelayPDF option you can name. Do not POST webfont CSS at /v1/convert and expect it to apply to a .docx. If you need print-CSS control, that is HTML on POST /v1/pdf, documented at https://relaypdf.com/html-to-pdf.
Documented limits
The public convert docs do not publish a megabyte cap for a single .docx. Oversized HTML or files return 413 payload_too_large. That is the size signal. Do not copy the merge 15 MB figure onto convert; that number is for the merge how-to, not this endpoint.
- 503 convert_unavailable: document worker cold or unreachable. Not billed. Retry with backoff.
- Rate limits (Python SDK / account docs): trial 20/min; funded or auto-reload 60/min; burst 5 per 10 seconds. 429 includes Retry-After. Not billed.
- response: url and completed async jobs expose GET /v1/files/:id for 24 hours with no API key on GET.
- callbackUrl, if you use async, must be https. Private, loopback, and metadata hosts are url_not_allowed.
- jobs.wait in the Python client defaults to timeout_ms 120000. Node documented sample uses 120000 ms as well. That is a poll budget, not a LibreOffice option.
- Query-string API keys are rejected. Authorization uses a Bearer pdf_live key only.
LibreOffice convert is 0.04 USD per successful job on the live rate card (https://relaypdf.com/pricing, https://relaypdf.com/docs/wallet). wkhtmltopdf is 0.025 USD and is the wrong engine for .docx. New accounts get 5 USD trial credit. Failed jobs, 429s, and 402s never debit. Wallet admin can override rates; do not hardcode a second list in your app.
curl
The Office product page uses a JSON body and --output. Binary is the default: PDF bytes plus x-relaypdf-id, x-relaypdf-size, and content-disposition. Encode the file yourself; do not paste a live key.
B64=$(base64 -w0 letter.docx)
curl https://api.relaypdf.com/v1/convert
-H "Authorization: Bearer pdf_live_..."
-H "Content-Type: application/json"
-d '{"file":"UEsDB...","sourceFilename":"letter.docx","to":"pdf"}'
--output letter.pdf
For a 202, add response async. Poll GET /v1/jobs/:id with the same key until status is completed or failed. See https://relaypdf.com/docs/async. CLI: relaypdf convert --to pdf after setup writes the env file (mode 0600).
Node.js
Install the official package @relaypdf/sdk. Node 18+ with global fetch. convert.fromPath reads the local file and sets sourceFilename from the path. file may also be a Uint8Array, Buffer, ArrayBuffer, or an existing base64 string on convert.create. One method call is one HTTP request; the SDK does not retry.
import { RelayPDF, RelayPDFError } from "@relaypdf/sdk";
const client = new RelayPDF({
apiKey: process.env.RELAYPDF_API_KEY,
});
try {
const pdf = await client.convert.fromPath("./letter.docx", {
to: "pdf",
filename: "letter.pdf",
});
if (pdf.kind === "binary") {
await pdf.save("letter.pdf");
console.log(pdf.id, pdf.sizeBytes);
}
} catch (error) { if (error instanceof RelayPDFError) {
console.log(error.status, error.code, error.retryAfter);
} else { throw error;
}
}
Deck-sized files belong on async. The Node docs already use convert.fromPath on a .pptx with response async, then jobs.wait and files.download. The same sequence applies to .docx.
const job = await client.convert.fromPath("./letter.docx", {
to: "pdf",
response: "async",
});
if (job.kind === "async") {
const done = await client.jobs.wait(job.id, {
intervalMs: 1500,
timeoutMs: 120000,
});
const file = await client.files.download(done.id);
await file.save("letter.pdf");
}
Errors to branch on
Every failure is structured JSON with error.code. SDKs throw RelayPDFError with status, code, message, and retryAfter when present. Branch on code, not the status text. Table: https://relaypdf.com/docs/errors.
- invalid_request: missing sourceFilename, two sources, or wkhtml on a .docx.
- unauthorized: missing or unknown key.
- payment_required: empty wallet; top up or enable auto-reload.
- payload_too_large: shrink the file.
- rate_limited: honor Retry-After.
- processing_failed: worker opened the file and failed; unbilled.
- convert_unavailable: worker cold; unbilled.
What this is not
- Not Microsoft Word Online. LibreOffice is the documented engine.
- Not OCR, e-sign, PDF/A, or HIPAA. Those are not product claims.
- Not a Chromium header/footer on the Word pages. Use stamp after convert if you need a watermark on the PDF (POST /v1/pdf/stamp, 0.005 USD).
- Not merge. Convert one file, then merge PDFs if you need a pack.
Send Word, Excel, PowerPoint, or mail files at https://relaypdf.com/office-to-pdf. Field list and engines: https://relaypdf.com/docs/convert. Node methods: https://relaypdf.com/docs/sdks/node. Hub: https://relaypdf.com/docs. If the source is HTML you control, stay on /v1/pdf.