API · v1

동일한 엔진을, 서버에서.

어떤 이미지든 깔끔하고 편집 가능한 벡터 아트로 변환하세요 — 실제 패스, 색상 영역마다 하나의 채우기. 이 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가 구독을 통해 청구됩니다. 계정 페이지에서 키를 폐기하면 다음 요청부터 작동하지 않습니다. 키 관리는 세션 쿠키로 인증되고 오리진이 검사되는 브라우저 화면입니다 — 클라이언트가 형태를 확인할 수 있도록 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 파일 파트로 보내거나 JSON 본문 안에 base64로 보낼 수 있습니다. 응답은 벡터 파일 자체이거나, 요청 시 JSON 형식의 문서입니다.

PNG · JPG · JPEG · WebP · BMP · GIF

요청

파트위치
imagemultipart/form-data래스터 파일.
imageapplication/json 본문동일한 파일을 base64로 인코딩한 것으로, data: 접두사가 있어도 없어도 됩니다. 둘 중 하나만 사용하세요.
optionsJSON 본문 또는 폼 필드아래 옵션의 임의 부분 집합. 생략한 필드는 지정한 프리셋의 값을 따릅니다.
format쿼리 문자열내보낼 형식. 쿼리가 본문보다 우선합니다.
Accept요청 헤더application/json을 지정하면 파일 대신 문서와 통계를 반환합니다.

예시

curl
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.svg
node
import { 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()))
python
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 엔진이 읽는 것과 동일한 표입니다.

필드기본값설명
presetlogo · line-art · photo · embroidery · vinyl · laserlogo이름이 붙은 옵션 조합. 앱 및 Rust 엔진과 동일한 표입니다.
modecolor · binarycolor이진 모드는 단색 잉크 하나를 추적하고, 컬러 모드는 먼저 팔레트를 군집화합니다.
colors2 – 6416군집화 후 팔레트 크기. 이진 모드에서는 무시됩니다.
filterSpeckle면적(픽셀)4이보다 작은 영역은 제거됩니다.
cornerThreshold0 – 180도60이보다 예리한 꺾임은 곡선이 아닌 직각 모서리로 유지됩니다.
pathPrecision0 – 42패스 데이터에 기록되는 소수 자릿수.
curveFittingpixel · polygon · splinespline픽셀은 계단 형태를 유지하고, 폴리곤은 직선에 맞추며, 스플라인은 3차 곡선에 맞춥니다.
hierarchicalstacked · cutoutstacked스택형은 영역을 겹쳐서 칠하고, 컷아웃형은 모든 영역을 서로 분리합니다.
spliceThreshold0 – 180도45이 각도에서 피팅된 곡선이 둘로 분할됩니다.
lengthThreshold픽셀4단순화 전에 유지되는 가장 짧은 폴리곤 변의 길이.
maxIterations1 – 10010서브패스당 곡선 피팅 반복 예산.

응답 및 오류

성공

상태Content-Type본문
200image/svg+xml서버가 생성한 파일명이 붙은, 인라인 형태의 내보내기된 SVG 파일.
200application/pdf서버가 생성한 파일명이 붙은, 인라인 형태의 내보내기된 PDF 파일.
200application/postscript서버가 생성한 파일명이 붙은, 인라인 형태의 내보내기된 EPS 파일.
200image/vnd.dxf서버가 생성한 파일명이 붙은, 인라인 형태의 내보내기된 DXF 파일.
200image/png서버가 생성한 파일명이 붙은, 인라인 형태의 내보내기된 PNG 파일.
200application/jsonAccept: 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": "…" } }
상태코드발생 시점
400DECODE_FAILED지원되는 형식의 바이트이지만 디코딩할 수 없었습니다.
400VALIDATION_ERROR본문 또는 필드가 계약과 일치하지 않았습니다.
401UNAUTHORIZED읽을 수 없는 Authorization 헤더이거나, 알 수 없는 키입니다.
413IMAGE_TOO_LARGE이미지가 이 호출자 등급의 픽셀 한도를 초과했습니다.
413PAYLOAD_TOO_LARGE본문이 이 호출자 등급의 바이트 한도를 초과했습니다.
415UNSUPPORTED_FORMAT요청한 출력 형식은 이 빌드에 내보내기 기능이 없습니다.
415UNSUPPORTED_INPUT_FORMAT바이트가 지원되는 래스터 형식이 아닙니다.
429RATE_LIMITED시간당 예산을 모두 사용했습니다. Retry-After가 재시도 시점을 알려줍니다.
500ENGINE_ERROR트레이서가 실행되었으나 이 이미지에서 실패했습니다.
500INTERNAL_ERROR저희 쪽 문제입니다. 한 번 더 시도한 뒤 알려주세요.

요청 제한

등급최대 본문 크기최대 픽셀 수요청 수집계 기준
익명2 MB1 MP시간당 20회클라이언트 IP
키 사용20 MB16 MP시간당 600회키 핸들

픽셀 한도를 초과한 이미지는 축소되지 않고 거부됩니다. 브라우저 내 변환기는 과대한 아트워크를 축소하는데, 그 이유는 대안이 여러분의 탭에서 250메가바이트 규모의 메모리 할당을 요구하기 때문입니다. 여기서 한도는 예산의 문제이며, 보낸 아트워크와 맞지 않는 좌표를 반환하는 것은 오류보다 더 나쁩니다.

OpenAPI

위 레퍼런스는 서버가 검증에 사용하는 것과 동일한 zod 스키마에서 생성되므로, 스펙이 손으로 작성되어 어긋날 일이 없습니다. 클라이언트 생성기를 여기에 연결하세요.

GET https://vectortrace.app/api/openapi.json

/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 또는 streamable HTTP를 통해 엔진을 에이전트에 노출하는 MCP 서버입니다. 세 가지 도구가 있습니다:

도구기능
vectorize_image이미지를 추적하고 문서 핸들과 통계를 반환합니다.
list_presets모든 옵션 값이 담긴 프리셋 표를 반환합니다.
export_document핸들을 내보내기 형식 중 하나로 직렬화합니다.