JPG to TIFF API
POST a JPEG to /v2/convert/jpg/to/tiff and get an uncompressed baseline TIFF: 8-bit RGB in one strip, the decoded photo with no further loss. The sample sends ImageResolution=300, so the TIFF says 300 pixels per inch, as the JPEG did.
- Endpoint
- POST /v2/
convert/ jpg/ to/ tiff - Accepts
- jpg
- Sample timing
- 1 ms 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/jpg/to/tiff \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@trailhead-sign.jpg \
--form-string ImageResolution=300 \
-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/jpg/to/tiff",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("trailhead-sign.jpg", "rb"))],
data={
"ImageResolution": "300",
},
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 = "trailhead-sign.jpg";
form.append("File", new Blob([await readFile(file)]), file);
form.append("ImageResolution", "300");
const url = "https://api.pdfconversionapi.com/v2/convert/jpg/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.001,
"Files": [
{
"FileName": "trailhead-sign.tiff",
"FileExt": "tiff",
"FileSize": 360210,
"FileData": "SUkqAGR+BQAsAQAAAQAAACwB…"
}
]
}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
- trailhead-sign.jpg (25 KB)
- Output
- trailhead-sign.tiff (352 KB)
- Source
- A drawn mountain trailhead with a wooden sign and a QR code, made by us for these pages and saved at JPEG quality 92 with an EXIF block, an sRGB color profile and 300 dpi. (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 | Written to XResolution and YResolution with the unit set to inches. Without it the tags say 1 × 1 with no unit, so the JPEG's own 300 dpi is lost.Values: 10–800 |
ColorSpaceenum, default default | gray writes a one-channel 8-bit TIFF, a third of the size (120,198 bytes for the sample). monochrome also gives 8 bits per pixel, with only the values 0 and 255.Values: default, rgb, gray, monochrome; cmyk returns 400 |
ImageWidthinteger | Width in pixels. 200 gives 200 × 150 and 90,210 bytes.Values: 1–20000 |
ImageHeightinteger | Height in pixels; with a width as well, the photo fits inside both.Values: 1–20000 |
ScaleProportionsboolean, default true | false with both sizes stretches to fill them exactly. |
ScaleIfLargerboolean, default false | true skips enlarging; a request for 800 px wide would otherwise make a 1,440,226-byte file. |
ScaleImageboolean, default true | false crops the top-left area at the requested size. |
ImageInterpolationboolean, default false | Both values accepted; scaling uses Lanczos3 regardless. |
MultiPageboolean, default true | Accepted with either value. One JPEG always makes a one-page TIFF. |
TransparentColorstring | Adds an alpha channel and clears pixels of exactly that color. The channel is added even with no match, which grew the sample to 480,214 bytes.Values: Color name, #RRGGBB or R,G,B |
FileNamestring | Name of the .tiff; default trailhead-sign.tiff. |
StoreFileboolean, default false | true returns a link valid for 3 hours. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
ImageQuality | The TIFF is uncompressed. ConvertAPI's default, 75, is accepted; any other value returns 400 "ImageQuality is not supported yet for JPG → TIFF". |
What carries over, and what doesn't
Kept
- Every decoded pixel: the TIFF matched our JPEG decode of the sample exactly
- The resolution you ask for, as inches (unit 2 in the ResolutionUnit tag)
- Image size, with phone photos turned upright: a 300 × 200 test photo tagged EXIF Orientation 6 came back as a 200 × 300 TIFF
- CMYK JPEGs, which are converted to RGB on the way
Lost or not yet supported
- Compression. The 25,110-byte JPEG became a 360,210-byte TIFF: uncompressed RGB, no LZW, Deflate or JPEG option.
- The JPEG's dpi, unless you send
ImageResolution. - EXIF tags, the orientation tag included once it has been applied, and the sRGB ICC profile.
- CMYK as CMYK: a CMYK JPEG arrives as an RGB TIFF.
Limits
- One JPEG per request, one page in the TIFF.
- Up to 10 MB on the Free plan or 100 MB on paid plans per request.
- 100,000,000 pixels per image.
- Resize targets 1 to 20,000 px.
- 120 seconds per conversion.
Where teams use it
Print and prepress hand-offs
When a print vendor or a layout tool asks for TIFF at a stated resolution, convert with ImageResolution=300 so the size it computes matches the JPEG's.
Archives that keep a lossless master
Storing the decoded JPEG as TIFF stops further generation loss when the image is edited and saved again later.
Grayscale scans for document systems
ColorSpace=gray turns a page photographed as JPEG into a one-channel TIFF, a third of the RGB size, for document stores that keep gray TIFF.
Questions
Is the TIFF compressed?
No. Compression tag 1 (none), one strip, 8 bits per sample. That keeps it readable everywhere but large: 360,210 bytes for 400 × 300.
Will the TIFF keep my 300 dpi?
Only if you send it. The JPEG's JFIF density is not carried over; with ImageResolution=300 the TIFF reports 300 × 300 pixels per inch.
Can I get a 1-bit black-and-white TIFF?
Not yet. ColorSpace=monochrome thresholds the image to pure black and white but still stores 8 bits per pixel (120,198 bytes for the sample).
Why does ImageQuality return an error?
ConvertAPI documents it for this conversion with a default of 75. We write uncompressed TIFFs, so we accept 75 and refuse other values rather than ignore them.
Convert your first JPG file in a minute.