O mesmo mecanismo, no servidor.
Transforme qualquer imagem em arte vetorial limpa e editável — caminhos reais, um preenchimento por região de cor. A API roda o mesmo mecanismo WebAssembly do conversor no navegador, na nossa máquina em vez da sua, então o SVG que você recebe é o mesmo que o aplicativo produziria.
curl -X POST "https://vectortrace.app/api/v1/vectorize?format=svg" \ -F image=@logo.png \ -o logo.svg
Uma requisição, um arquivo de volta. Nenhuma chave é necessária para os limites anônimos abaixo.
Autenticação
Requisições anônimas funcionam, com limites reduzidos. Uma chave eleva esses limites e é enviada como bearer token. Uma chave que não reconhecemos — incluindo uma que foi revogada — é recusada com 401 em vez de ser silenciosamente rebaixada ao nível anônimo, e a recusa conta contra o orçamento do seu IP: um rebaixamento silencioso transformaria um erro de digitação em um erro de limite de taxa uma hora depois.
Authorization: Bearer $VECTORTRACE_KEY
As chaves são criadas na página da sua conta e exibidas uma única vez; apenas um hash é armazenado. Elas fazem parte do Pro: 500 imagens por mês estão incluídas, e cada imagem além disso custa € 0,02, cobrada através da sua assinatura. Revogue uma chave na página da conta e ela para de funcionar na próxima requisição. O gerenciamento de chaves é uma superfície de navegador, autenticada pelo cookie de sessão e verificada por origem — está documentado no arquivo OpenAPI para que um cliente veja os formatos, mas não é pensado para ser automatizado por script.
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
Vetorize uma imagem raster. Envie-a como parte multipart ou em base64 dentro de um corpo JSON. A resposta é o próprio arquivo vetorial, ou o documento em JSON quando solicitado.
PNG · JPG · JPEG · WebP · BMP · GIF
Requisição
| Parte | Onde | Valor |
|---|---|---|
| image | multipart/form-data | O arquivo raster. |
| image | corpo application/json | O mesmo arquivo, codificado em base64, com ou sem prefixo data:. Use apenas um dos dois. |
| options | corpo JSON, ou campo de formulário | Qualquer subconjunto das opções abaixo. Os campos omitidos assumem os valores do preset indicado. |
| format | query string | O formato de exportação. A query prevalece sobre o corpo. |
| Accept | cabeçalho da requisição | application/json retorna o documento e suas estatísticas em vez do arquivo. |
Exemplos
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)Corpo JSON
POST /api/v1/vectorize?format=svg
Content-Type: application/json
Accept: application/json
{
"image": "iVBORw0KGgoAAAANSUhEUgAA…",
"options": { "preset": "logo", "colors": 8 }
}Opções
Todo campo é opcional. Um preset preenche o restante; um campo que você define prevalece sobre o preset. São os mesmos controles do inspetor do conversor, e a mesma tabela que o mecanismo em Rust lê.
| Campo | Valores | Padrão | Notas |
|---|---|---|---|
| preset | logo · line-art · photo · embroidery · vinyl · laser | logo | Conjuntos de opções nomeados. Mesma tabela do aplicativo e do mecanismo em Rust. |
| mode | color · binary | color | Binário vetoriza uma única tinta; cor agrupa uma paleta primeiro. |
| colors | 2 – 64 | 16 | Tamanho da paleta após o agrupamento. Ignorado no modo binário. |
| filterSpeckle | pixels de área | 4 | Regiões menores que este valor são descartadas. |
| cornerThreshold | 0 – 180 graus | 60 | Curvas mais acentuadas que este valor permanecem quinas duras em vez de curvas suaves. |
| pathPrecision | 0 – 4 | 2 | Casas decimais gravadas nos dados do caminho. |
| curveFitting | pixel · polygon · spline | spline | Pixel mantém o efeito serrilhado, polígono ajusta retas, spline ajusta curvas cúbicas. |
| hierarchical | stacked · cutout | stacked | Empilhado sobrepõe regiões umas às outras; recorte torna cada região disjunta. |
| spliceThreshold | 0 – 180 graus | 45 | Ângulo no qual uma curva ajustada é dividida em duas. |
| lengthThreshold | pixels | 4 | Menor aresta de polígono mantida antes da simplificação. |
| maxIterations | 1 – 100 | 10 | Orçamento de refinamento do ajuste de curva por subcaminho. |
Respostas e erros
Sucesso
| Status | Content-Type | Corpo |
|---|---|---|
| 200 | image/svg+xml | O arquivo SVG exportado, inline, com um nome de arquivo definido pelo servidor. |
| 200 | application/pdf | O arquivo PDF exportado, inline, com um nome de arquivo definido pelo servidor. |
| 200 | application/postscript | O arquivo EPS exportado, inline, com um nome de arquivo definido pelo servidor. |
| 200 | image/vnd.dxf | O arquivo DXF exportado, inline, com um nome de arquivo definido pelo servidor. |
| 200 | image/png | O arquivo PNG exportado, inline, com um nome de arquivo definido pelo servidor. |
| 200 | application/json | O documento vetorial e suas estatísticas, com 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 }
}Toda resposta carrega os cabeçalhos de limite de taxa, recusada ou não. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Envelope de erro
Um único envelope, sempre. Baseie a lógica no código, nunca no texto — o código é estável e a mensagem não é.
{ "error": { "code": "IMAGE_TOO_LARGE", "message": "…" } }| Status | Código | Quando |
|---|---|---|
| 400 | DECODE_FAILED | Os bytes são de um formato aceito, mas não puderam ser decodificados. |
| 400 | VALIDATION_ERROR | O corpo ou um campo não correspondeu ao contrato. |
| 401 | UNAUTHORIZED | Um cabeçalho Authorization ilegível, ou uma chave desconhecida. |
| 413 | IMAGE_TOO_LARGE | A imagem excede o limite de pixels desta categoria de cliente. |
| 413 | PAYLOAD_TOO_LARGE | O corpo excede o limite de bytes desta categoria de cliente. |
| 415 | UNSUPPORTED_FORMAT | O formato de saída solicitado não tem exportador nesta versão. |
| 415 | UNSUPPORTED_INPUT_FORMAT | Os bytes não correspondem a nenhum dos rasters aceitos. |
| 429 | RATE_LIMITED | Orçamento horário esgotado. Retry-After indica quando tentar de novo. |
| 500 | ENGINE_ERROR | O mecanismo de vetorização rodou e falhou nesta imagem. |
| 500 | INTERNAL_ERROR | Erro nosso. Tente novamente uma vez e depois nos avise. |
Limites de requisição
| Nível | Corpo máx. | Pixels máx. | Requisições | Contado por |
|---|---|---|---|---|
| Anônimo | 2 MB | 1 MP | 20 / hora | IP do cliente |
| Com chave | 20 MB | 16 MP | 600 / hora | Identificador da chave |
Uma imagem acima do limite de pixels é recusada, não reduzida. O conversor no seu navegador reduz artes grandes demais porque a alternativa seria alocar um quarto de gigabyte na sua própria aba; aqui o limite é um orçamento, e devolver coordenadas que não correspondem à arte enviada seria pior do que um erro.
OpenAPI
A referência acima é gerada a partir dos mesmos esquemas zod que o servidor usa para validar, então não existe uma especificação escrita à mão para ficar desatualizada. Aponte um gerador de cliente para ela.
GET https://vectortrace.app/api/openapi.json
llms.txt
Um resumo em texto simples do produto, das páginas e deste endpoint, escrito para modelos de linguagem e agentes. A versão completa acrescenta o índice de páginas e a tabela de presets.
GET https://vectortrace.app/llms.txt GET https://vectortrace.app/llms-full.txt
CLI
semana 10O mecanismo como um comando. Mesmos presets, mesma saída, sem servidor no meio do caminho.
npx @vectortrace/cli in.png -o out.svg --preset laser
MCP
semana 10Um servidor MCP que expõe o mecanismo a agentes via stdio ou HTTP streamable. Três ferramentas:
| Ferramenta | O que faz |
|---|---|
| vectorize_image | Vetoriza uma imagem e retorna um identificador de documento mais estatísticas. |
| list_presets | Retorna a tabela de presets com todos os valores de opção. |
| export_document | Serializa um identificador para um dos formatos de exportação. |