Skip to content
pdfconversionapi

HEIC to JXL API

POST a HEIC to /v2/convert/heic/to/jxl and get a JPEG XL file encoded from the decoded, upright photo. ImageQuality sets the trade-off, 75 unless you send one: the sample at 90 is 21,428 bytes against 22,517 for the HEIC, and 100 keeps every pixel.

Endpoint
POST /v2/convert/heic/to/jxl
Accepts
heic
Sample timing
69 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/heic/to/jxl \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@harbor-dusk.heic \
  --form-string ImageQuality=90 \
  -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
fi
200 OK69 ms median1 file, 21 KB
{
  "ConversionCost": 1,
  "ConversionTime": 0.069,
  "Files": [
    {
      "FileName": "harbor-dusk.jxl",
      "FileExt": "jxl",
      "FileSize": 21428,
      "FileData": "/wpYuQEAE4gCAKzTJULt/YJN…"
    }
  ]
}

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
harbor-dusk.heic (22 KB)
Output
harbor-dusk.jxl (21 KB)
Source
A harbor at dusk that we drew ourselves, saved as a 400 x 300 HEIC stored sideways with a rotation flag and made-up camera and GPS tags. (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.

ParameterWhat it does
ImageQualityinteger, default 75The encoder's visual quality. For the sample: 30 gave 3,790 bytes, 75 gave 8,157 (36 dB peak signal-to-noise against the decoded HEIC), 90 gave 21,428 (40.5 dB), and 100 a lossless 75,734.Values: 1–100
ImageWidthintegerScales the photo before encoding: 200 gave 200 × 150 in 3,334 bytes at the default quality.Values: 1–20000
ImageHeightintegerTarget height, or with ImageWidth a box to fit the photo into.Values: 1–20000
ScaleProportionsboolean, default truefalse uses both sizes as given, distorting the photo.
ScaleIfLargerboolean, default falsetrue only ever shrinks.
ScaleImageboolean, default truefalse crops the top-left area at the requested size.
ColorSpaceenum, default defaultgray writes a grayscale JPEG XL (6,741 bytes at quality 75). monochrome thresholds to black and white before encoding (7,060 bytes at 75), but the lossy encode brings back gray: 7,326 of the 120,000 pixels decode to neither black nor white. At ImageQuality=100 it stays two-level, in 834 bytes.Values: default, rgb, gray, monochrome
ImageResolutionintegerAccepted for ConvertAPI compatibility; the file we write records no resolution, so 300 and 200 gave identical bytes.Values: 10–800
FileNamestringName of the .jxl file without its extension.
StoreFileboolean, default falsetrue returns a link valid for 3 hours instead of base64 data.

What carries over, and what doesn't

Kept

  • At quality 100, every decoded pixel: our decode of the 75,734-byte file matched the HEIC to PNG output exactly
  • At 90, close detail: average error under 2 levels per channel, 40.5 dB
  • 8-bit sRGB color, stated in the file's header
  • The upright view and the 400 × 300 size

Lost or not yet supported

  • A generation of quality below 100: the encode is lossy on top of the HEIC's own compression; at 75 the worst pixel moved 59 levels.
  • EXIF, XMP and GPS. The file is a bare JPEG XL codestream without metadata boxes.
  • A preview on this site: our API doesn't read JPEG XL, so the sample offers a download only.
  • Tones of HEIC files tagged with an embedded Display P3 profile, stretched by the decoder (gray 235 became 255).

Limits

  • One HEIC per request, up to 100,000,000 decoded pixels.
  • Requests up to 10 MB on the Free plan or 100 MB on paid plans; 120 seconds per conversion.
  • There is no heif/to/jxl route (404). A .heif file can be sent here instead: our transparent HEIF sticker gave a JPEG XL with an alpha channel.
  • HEIC files saved at a desktop encoder's top quality setting returned 422 'malformed data'.

Where teams use it

Archiving phone photos in an open format

Opening a HEIC takes an HEVC decoder. JPEG XL at quality 100 keeps the decoded pixels exactly, so an archive can drop the HEIC without losing anything that was visible.

Smaller web images where JPEG XL is shown

At the default quality the sample is 8,157 bytes, about a third of the HEIC. Serve it where clients accept image/jxl and keep a JPEG fallback from heic/to/jpg for the rest.

Questions

Is the JPEG XL smaller than the HEIC?

At the default quality, yes: 8,157 bytes against 22,517 for the sample. At 90 they are about even (21,428 bytes), and lossless output is more than three times the HEIC.

Is quality 100 really lossless?

Yes, relative to the decoded HEIC. The header reports a possibly lossless 8-bit RGB image, and decoding it gave the same pixels as our HEIC to PNG output, all 120,000 of them.

Can I send a .heif file?

Not to a .heif route, which doesn't exist for JPEG XL. Post it to /v2/convert/heic/to/jxl: the decoder reads the content, not the name. A HEIF with an alpha plane came back as an RGB plus alpha JPEG XL.

What does `ImageQuality` mean here?

It is passed to the JPEG XL encoder as its quality setting, from 1 to 100, where 100 means lossless. 75 is our default and also ConvertAPI's documented default for this pair.

Convert your first HEIC file in a minute.