AI to SVG API
POST an .ai file to /v2/convert/ai/to/svg and get one SVG per artboard, sized in points from the artboard (viewBox="0 0 192 144" for the sample). Shapes, gradients and clips are written as SVG elements; nothing is turned into pixels.
- Endpoint
- POST /v2/
convert/ ai/ to/ svg - Accepts
- ai
- Sample timing
- 2 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/ai/to/svg \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@quillback-ridge-logo-sheet.ai \
-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/ai/to/svg",
headers={"Authorization": f"Bearer {key}"},
files=[
("File", open("quillback-ridge-logo-sheet.ai", "rb")),
],
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 = "quillback-ridge-logo-sheet.ai";
form.append("File", new Blob([await readFile(file)]), file);
const url = "https://api.pdfconversionapi.com/v2/convert/ai/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.002,
"Files": [
{
"FileName": "quillback-ridge-logo-sheet-1.svg",
"FileExt": "svg",
"FileSize": 14628,
"FileData": "PHN2ZyB2aWV3Qm94PSIwIDAg…"
},
{
"FileName": "quillback-ridge-logo-sheet-2.svg",
"FileExt": "svg",
"FileSize": 13967,
"FileData": "PHN2ZyB2aWV3Qm94PSIwIDAg…"
}
]
}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
- quillback-ridge-logo-sheet.ai (10 KB)
- Output
- quillback-ridge-logo-sheet-1.svg (14 KB)quillback-ridge-logo-sheet-2.svg (14 KB)
- Source
- A two-artboard logo sheet for a fictional trail club, a full-color badge and a one-color version, which we wrote as a PDF-compatible Illustrator file with the lettering already in outlines. (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 |
|---|---|
PageRangestring | Artboards to convert. Each one becomes its own SVG named with its number, -1.svg, -2.svg and so on.Values: 1, 2-4, 1,3, last |
Passwordstring | The password of a protected .ai file, open or owner. Our encrypted copy of the sample gave the same two SVGs as the original with it, and 422 "the input file is password-protected" without it. |
FileNamestring | Base name of the SVGs: badge gives badge-1.svg and badge-2.svg. |
StoreFileboolean, default false | true stores the SVGs for 3 hours and returns their URLs. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
ImageWidth | The SVG keeps the artboard's size in points. Resize it afterwards with /v2/convert/svg/to/svg, which takes ImageWidth. |
ImageHeight | Refused for the same reason as ImageWidth. |
ImageResolution | There are no pixels to size. ConvertAPI's default of 200 is accepted; other values return 400. |
ColorSpace | Colors are written as RGB hex values; default passes, anything else is refused. |
Also refused when set: ImageQuality, ImageInterpolation.
What carries over, and what doesn't
Kept
- Vector paths, with the artboard size as the viewBox (0 0 192 144)
- Clipping: the sky, sun and mountains of artboard 1 sit in groups clipped to the badge circle
- Gradients as linearGradient elements: the sky runs from #f6a04d to #e4576e
- Opacity as fill-opacity: the 85% sun is written as 0.8509804
- Stroke width and miter limit on the 3 pt ring
- Raster images placed in the artwork, embedded as data:image/png
- The look of the artwork: drawn back to 400 × 300 on white, the SVGs differed from
/v2/convert/ai/to/pngby 0.35 to 0.39 levels per channel on average
Lost or not yet supported
- Live text. In a test file with real type, every letter became a glyph outline placed with <use>, so the words can't be selected or edited.
- Layer and object names: ids are generated (c0, n0, v0).
- The white page. The empty artboard stays transparent, unlike the PNG and JPEG routes, which paint it.
- CMYK values: colors are written as RGB hex converted with a US web offset profile (100% cyan became #00aeef).
Limits
- One .ai file per request.
- Up to 2,000 artboards per request; more returns 413.
- Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together.
- 120 seconds per conversion, then 504.
Where teams use it
Web logos from print masters
Designers hand over .ai files; websites want SVG. Convert on upload and serve the result inline or as an image, sharp at every size and small: about 14 KB for each sample artboard.
Previews in a design asset manager
A browser can show and zoom an SVG of each artboard without a design application, from one file per artboard.
Input for SVG-based tools
Cutting, plotting and web animation tools that read SVG but not .ai can take the paths directly.
Questions
Is the SVG real vector art or a picture inside an SVG?
Vector. The sample SVGs hold paths, clip paths and, on artboard 1, a gradient; neither contains an <image>. An image only appears when the artwork itself contains one: a placed bitmap is embedded as PNG data.
Why did my text turn into shapes?
The converter writes each glyph as an outline, so the SVG shows the right letterforms without the font installed. The cost is that the text can't be selected, searched or edited.
How do I set the width of the SVG?
Not on this route; ImageWidth returns 400. Edit the width and height attributes, or send the SVG to /v2/convert/svg/to/svg with ImageWidth: artboard 1 at 600 came back with width 600, height 450 and the original viewBox.
Why do I get several SVG files?
SVG holds one page, so each artboard is its own file, numbered in the order the .ai stores them. Use PageRange to choose.
Convert your first AI file in a minute.