Documents & Productivity — entry 027 of 30
Vector Express v2.0
Vector Express chains together open-source conversion engines (Ghostscript, UniConvertor, libcdr, hp2xx, and others) to translate vector graphics across CAD and illustration formats including AI, DWG, DXF, EPS, and SVG. The core API is free under shared rate limits, while a pay-as-you-go tier removes those limits and raises the file-size ceiling; it sends no CORS headers, so browser calls need a server-side proxy.
Vector Express chains open-source engines (Ghostscript, UniConvertor, libcdr, hp2xx, and others) behind one URL-path-based conversion API — no request body needed for a same-format-family lookup, just /convert/<inFormat>/<toFormat>/. A live GET this run against /public/convert/ returned the full converter graph as real JSON at HTTP 200, fully keyless.
GreatAPIs Score
Auth quickstart
- No API key, signup, or credit card required for the public tier used above — every call in this run went through with zero credentials. The paid pay-as-you-go plan (vector.express/pricing) only removes the 5-requests/hour cap and raises the max output file size from 1 MiB to 40 MiB; it doesn't unlock any endpoint the free tier can't already reach.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
List every available converter and its supported formats
GEThttps://vector.express/api/v2/public/convert/
{
"converters": [
{ "name": "cad", "inputFormats": ["svg"], "outputFormats": ["dxf", "dwg"] },
{ "name": "cad2svg", "inputFormats": ["dxf", "dwg"], "outputFormats": ["svg"] },
{ "name": "gs", "inputFormats": ["ai", "eps", "pdf", "ps"], "outputFormats": ["eps", "pdf", "ps"] },
{ "name": "libcdr", "inputFormats": ["cdr"], "outputFormats": ["svg"] },
{ "name": "librsvg", "inputFormats": ["svg"], "outputFormats": ["eps", "pdf", "ps"] },
{ "name": "hp2xx", "inputFormats": ["hpgl", "plt"], "outputFormats": ["eps", "svg"] },
{ "name": "uniconvertor", "inputFormats": ["eps", "plt", "svg"], "outputFormats": ["pdf", "plt", "svg"] }
]
}Trimmed from 17 real converters to 7 for length; the full response also lists cadlib, emf2svg, svg2cad, pdf2svg, pstoedit, svg2emf, svg2wmf, svgo, and wmf2svg. Each entry is a real installed conversion engine, not a format pair — one engine (e.g. gs, Ghostscript) can cover several input/output combinations at once.
Developer reference
5 requests/hour on the free public API -- per the vendor's own README 'Limits' section at github.com/smidyo/vectorexpress-api; a paid plan removes the cap entirely.
Gotchas & limits
- The public API is capped at 5 requests per hour per the project's own README, and it means it — three plain GETs to the same endpoint this run got
200,200, then a genuine429 {"error":"rate limit exceeded"}on the third, withx-ratelimit-limit: 5on the successful ones. There's no burst allowance and no way to check remaining quota except reading that header on the last successful call. - There's no direct "can format A become format B" lookup — converting between two formats with no shared converter means walking a multi-hop path (e.g. svg → dxf via
svg2cad, or svg → pdf vialibrsvg), and the/convert/<from>/auto/<to>/alternatives endpoint exists specifically to enumerate those paths; a live GET this run against/convert/svg/auto/pdf/returned 50 real ranked paths, the shortest being direct single-engine hops likesvg/librsvg/pdfandsvg/uniconvertor/pdf. - No CORS headers are sent on any response, confirmed live this run with and without an
Originheader attached to the same GET — matching the project's own README ("It does not support CORS") and the storedcors: no. A browser calling this directly will be blocked; a server-side proxy is required. x-ratelimit-remainingcan't be trusted to predict the next call — two back-to-back GETs to the same endpoint this run both reportedx-ratelimit-remaining: 3(identical, not decrementing, likely because the response itself was served from Cloudflare's cache,cf-cache-status: HIT), and the very next call still got a genuine429 {"error":"rate limit exceeded"}. The header reflects whatever request generated the cached body, not necessarily the caller's own live quota.