ODC to TIFF API
POST /v2/convert/odc/to/tiff renders a standalone OpenDocument chart as one uncompressed TIFF. The sample asks for ImageResolution=72 and gets a 510 × 283 RGB image of 433,200 bytes whose resolution tags say 72 DPI.
- Endpoint
- POST /v2/
convert/ odc/ to/ tiff - Accepts
- odc
- Sample timing
- 0.533 s median of 5 runsHow we measure
- Request size
- Up to 10 MB on the Free plan or 100 MB on paid plans, all files together
Request and response
Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.
curl -sS -X POST \
https://api.pdfconversionapi.com/v2/convert/odc/to/tiff \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@garden-water-use.odc \
--form-string ImageResolution=72 \
-o response.json
# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
mkdir -p converted
name=$(jq -r '.Files[0].FileName' response.json)
jq -r '.Files[0].FileData' response.json \
| base64 --decode > "converted/$name"
else
cat response.json
fiimport base64
import os
import requests
key = os.environ["PDFCONVERSIONAPI_KEY"]
response = requests.post(
"https://api.pdfconversionapi.com/v2/convert/odc/to/tiff",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("garden-water-use.odc", "rb"))],
data={
"ImageResolution": "72",
},
timeout=180,
)
result = response.json()
if not response.ok:
raise SystemExit(f"{result['Code']}: {result['Message']}")
os.makedirs("converted", exist_ok=True)
for file in result["Files"]:
path = os.path.join("converted", file["FileName"])
with open(path, "wb") as out:
out.write(base64.b64decode(file["FileData"]))
print(path, file["FileSize"], "bytes")
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
const form = new FormData();
const file = "garden-water-use.odc";
form.append("File", new Blob([await readFile(file)]), file);
form.append("ImageResolution", "72");
const url = "https://api.pdfconversionapi.com/v2/convert/odc/to/tiff";
const key = process.env.PDFCONVERSIONAPI_KEY;
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${key}` },
body: form,
});
const result = await response.json();
if (!response.ok) {
throw new Error(`${result.Code}: ${result.Message}`);
}
await mkdir("converted", { recursive: true });
for (const file of result.Files) {
const path = join("converted", file.FileName);
await writeFile(path, Buffer.from(file.FileData, "base64"));
console.log(path, file.FileSize, "bytes");
}
{
"ConversionCost": 1,
"ConversionTime": 0.533,
"Files": [
{
"FileName": "garden-water-use-1.tiff",
"FileExt": "tiff",
"FileSize": 433200,
"FileData": "SUkqAIKbBgBIAAAAAQAAAEgA…"
}
]
}Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.
The sample, converted
The same file the code sends. Download the input and the output and compare them yourself.

- Input
- garden-water-use.odc (2.7 KB)
- Output
- garden-water-use-1.tiff (423 KB)
- Source
- A line chart of a fictional community garden's daily water use, 2025 against 2026, which we wrote as an OpenDocument chart by hand (CC0-1.0). How it was made
- Made by
- 2026-11-04, API build
9eeeb0640aba
Parameters
Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.
| Parameter | What it does |
|---|---|
ImageResolutioninteger, default 150 | Pixels per inch of chart, written to the TIFF's resolution tags. 72 gives 510 × 283, 150 gives 1,062 × 590 (1,879,966 bytes) and 300 gives 2,125 × 1,181 (7,529,149 bytes).Values: 36–600 |
ColorSpaceenum, default default | gray stores one byte per pixel instead of three: 144,528 bytes at 72 DPI, 2,509,847 at 300. rgb gives the same three-channel file as the default: 433,200 bytes at 72 DPI.Values: default, rgb, gray, monochrome |
ImageWidthinteger | Width in pixels; the height follows the chart's shape.Values: 1–20000 |
ImageHeightinteger | Height in pixels. With ImageWidth and ScaleProportions=false, 1,200 × 1,200 returned a stretched square chart.Values: 1–20000 |
ScaleProportionsboolean, default true | false fills the exact box, distorting the chart. |
ScaleImageboolean, default true | false crops the box from the top-left corner instead of scaling. |
ScaleIfLargerboolean, default false | true avoids enlarging a chart past its rendered size. |
TransparentColorstring | One exact color to clear, which adds an alpha channel: white at 72 DPI cleared 77,702 of 144,330 pixels in a 577,534-byte file.Values: color name, #RRGGBB or R,G,B |
FileNamestring | Stem of the file name, followed by -1.tiff. |
StoreFileboolean, default false | Store the TIFF and return a link for 3 hours. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
PageSize | 400 "PageSize is not supported yet for ODC files". |
What carries over, and what doesn't
Kept
- Exact rendered pixels, stored without compression
- The DPI in the resolution tags whenever
ImageResolutionis sent: the sample's tags say 72 per inch - The chart's own 18:10 area, with no page margins around it
- Three 8-bit channels in color and one in gray;
TransparentColoradds an alpha channel
Lost or not yet supported
- Compression: three bytes per pixel, so the default 150 DPI chart is 1,879,966 bytes.
- Vector sharpness: zooming a TIFF enlarges pixels; for print at any size, use the PDF route.
- The DPI tags unless
ImageResolutionis sent: the default 150 DPI file, and one sized withImageWidthorImageHeightalone, record a resolution of 1 with no unit.
Limits
MultiPageandTiffTypeare ignored on this route; a chart is always one single-page TIFF.- 100,000,000 pixels and 16,000 pixels per side; larger sizes return 413.
- Protected charts aren't supported yet: 422 "the input file is password-protected" without
Password, 400 "password-protected ODC files are not supported yet" with it. An unprotected chart sent withPasswordgives the same 1,879,966-byte TIFF as without. - Up to 10 MB on the Free plan or 100 MB on paid plans per request and 120 seconds per conversion.
Where teams use it
Figures for a print layout
A print or publishing workflow that places raster figures can take the chart as TIFF at the resolution it asks for, with that resolution written in the file.
Charts in a TIFF-based archive
Records systems that store images as TIFF can keep monthly charts next to scanned documents, one file per chart.
Gray figures for one-color print
ColorSpace=gray gives a single-channel figure: at 300 DPI, 2,509,847 bytes instead of 7,529,149.
Questions
How do I get a 300 DPI TIFF of my chart?
Send ImageResolution=300. The 18 × 10 cm chart becomes 2,125 × 1,181 pixels with 300 DPI in its tags, 7,529,149 bytes uncompressed, or 2,509,847 bytes with ColorSpace=gray.
Is the TIFF compressed?
No. The file holds raw pixels, so its size is width × height × 3 bytes plus a small header. Lower the resolution or use gray to keep it small.
Can I set the physical size instead of the DPI?
The physical size comes from the chart itself. Set the DPI with ImageResolution; 18 cm at 300 DPI is 2,125 pixels.
Convert your first ODC file in a minute.