HEIF to SVG API
POST a .heif to /v2/convert/heif/to/svg and get its shapes traced as filled paths, with clear areas left empty. The sample uses CurveMode=polygon for straight segments: 178 paths in 28,365 bytes, against 72,574 bytes with the default splines.
- Endpoint
- POST /v2/
convert/ heif/ to/ svg - Accepts
- heif
- Sample timing
- 35 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/heif/to/svg \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@succulent-sticker.heif \
--form-string CurveMode=polygon \
-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/heif/to/svg",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("succulent-sticker.heif", "rb"))],
data={
"CurveMode": "polygon",
},
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 = "succulent-sticker.heif";
form.append("File", new Blob([await readFile(file)]), file);
form.append("CurveMode", "polygon");
const url = "https://api.pdfconversionapi.com/v2/convert/heif/to/svg";
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.035,
"Files": [
{
"FileName": "succulent-sticker.svg",
"FileExt": "svg",
"FileSize": 28365,
"FileData": "PD94bWwgdmVyc2lvbj0iMS4w…"
}
]
}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
- succulent-sticker.heif (11 KB)
- Output
- succulent-sticker.svg (28 KB)
- Source
- A potted succulent sticker that we drew ourselves, with a transparent background and a soft shadow, saved as a 320 x 320 HEIF with an alpha plane. (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 |
|---|---|
CurveModeenum, default spline | polygon (the sample) draws straight segments, 28,365 bytes; pixel follows pixel edges, 78,577 bytes; spline fits curves.Values: spline, polygon, pixel |
Presetenum, default none | poster gave 240 paths, photo 88 with simplified leaves, bw a single black path of the silhouette.Values: none, bw, poster, photo |
FilterSpeckleinteger, default 4 | Patches whose area is under this value squared are dropped, so under 16 pixels at the default 4. 0 traced 3,239 paths (300,599 bytes); 16 left 87.Values: 0–128 |
ColorPrecisioninteger, default 6 | Bits per channel for grouping colors; 3 merged the sticker into 85 paths.Values: 1–8 |
GradientStepinteger, default 16 | Color step between stacked layers: 0 gave 201 paths, 32 gave 149.Values: 0–128 |
Layeringenum, default stacked | cutout makes shapes that don't overlap: 121 paths, 38,525 bytes.Values: stacked, cutout |
ColorModeenum, default color | bw traces black on clear.Values: color, bw |
CornerThresholdinteger, default 60 | Turns sharper than this angle stay corners.Values: 0–180 |
SegmentLengthnumber, default 4 | Curves are subdivided and smoothed until each segment is at most this many pixels long.Values: 3.5–10 |
SpliceThresholdinteger, default 45 | Angle at which a spline is split.Values: 0–180 |
ImageWidthinteger | Scales before tracing. 200 still gave 187 paths; 3999 was refused, since 3999 × 3999 is over the 12-megapixel tracing limit.Values: 1–20000 |
ImageHeightinteger | Target height, or a box with ImageWidth.Values: 1–20000 |
FileNamestring | Base name of the .svg. |
StoreFileboolean, default false | true returns a link valid for 3 hours. |
What carries over, and what doesn't
Kept
- Clear areas: the rendered SVG has 71,335 fully clear pixels where the PNG of the same HEIF has 72,482
- The pot's bands, the soil and the rosette's rings of leaves, each as flat colors
- The canvas size,
width="320" height="320"
Lost or not yet supported
- Soft transparency. Partly transparent pixels are traced as opaque, so the shadow under the pot (alpha 1 to 112) became a solid near-black ellipse.
- Clean leaf tips: short dark strokes appear beside several of them, traced from partly transparent edge pixels.
- A
viewBox; onlywidthandheightare set on the root element. - Tones of Display P3-tagged HEIF files.
Limits
- At most 12,000,000 pixels are traced. Scaling the sticker to
ImageWidth=3999returned 413 'vectorizing is limited to 12,000,000 pixels, and this image is 3,999×3,999; lower ImageWidth or ImageHeight'. - One HEIF per request, requests up to 10 MB on the Free plan or 100 MB on paid plans, 120 seconds per conversion.
- AV1-coded HEIF (AVIF) returns 422.
Where teams use it
Stickers and logos for cutting machines
Vinyl cutters and laser software need paths, not pixels. A HEIF cut-out with a clear background traces to shapes with nothing around them; ColorMode=bw gives the outline alone.
Vector versions of small artwork
A 320 px sticker becomes a drawing that prints at any size. Flat-colored parts like the pot trace cleanly; check gradients and shadows before using the result.
Questions
Why is the shadow black in the SVG?
The tracer gives each path a solid color and no opacity. The shadow's pixels are dark and partly transparent, so they were traced as a dark opaque shape. Remove soft shadows from the artwork, or flatten it first with heif/to/pnm and an AlphaColor, if the background color is known.
Do options like ColorSpace work here?
No, and they don't return an error either: ColorSpace=cmyk and ImageResolution=5 came back with the same SVG. On /v2/convert/heic/to/svg the same options return 400, because ConvertAPI documents them for that pair.
Which settings fit a sticker like this?
Flat artwork traces well with the defaults; CurveMode=polygon cuts the size to about 40% with straight edges, and Layering=cutout avoids overlapping shapes for cutting machines. FilterSpeckle=0 keeps every speck, which made 3,239 paths here.
Convert your first HEIF file in a minute.