同一引擎,运行在服务器端。
把任意图像转换为干净、可编辑的矢量图形 —— 真实路径,每个色块区域一个填充。该 API 运行的是与浏览器内转换器完全相同的 WebAssembly 引擎,只是运行在我们的机器上而非您的机器上,因此返回的 SVG 与应用本身生成的 SVG 完全一致。
curl -X POST "https://vectortrace.app/api/v1/vectorize?format=svg" \ -F image=@logo.png \ -o logo.svg
一次请求,返回一个文件。在下方匿名限额范围内无需密钥。
身份验证
匿名请求可以使用,但限额较严格。密钥可以提升限额,以 Bearer 令牌形式发送。系统无法识别的密钥 —— 包括已撤销的密钥 —— 会直接以 401 拒绝,而不是悄悄降级到匿名档位;这次拒绝仍会计入您所在 IP 的额度:静默降级只会让一个拼写错误在一小时后变成一次速率限制错误。
Authorization: Bearer $VECTORTRACE_KEY
密钥在您的账户页面创建,仅显示一次;系统只保存其哈希值。密钥是 Pro 的功能之一:每月包含 500 张图像,超出部分每张 €0.02,通过您的订阅计费。在账户页面撤销密钥后,下一次请求即失效。密钥管理是一个浏览器端功能,通过会话 Cookie 认证并校验来源 —— 该功能已在 OpenAPI 文件中记录,便于客户端了解其数据结构,但并非为脚本化调用而设计。
GET /api/account/keys → { keys, usage, maxKeys }
POST /api/account/keys { name } → { key, secret } # secret shown once
DELETE /api/account/keys/{id} → { revoked: true, id }POST/api/v1/vectorize
对一张栅格图像进行矢量化。可以作为 multipart 文件部分发送,也可以作为 base64 编码放入 JSON 请求体。响应即为矢量文件本身,或在您指定时以 JSON 形式返回文档。
PNG · JPG · JPEG · WebP · BMP · GIF
请求
| 部分 | 位置 | 值 |
|---|---|---|
| image | multipart/form-data | 栅格文件。 |
| image | application/json 请求体 | 同一文件的 base64 编码,可带 data: 前缀,也可不带。两种方式二选一。 |
| options | JSON 请求体或表单字段 | 下方选项的任意子集。未指定的字段将使用所选预设的值。 |
| format | 查询字符串 | 指定导出格式。查询参数的优先级高于请求体。 |
| Accept | 请求头 | 设为 application/json 时返回文档及其统计信息,而非文件本身。 |
示例
curl -X POST "https://vectortrace.app/api/v1/vectorize?format=svg" \
-H "Authorization: Bearer $VECTORTRACE_KEY" \
-F "image=@logo.png" \
-F 'options={"preset":"logo","colors":8}' \
-o logo.svgimport { readFile, writeFile } from 'node:fs/promises'
const form = new FormData()
form.append('image', new Blob([await readFile('logo.png')]), 'logo.png')
form.append('options', JSON.stringify({ preset: 'logo', colors: 8 }))
const response = await fetch('https://vectortrace.app/api/v1/vectorize?format=svg', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.VECTORTRACE_KEY}` },
body: form,
})
if (!response.ok) throw new Error(await response.text())
await writeFile('logo.svg', Buffer.from(await response.arrayBuffer()))import json, os, requests
with open("logo.png", "rb") as image:
response = requests.post(
"https://vectortrace.app/api/v1/vectorize",
params={"format": "svg"},
headers={"Authorization": f"Bearer {os.environ['VECTORTRACE_KEY']}"},
files={"image": image},
data={"options": json.dumps({"preset": "logo", "colors": 8})},
)
response.raise_for_status()
open("logo.svg", "wb").write(response.content)JSON 请求体
POST /api/v1/vectorize?format=svg
Content-Type: application/json
Accept: application/json
{
"image": "iVBORw0KGgoAAAANSUhEUgAA…",
"options": { "preset": "logo", "colors": 8 }
}选项
所有字段均为可选。预设会为未指定的字段填充默认值;您设置的字段优先于预设。这些选项与转换器检查器面板中的控件完全相同,也是 Rust 引擎读取的同一张表。
| 字段 | 取值 | 默认值 | 说明 |
|---|---|---|---|
| preset | logo · line-art · photo · embroidery · vinyl · laser | logo | 具名的选项组合。与应用及 Rust 引擎使用的是同一张表。 |
| mode | color · binary | color | 二值模式描摹单一油墨;彩色模式先聚类出一个调色板。 |
| colors | 2 – 64 | 16 | 聚类后的调色板大小,二值模式下忽略此项。 |
| filterSpeckle | 像素面积 | 4 | 小于此面积的区域将被丢弃。 |
| cornerThreshold | 0 – 180 度 | 60 | 转角角度小于此值时保留为硬转角,而不是拟合为曲线。 |
| pathPrecision | 0 – 4 | 2 | 写入路径数据的小数位数。 |
| curveFitting | pixel · polygon · spline | spline | 像素模式保留锯齿边缘,多边形模式拟合直线,样条模式拟合三次曲线。 |
| hierarchical | stacked · cutout | stacked | 堆叠模式让各区域相互叠加着色;镂空模式使每个区域彼此独立、互不重叠。 |
| spliceThreshold | 0 – 180 度 | 45 | 拟合曲线被一分为二的角度阈值。 |
| lengthThreshold | 像素 | 4 | 简化前保留的最短多边形边长。 |
| maxIterations | 1 – 100 | 10 | 每条子路径曲线拟合优化的迭代预算。 |
响应与错误
成功
| 状态码 | Content-Type | 响应体 |
|---|---|---|
| 200 | image/svg+xml | 导出的 SVG 文件,内联返回,文件名由服务器生成。 |
| 200 | application/pdf | 导出的 PDF 文件,内联返回,文件名由服务器生成。 |
| 200 | application/postscript | 导出的 EPS 文件,内联返回,文件名由服务器生成。 |
| 200 | image/vnd.dxf | 导出的 DXF 文件,内联返回,文件名由服务器生成。 |
| 200 | image/png | 导出的 PNG 文件,内联返回,文件名由服务器生成。 |
| 200 | application/json | 当 Accept 为 application/json 时,返回矢量文档及其统计信息。 |
{
"document": {
"version": 1, "width": 512, "height": 512, "unit": "px",
"palette": ["#101114", "#e8491d"],
"elements": [{ "kind": "path", "fill": 0, "stroke": null, "subpaths": [ … ] }]
},
"stats": { "paths": 12, "nodes": 184, "colors": 2, "ms": 41, "estimatedSvgBytes": 3210 }
}无论请求被拒绝与否,每个响应都携带速率限制相关的响应头。 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
错误信封
错误始终使用同一种信封格式。请根据错误码分支处理,而不是根据文字描述 —— 错误码是稳定的,提示文字则不是。
{ "error": { "code": "IMAGE_TOO_LARGE", "message": "…" } }| 状态码 | 错误码 | 触发条件 |
|---|---|---|
| 400 | DECODE_FAILED | 字节数据属于受支持的格式,但无法解码。 |
| 400 | VALIDATION_ERROR | 请求体或某个字段与约定的接口不符。 |
| 401 | UNAUTHORIZED | Authorization 请求头无法解析,或密钥无法识别。 |
| 413 | IMAGE_TOO_LARGE | 图像超出该调用方类别的像素限制。 |
| 413 | PAYLOAD_TOO_LARGE | 请求体超出该调用方类别的字节限制。 |
| 415 | UNSUPPORTED_FORMAT | 所请求的输出格式在此版本中没有对应的导出器。 |
| 415 | UNSUPPORTED_INPUT_FORMAT | 字节数据不属于任何受支持的栅格格式。 |
| 429 | RATE_LIMITED | 每小时额度已用尽,Retry-After 会指明何时可以重试。 |
| 500 | ENGINE_ERROR | 描摹引擎运行后在此图像上失败。 |
| 500 | INTERNAL_ERROR | 这是我们的问题。请重试一次,如仍失败请告知我们。 |
速率限制
| 档位 | 最大请求体 | 最大像素数 | 请求次数 | 计量依据 |
|---|---|---|---|---|
| 匿名 | 2 MB | 1 MP | 20 次 / 小时 | 客户端 IP |
| 密钥 | 20 MB | 16 MP | 600 次 / 小时 | 密钥标识 |
超过像素限制的图像会被直接拒绝,而不是缩小处理。浏览器内的转换器会缩小过大的作品,因为不这样做就要在您自己的标签页中分配四分之一 GB 的内存;而在这里,限额是一种资源预算 —— 返回与您提交的原图不对应的坐标,后果会比报错更糟。
OpenAPI
以上参考文档由服务器校验所用的同一套 zod schema 生成,因此不存在手写文档过时的问题。可以直接指向它生成客户端代码。
GET https://vectortrace.app/api/openapi.json
llms.txt
一份面向语言模型与智能体的纯文本摘要,概述产品、各个页面及此接口。完整版还包含页面索引和预设表。
GET https://vectortrace.app/llms.txt GET https://vectortrace.app/llms-full.txt
CLI
第 10 周以命令行形式提供的引擎。相同的预设,相同的输出,过程中不涉及服务器。
npx @vectortrace/cli in.png -o out.svg --preset laser
MCP
第 10 周一个通过 stdio 或可流式传输的 HTTP 向智能体开放引擎的 MCP 服务器。提供三个工具:
| 工具 | 作用 |
|---|---|
| vectorize_image | 描摹一张图像,返回文档句柄及统计信息。 |
| list_presets | 返回包含所有选项取值的预设表。 |
| export_document | 将句柄序列化为其中一种导出格式。 |