SVG optimise, sanitise & render API
Optimize SVG with svgo, strip scripts and external references from untrusted SVG, inspect it, or render it to PNG / JPEG at any size, without a browser.
Four actions on one SVG (sent as svg, an uploaded file, a raw image/svg+xml body or a url). optimize (default) runs svgo with its default preset but keeps ids and role attributes, so CSS, scripts and #anchors that point into the file keep working; precision, multipass, pretty and aggressive=true (pure preset + removeDimensions) are available, and sanitize=true cleans the file first. sanitize removes everything that can run code or leak data: <script>, on… event handlers, javascript: / data: links that are not raster images, <foreignObject>, <iframe> / <embed>, external images and stylesheets (@import, url(https://…)) unless allow_external=true, and animations that rewrite links. The response lists every removed item. info reports size, viewBox, element counts, scripts and external references.
render turns the SVG into PNG (default) or JPEG with our own renderer written in JavaScript (no headless browser, no resvg): paths with every command including arcs, basic shapes, groups and transforms, nested svg, use / symbol, fills (non-zero / even-odd) and strokes (caps, joins, miter limit, dashes), opacity, linear and radial gradients, clip-path, luminance masks, simple <style> rules (tag, .class, #id), embedded PNG / JPEG images and text drawn from embedded fonts (Be Vietnam Pro for sans-serif, JetBrains Mono for monospace, STIX Two Math for serif), so Vietnamese text renders correctly. Set width and / or height (up to 4096 px, 5 megapixels) or scale, and background.
Not drawn: filters (blur, drop shadow), patterns, markers, textPath, external images and web fonts; they are listed in the x-render-warnings header (or warnings with format=json). On our test set the output matches Chrome to within anti-aliasing. Files are processed in memory and never stored.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
svg | body|query | string | no | The SVG markup (or send a multipart file, a raw image/svg+xml body, file_base64 or a url). | |
file | body | file | no | SVG file upload. | |
url | query|body | string | no | Public URL of the SVG (up to 5 MB). | |
action | query|body | string | no | optimize | optimize, sanitize, render or info. |
precision | query|body | number | no | 3 | optimize: decimals kept in numbers (0–8). |
multipass | query|body | boolean | no | true | optimize: repeat until the file stops shrinking. |
pretty | query|body | boolean | no | false | optimize: indented output. |
aggressive | query|body | boolean | no | false | optimize: plain svgo preset-default (ids cleaned) + removeDimensions + sortAttrs. |
sanitize | query|body | boolean | no | false | optimize: sanitise before optimising. |
allow_external | query|body | boolean | no | false | sanitize: keep http(s) image / stylesheet references. |
width | query|body | number | no | render: output width in px (≤ 4096); height follows the aspect ratio when omitted. | |
height | query|body | number | no | render: output height in px (≤ 4096). | |
scale | query|body | number | no | 1 | render: multiplier on the SVG size when width / height are not set (0.05–16). |
background | query|body | string | no | render: background colour (transparent for PNG, white for JPEG by default). | |
format | query|body | string | no | render: png (default), jpeg or json (PNG as base64 + warnings); optimize / sanitize: svg returns the file itself instead of JSON. | |
quality | query|body | number | no | 90 | render: JPEG quality (1–100). |
Example
curl -X POST "https://apibox.io.vn/v1/svg-tools" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"><!-- Logo --><metadata>Created by Editor 1.0</metadata><g id=\"logo\"><rect x=\"10.000\" y=\"10.000\" width=\"100.000\" height=\"100.000\" rx=\"20\" fill=\"#0F766E\"/><circle cx=\"60\" cy=\"60\" r=\"30.0000\" fill=\"#ffffff\" fill-opacity=\"1\"/></g></svg>"}'const res = await fetch('https://apibox.io.vn/v1/svg-tools', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"><!-- Logo --><metadata>Created by Editor 1.0</metadata><g id=\"logo\"><rect x=\"10.000\" y=\"10.000\" width=\"100.000\" height=\"100.000\" rx=\"20\" fill=\"#0F766E\"/><circle cx=\"60\" cy=\"60\" r=\"30.0000\" fill=\"#ffffff\" fill-opacity=\"1\"/></g></svg>"
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://apibox.io.vn/v1/svg-tools",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"><!-- Logo --><metadata>Created by Editor 1.0</metadata><g id=\"logo\"><rect x=\"10.000\" y=\"10.000\" width=\"100.000\" height=\"100.000\" rx=\"20\" fill=\"#0F766E\"/><circle cx=\"60\" cy=\"60\" r=\"30.0000\" fill=\"#ffffff\" fill-opacity=\"1\"/></g></svg>"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/svg-tools');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => '{"svg":"<svg xmlns=\\"http://www.w3.org/2000/svg\\" xmlns:xlink=\\"http://www.w3.org/1999/xlink\\" width=\\"120\\" height=\\"120\\" viewBox=\\"0 0 120 120\\"><!-- Logo --><metadata>Created by Editor 1.0</metadata><g id=\\"logo\\"><rect x=\\"10.000\\" y=\\"10.000\\" width=\\"100.000\\" height=\\"100.000\\" rx=\\"20\\" fill=\\"#0F766E\\"/><circle cx=\\"60\\" cy=\\"60\\" r=\\"30.0000\\" fill=\\"#ffffff\\" fill-opacity=\\"1\\"/></g></svg>"}',
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"action": "optimize",
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"><g id=\"logo\"><rect width=\"100\" height=\"100\" x=\"10\" y=\"10\" fill=\"#0f766e\" rx=\"20\"/><circle cx=\"60\" cy=\"60\" r=\"30\" fill=\"#fff\"/></g></svg>",
"original_bytes": 362,
"optimized_bytes": 223,
"saved_bytes": 139,
"saved_percent": 38.4,
"preset": "preset-default (ids and role kept)",
"precision": 3
}
Use cases
- Shrink icons and logos before shipping them on a website
- Clean user-uploaded SVG avatars and logos before showing them
- Convert SVG logos to PNG for e-mails and social networks
- Generate PNG previews of SVG assets in a CMS or design system
FAQ
Is the optimised SVG safe to change visually?
The default preset is lossless for rendering; numbers are rounded to precision (3) decimals. Ids are kept so external CSS / JS keep working; use aggressive=true to drop them and the width / height.
Does sanitising make any SVG safe to inline in HTML?
It removes scripts, event handlers, script URLs, foreign HTML, external loads and link-changing animations, which covers the known SVG XSS vectors. Still serve user files with a strict Content-Security-Policy.
Why does my PNG look different from the browser?
Filters, patterns, markers and web fonts are not supported; the header x-render-warnings lists what was skipped. Text uses the embedded fonts, so letter shapes can differ from the font you designed with.
Related APIs
QR Code Generator
Generate QR codes as PNG or SVG with one GET request: URLs, text, WiFi logins, vCards, e-mail, SMS, phone and geo links. Custom colours, size and ECC.
|||Barcode Generator
Create Code 128 barcodes for labels, SKUs and shipping with a single request. SVG with human-readable text or PNG, custom height, width and colours.
▭Placeholder Image
Get placeholder images of any size for mockups and tests: /v1/placeholder/600x400.png. SVG with custom text and colours, or a solid-colour PNG.