VSDX to PDF API
Send a Visio file to POST /v2/convert/vsdx/to/pdf and get a PDF with one page for each drawing page, in vector form with text you can select. Page names become bookmarks, and PdfaVersion makes an archival PDF/A copy.
- Endpoint
- POST /v2/
convert/ vsdx/ to/ pdf - Accepts
- vsdx
- Sample timing
- 0.538 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/vsdx/to/pdf \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@bike-repair-workflow.vsdx \
-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/vsdx/to/pdf",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("bike-repair-workflow.vsdx", "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 = "bike-repair-workflow.vsdx";
form.append("File", new Blob([await readFile(file)]), file);
const url = "https://api.pdfconversionapi.com/v2/convert/vsdx/to/pdf";
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.538,
"Files": [
{
"FileName": "bike-repair-workflow.pdf",
"FileExt": "pdf",
"FileSize": 38605,
"FileData": "JVBERi0xLjcKJcOkw7zDtsOf…"
}
]
}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
- bike-repair-workflow.vsdx (7.8 KB)
- Output
- bike-repair-workflow.pdf (38 KB)
- Source
- A two-page Visio drawing for a fictional bike shop, a repair intake flowchart and a workshop floor layout, which we wrote by hand from the VSDX package format (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 |
|---|---|
PdfaVersionenum, default none | Write PDF/A. pdfA2b turns the 38,605-byte sample into a PDF/A-2b file of about 47.5 KB; pdfA1b and pdfA3b work too, and anything else returns 400 listing the four values.Values: none, pdfA1b, pdfA2b, pdfA3b |
Pdfaboolean, default false | true is a shorter way to ask for PDF/A-1b. When PdfaVersion names a version, that version wins. |
PageRangestring | Keep only some pages of the PDF. 2 returns just the workshop layout (20,382 bytes, with the title and author but without the page-name bookmarks); 3 returns 400 saying the document has 2 pages. A range that leaves pages out can't be combined with PDF/A.Values: e.g. 2, 1-2, 2-last |
FileNamestring | Base name of the PDF. bike-repair-workflow.vsdx becomes bike-repair-workflow.pdf unless you send one. |
StoreFileboolean, default false | Store the PDF and return a link that stays valid for 3 hours. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
PageSize | Each page keeps the size saved in the drawing; PageSize=a4 returns 400 "PageSize is not supported yet for VSDX files". /v2/convert/pdf/to/resize changes it afterwards. |
PageOrientation | Comes from the drawing's page setup. |
PdfTitle | The title is taken from the file's own document properties, as the sample shows. |
IncludeMetadata | Only the default, true, is accepted. |
EmbedFonts | Fonts are embedded (as subsets in the sample); false returns 400. |
What carries over, and what doesn't
Kept
- One PDF page per drawing page, at the page size saved in the file: 11 × 8.5 in Letter landscape for both sample pages
- Text as real text in the drawing's fonts or their stand-ins, including a bold run inside a sentence and the ½ character
- Vector shapes with their exact fills (the sample's light blue is RGB 220, 233, 247), 1 pt and 3 pt line weights and dashed outlines
- Connector arrowheads, the document shape's curved edge, and a label rotated 90 degrees
- Embedded pictures: the sample's PNG badge appears as an image on page 1
- Page names as PDF bookmarks (Repair intake, Workshop layout) and the file's title and author in the PDF properties
Lost or not yet supported
- Hyperlinks on shapes are not exported: the sample's link on the Inspect box is missing from the PDF.
- Shape data (custom properties such as Owner and Target minutes) is not shown or stored anywhere in the PDF.
- Calibri is drawn with Carlito, a font with the same widths. Other fonts the server lacks are replaced by similar ones.
- Pages of different sizes share one size. In a test with one landscape and one portrait Letter page, both came out 11 × 11 in, with the drawing in the top-left corner.
- The layout comes from an open-source Visio reader, not from Visio itself; we have not compared it with a PDF saved by Visio.
Limits
- One VSDX per request.
- A file that isn't a readable VSDX returns 422 "it could not be opened as VSDX".
PageRangethat leaves pages out plus PDF/A returns 400 "PageRange cannot be combined with PDF/A yet".- 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
Process documents for people without Visio
Flowcharts and floor layouts drawn in Visio reach staff, auditors and customers who don't have it. Convert the VSDX when it is saved to the shared drive and link the PDF instead.
Archiving diagrams as PDF/A
Records policies often ask for PDF/A. One request with PdfaVersion=pdfA2b gives an archival copy of every page, with the text still searchable.
One page of a multi-page drawing
Send PageRange=2 to attach only the workshop layout to a facilities ticket, without the intake flowchart in front of it.
Questions
Is the text in the PDF searchable?
Yes. Shape text is written as text in embedded font subsets, so it can be selected, searched and read by /v2/convert/pdf/to/txt. Only text inside embedded pictures stays an image.
Which page size does the PDF use?
The one in the drawing's page setup, since PageSize and PageOrientation are refused. Both sample pages are Letter landscape, 792 × 612 points. If a drawing mixes sizes, every page gets the largest width and the largest height, so check those files.
What happens to background pages?
The sample has none. In a test file we wrote by hand, the footer on a background page was drawn behind both pages that used it, and the background page was also exported as an extra third page. Check the page count when your drawings use backgrounds.
Can I get PDF/A for just one page?
Not in one request: a PageRange that leaves pages out plus PdfaVersion returns 400. Convert the whole drawing to PDF/A, or take the page first and send that PDF to /v2/convert/pdf/to/pdfa.
Convert your first VSDX file in a minute.