OTS to PDF API#

The OTS to PDF API converts OpenDocument Spreadsheet Template files (.ots) to PDF through the POST /v1/convert/ots-to-pdf endpoint. OTS is the spreadsheet template format of LibreOffice and OpenOffice Calc. Upload an .ots file as multipart/form-data and receive raw PDF bytes back, or set direct_download=false to get JSON metadata with a presigned download URL. Rendering is handled server-side by LibreOffice, so the template's own formatting, fonts, and layout are preserved in the PDF output.


Endpoint#

POST /v1/convert/ots-to-pdf

Content-Type: multipart/form-data

Accepted input: .ots files

Output format: .pdf (application/pdf)


Authentication#

Requires either a private API key or a JWT token from a public key.

X-API-Key: sk_your_private_key

Or:

Authorization: Bearer <jwt_token>

Request Parameters#

Parameter Type Required Default Description
file file Yes -- The .ots file to convert.
output_filename string No Input filename Custom output filename. The .pdf extension is added automatically.
direct_download boolean No true When true, returns raw PDF bytes. When false, returns JSON metadata with a presigned download URL.
pdf_options string No null JSON string. Only the grayscale option is supported for this endpoint (see below).

PDF Options#

For document converters powered by LibreOffice, page layout (size, margins, orientation) is determined by the document's own settings. The only pdf_options field that applies is:

Parameter Type Default Description
grayscale boolean false Convert the output PDF to grayscale via Ghostscript post-processing.
Note: Page size, margins, orientation, scale, headers, and footers from pdf_options do not apply to this endpoint. The PDF output preserves the formatting defined in the original document. To change page layout, modify the source document before uploading.

Conversion Details#

  • Uses LibreOffice (via unoserver) for server-side document rendering
  • The document's own formatting, fonts, page layout, and embedded media are preserved
  • Conversion timeout: 120 seconds
  • The output faithfully reproduces the document as it would appear when printed from LibreOffice

Response#

Direct Download (direct_download=true, default)#

HTTP 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="document_20260405_123456789.pdf"

Returns raw PDF bytes.

Metadata Response (direct_download=false)#

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/ots-to-pdf/document_20260405_123456789.pdf",
    "filename": "document_20260405_123456789.pdf",
    "file_size": 67890,
    "conversion_time_seconds": 3.5
}

Code Examples#

Python#

import requests

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

with open("output.pdf", "wb") as out:
    out.write(response.content)

Node.js#

const form = new FormData();
form.append("file", fs.createReadStream("document.ots"));

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

fs.writeFileSync("output.pdf", Buffer.from(await response.arrayBuffer()));

PHP#

$ch = curl_init("https://api.enconvert.com/v1/convert/ots-to-pdf");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_your_private_key"],
    CURLOPT_POSTFIELDS => ["file" => new CURLFile("document.ots")]
]);
$pdf = curl_exec($ch);
curl_close($ch);
file_put_contents("output.pdf", $pdf);

Go#

body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "document.ots")
file, _ := os.Open("document.ots")
io.Copy(part, file)
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/ots-to-pdf", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_your_private_key")
resp, _ := http.DefaultClient.Do(req)

With Grayscale Output#

import requests
import json

with open("document.ots", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/ots-to-pdf",
        headers={"X-API-Key": "sk_your_private_key"},
        files={"file": ("document.ots", f)},
        data={"pdf_options": json.dumps({"grayscale": True})}
    )

Error Responses#

Status Condition
400 Bad Request File is not a .ots file
400 Bad Request Document conversion failed (corrupt or unsupported file)
400 Bad Request Invalid pdf_options JSON
401 Unauthorized Missing or invalid API key / JWT token
402 Payment Required Monthly ops allowance exhausted
402 Payment Required Storage limit reached
413 Payload Too Large File exceeds plan's maximum file size
500 Internal Server Error Conversion timed out (120-second limit)

Limits#

Limit Value
Max file size Plan-dependent (Founding: 5 MB)
Conversion timeout 120 seconds
Monthly conversions Plan-dependent

Frequently asked questions#

How do I convert an OTS spreadsheet template to PDF with a REST API?#

Send a POST request to /v1/convert/ots-to-pdf with the .ots file in a multipart/form-data body, authenticated with an X-API-Key header or an Authorization: Bearer JWT. The response contains the converted PDF bytes by default.

Can I convert LibreOffice or OpenOffice Calc template files to PDF with this API?#

Yes. The endpoint accepts .ots files, the OpenDocument Spreadsheet Template format used by LibreOffice and OpenOffice Calc, and renders them server-side with LibreOffice so the output matches how the document would print from LibreOffice.

Can I get a download URL instead of the raw PDF bytes?#

Yes. Set direct_download=false and the API returns JSON metadata including a presigned_url, the output filename, file_size, and conversion_time_seconds.

Can I change the page size, margins, or orientation of the PDF output?#

No. Page layout is taken from the OTS document's own settings; the only supported pdf_options field is grayscale. To change the layout, modify the source document before uploading.

Why does the ots-to-pdf endpoint return 400 Bad Request?#

A 400 Bad Request is returned when the upload is not an .ots file, when the document is corrupt or unsupported, or when the pdf_options value is not valid JSON.