Ten sam silnik, po stronie serwera.
Zamień dowolny obraz w czystą, edytowalną grafikę wektorową — prawdziwe ścieżki, jedno wypełnienie na region koloru. API działa na tym samym silniku WebAssembly co konwerter w przeglądarce, tyle że na naszej maszynie zamiast Twojej, więc SVG, które dostajesz, jest tym samym SVG, jakie wygenerowałaby aplikacja.
curl -X POST "https://vectortrace.app/api/v1/vectorize?format=svg" \ -F image=@logo.png \ -o logo.svg
Jedno żądanie, jeden plik z powrotem. Bez klucza dla poniższych anonimowych limitów.
Uwierzytelnianie
Żądania anonimowe działają, z niskimi limitami. Klucz je podnosi i jest wysyłany jako token bearer. Klucz, którego nie rozpoznajemy — także taki, który został odwołany — jest odrzucany z kodem 401, a nie po cichu obniżany do poziomu anonimowego, a odmowa liczy się do budżetu Twojego IP: ciche obniżenie zmieniłoby literówkę w błąd limitu żądań godzinę później.
Authorization: Bearer $VECTORTRACE_KEY
Klucze tworzy się na stronie konta i pokazywane są raz; przechowywany jest tylko ich skrót. Są częścią Pro: 500 obrazów miesięcznie jest wliczone, a każdy kolejny obraz kosztuje 0,02 €, rozliczane w ramach subskrypcji. Odwołaj klucz na stronie konta, a przestanie działać przy następnym żądaniu. Zarządzanie kluczami to funkcja przeglądarki, uwierzytelniana ciasteczkiem sesji i sprawdzana pod kątem pochodzenia — jest udokumentowana w pliku OpenAPI, żeby klient mógł zobaczyć kształty danych, ale nie jest przeznaczona do skryptowania.
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
Wektoryzuje jeden obraz rastrowy. Wyślij go jako część multipart lub jako base64 w treści JSON. Odpowiedzią jest sam plik wektorowy albo dokument w formacie JSON, gdy o to poprosisz.
PNG · JPG · JPEG · WebP · BMP · GIF
Żądanie
| Część | Gdzie | Wartość |
|---|---|---|
| image | multipart/form-data | Plik rastrowy. |
| image | treść JSON | Ten sam plik, zakodowany w base64, z prefiksem data: lub bez niego. Użyj jednej z dwóch metod. |
| options | treść JSON lub pole formularza | Dowolny podzbiór poniższych opcji. Pominięte pola przyjmują wartości nazwanego presetu. |
| format | parametr zapytania | Co wyeksportować. Parametr zapytania ma pierwszeństwo przed treścią. |
| Accept | nagłówek żądania | application/json zwraca dokument i jego statystyki zamiast pliku. |
Przykłady
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)Treść JSON
POST /api/v1/vectorize?format=svg
Content-Type: application/json
Accept: application/json
{
"image": "iVBORw0KGgoAAAANSUhEUgAA…",
"options": { "preset": "logo", "colors": 8 }
}Opcje
Każde pole jest opcjonalne. Preset uzupełnia resztę; pole, które ustawisz, ma pierwszeństwo przed presetem. To te same ustawienia co w panelu konwertera i ta sama tabela, którą odczytuje silnik w Rust.
| Pole | Wartości | Domyślnie | Uwagi |
|---|---|---|---|
| preset | logo · line-art · photo · embroidery · vinyl · laser | logo | Nazwane zestawy opcji. Ta sama tabela co w aplikacji i w silniku Rust. |
| mode | color · binary | color | Tryb binarny wektoryzuje jeden kolor; tryb kolorowy najpierw grupuje paletę. |
| colors | 2 – 64 | 16 | Rozmiar palety po grupowaniu. Ignorowane w trybie binarnym. |
| filterSpeckle | pikseli powierzchni | 4 | Regiony mniejsze niż ta wartość są pomijane. |
| cornerThreshold | 0 – 180 stopni | 60 | Zakręty ostrzejsze niż ta wartość pozostają twardymi narożnikami zamiast krzywych. |
| pathPrecision | 0 – 4 | 2 | Liczba miejsc po przecinku zapisywana w danych ścieżki. |
| curveFitting | pixel · polygon · spline | spline | Piksel zachowuje schodki, wielokąt dopasowuje linie proste, splajn dopasowuje krzywe sześcienne. |
| hierarchical | stacked · cutout | stacked | Warstwowe nakłada regiony na siebie; wycinanka sprawia, że każdy region jest rozłączny. |
| spliceThreshold | 0 – 180 stopni | 45 | Kąt, przy którym dopasowana krzywa jest dzielona na dwie. |
| lengthThreshold | pikseli | 4 | Najkrótsza krawędź wielokąta zachowywana przed uproszczeniem. |
| maxIterations | 1 – 100 | 10 | Budżet iteracji dopasowania krzywej na podścieżkę. |
Odpowiedzi i błędy
Sukces
| Status | Content-Type | Treść |
|---|---|---|
| 200 | image/svg+xml | Wyeksportowany plik SVG, w treści odpowiedzi, z nazwą pliku nadaną przez serwer. |
| 200 | application/pdf | Wyeksportowany plik PDF, w treści odpowiedzi, z nazwą pliku nadaną przez serwer. |
| 200 | application/postscript | Wyeksportowany plik EPS, w treści odpowiedzi, z nazwą pliku nadaną przez serwer. |
| 200 | image/vnd.dxf | Wyeksportowany plik DXF, w treści odpowiedzi, z nazwą pliku nadaną przez serwer. |
| 200 | image/png | Wyeksportowany plik PNG, w treści odpowiedzi, z nazwą pliku nadaną przez serwer. |
| 200 | application/json | Dokument wektorowy i jego statystyki, przy 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 }
}Każda odpowiedź niesie nagłówki limitu żądań, odrzucona czy nie. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Koperta błędu
Zawsze jedna koperta. Rozgałęziaj na podstawie kodu, nigdy na podstawie treści — kod jest stabilny, a komunikat nie.
{ "error": { "code": "IMAGE_TOO_LARGE", "message": "…" } }| Status | Kod | Kiedy |
|---|---|---|
| 400 | DECODE_FAILED | Bajty są w formacie, który akceptujemy, ale nie udało się ich zdekodować. |
| 400 | VALIDATION_ERROR | Treść lub pole nie odpowiadały kontraktowi. |
| 401 | UNAUTHORIZED | Nagłówek Authorization, którego nie dało się odczytać, albo nieznany klucz. |
| 413 | IMAGE_TOO_LARGE | Obraz przekracza limit pikseli dla tej klasy klienta. |
| 413 | PAYLOAD_TOO_LARGE | Treść przekracza limit bajtów dla tej klasy klienta. |
| 415 | UNSUPPORTED_FORMAT | Żądany format wyjściowy nie ma eksportera w tej wersji. |
| 415 | UNSUPPORTED_INPUT_FORMAT | Bajty nie są w żadnym z akceptowanych formatów rastrowych. |
| 429 | RATE_LIMITED | Budżet godzinowy wyczerpany. Retry-After mówi, kiedy wrócić. |
| 500 | ENGINE_ERROR | Silnik uruchomił się i zawiódł na tym obrazie. |
| 500 | INTERNAL_ERROR | Nasza wina. Spróbuj raz jeszcze, a potem daj nam znać. |
Limity żądań
| Poziom | Maks. treść | Maks. piksele | Żądania | Liczone wg |
|---|---|---|---|---|
| Anonimowy | 2 MB | 1 MP | 20 / godzinę | IP klienta |
| Z kluczem | 20 MB | 16 MP | 600 / godzinę | Uchwyt klucza |
Obraz przekraczający limit pikseli jest odrzucany, a nie pomniejszany. Konwerter w Twojej przeglądarce zmniejsza zbyt duże grafiki, bo alternatywą jest alokacja ćwierć gigabajta w Twojej własnej karcie; tutaj limit jest budżetem, a zwrócenie współrzędnych, które nie odpowiadają wysłanej grafice, byłoby gorsze niż błąd.
OpenAPI
Powyższa dokumentacja jest generowana z tych samych schematów zod, którymi waliduje serwer, więc nie ma ręcznie pisanej specyfikacji, która mogłaby się zdezaktualizować. Skieruj na nią generator klienta.
GET https://vectortrace.app/api/openapi.json
llms.txt
Podsumowanie produktu, stron i tego punktu końcowego w czystym tekście, napisane z myślą o modelach językowych i agentach. Pełna wersja dodaje indeks stron i tabelę presetów.
GET https://vectortrace.app/llms.txt GET https://vectortrace.app/llms-full.txt
CLI
tydzień 10Silnik jako polecenie. Te same presety, ten sam wynik, bez serwera w pętli.
npx @vectortrace/cli in.png -o out.svg --preset laser
MCP
tydzień 10Serwer MCP udostępniający silnik agentom przez stdio lub streamable HTTP. Trzy narzędzia:
| Narzędzie | Działanie |
|---|---|
| vectorize_image | Wektoryzuje obraz i zwraca uchwyt dokumentu wraz ze statystykami. |
| list_presets | Zwraca tabelę presetów z wartościami wszystkich opcji. |
| export_document | Serializuje uchwyt do jednego z formatów eksportu. |