Dieselbe Engine, serverseitig.
Verwandeln Sie jedes Bild in sauberes, editierbares Vektor-Artwork — echte Pfade, eine Füllung pro Farbregion. Die API nutzt dieselbe WebAssembly-Engine wie der Konverter im Browser, nur auf unserer Maschine statt Ihrer — die SVG, die Sie zurückbekommen, ist also die SVG, die auch die App erzeugt hätte.
curl -X POST "https://vectortrace.app/api/v1/vectorize?format=svg" \ -F image=@logo.png \ -o logo.svg
Eine Anfrage, eine Datei zurück. Kein Schlüssel nötig für die unten genannten anonymen Limits.
Authentifizierung
Anonyme Anfragen funktionieren, mit engen Limits. Ein Schlüssel hebt sie an und wird als Bearer-Token gesendet. Ein Schlüssel, den wir nicht kennen — auch ein widerrufener —, wird mit 401 abgelehnt statt still auf die anonyme Stufe herabgestuft, und die Ablehnung geht zulasten des Budgets Ihrer IP: Eine stille Herabstufung würde aus einem Tippfehler eine Stunde später einen Rate-Limit-Fehler machen.
Authorization: Bearer $VECTORTRACE_KEY
Schlüssel werden auf Ihrer Kontoseite erstellt und einmalig angezeigt; gespeichert wird nur ein Hash. Sie sind Teil von Pro: 500 Bilder im Monat sind enthalten, jedes weitere Bild kostet 0,02 € und wird über Ihr Abo abgerechnet. Widerrufen Sie einen Schlüssel auf der Kontoseite, funktioniert er ab der nächsten Anfrage nicht mehr. Die Schlüsselverwaltung ist eine Browser-Oberfläche, authentifiziert über das Sitzungs-Cookie und Origin-geprüft — sie ist in der OpenAPI-Datei dokumentiert, damit ein Client die Formen sehen kann, ist aber nicht zum Skripten gedacht.
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
Vektorisieren Sie ein Rasterbild. Senden Sie es als Multipart-Dateiteil oder als Base64 innerhalb eines JSON-Bodys. Die Antwort ist die Vektordatei selbst oder das Dokument als JSON, wenn Sie das anfordern.
PNG · JPG · JPEG · WebP · BMP · GIF
Anfrage
| Teil | Wo | Wert |
|---|---|---|
| image | multipart/form-data | Die Rasterdatei. |
| image | application/json-Body | Dieselbe Datei, Base64-codiert, mit oder ohne data:-Präfix. Verwenden Sie eines der beiden. |
| options | JSON-Body oder Formularfeld | Eine beliebige Teilmenge der unten stehenden Optionen. Weggelassene Felder übernehmen die Werte des benannten Presets. |
| format | Query-String | Was exportiert werden soll. Der Query-Wert gewinnt gegenüber dem Body. |
| Accept | Request-Header | application/json liefert das Dokument und seine Statistiken statt der Datei. |
Beispiele
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-Body
POST /api/v1/vectorize?format=svg
Content-Type: application/json
Accept: application/json
{
"image": "iVBORw0KGgoAAAANSUhEUgAA…",
"options": { "preset": "logo", "colors": 8 }
}Optionen
Jedes Feld ist optional. Ein Preset füllt den Rest aus; ein von Ihnen gesetztes Feld gewinnt gegenüber dem Preset. Das sind dieselben Regler wie im Inspector des Konverters und dieselbe Tabelle, die die Rust-Engine liest.
| Feld | Werte | Standard | Hinweise |
|---|---|---|---|
| preset | logo · line-art · photo · embroidery · vinyl · laser | logo | Benannte Optionssätze. Dieselbe Tabelle wie in der App und in der Rust-Engine. |
| mode | color · binary | color | Binär vektorisiert eine einzelne Farbe; Farbe clustert zunächst eine Palette. |
| colors | 2 – 64 | 16 | Palettengröße nach dem Clustering. Im Binärmodus ignoriert. |
| filterSpeckle | Pixel Fläche | 4 | Regionen, die kleiner als dieser Wert sind, werden verworfen. |
| cornerThreshold | 0 – 180 Grad | 60 | Schärfere Winkel als dieser bleiben scharfe Ecken statt Kurven zu werden. |
| pathPrecision | 0 – 4 | 2 | In die Pfaddaten geschriebene Nachkommastellen. |
| curveFitting | pixel · polygon · spline | spline | Pixel behält die Treppenstufen bei, Polygon passt Linien an, Spline passt Kubiken an. |
| hierarchical | stacked · cutout | stacked | Gestapelt legt Regionen übereinander, Cutout macht jede Region disjunkt. |
| spliceThreshold | 0 – 180 Grad | 45 | Winkel, ab dem eine angepasste Kurve in zwei geteilt wird. |
| lengthThreshold | Pixel | 4 | Kürzeste Polygonkante, die vor der Vereinfachung erhalten bleibt. |
| maxIterations | 1 – 100 | 10 | Budget für die Kurvenanpassung pro Teilpfad. |
Antworten und Fehler
Erfolg
| Status | Content-Type | Body |
|---|---|---|
| 200 | image/svg+xml | Die exportierte SVG-Datei, inline, mit einem serverseitig abgeleiteten Dateinamen. |
| 200 | application/pdf | Die exportierte PDF-Datei, inline, mit einem serverseitig abgeleiteten Dateinamen. |
| 200 | application/postscript | Die exportierte EPS-Datei, inline, mit einem serverseitig abgeleiteten Dateinamen. |
| 200 | image/vnd.dxf | Die exportierte DXF-Datei, inline, mit einem serverseitig abgeleiteten Dateinamen. |
| 200 | image/png | Die exportierte PNG-Datei, inline, mit einem serverseitig abgeleiteten Dateinamen. |
| 200 | application/json | Das Vektordokument und seine Statistiken, mit 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 }
}Jede Antwort trägt die Rate-Limit-Header, ob abgelehnt oder nicht. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Fehler-Envelope
Immer ein einziges Envelope. Verzweigen Sie auf den Code, nie auf den Text — der Code ist stabil, der Text nicht.
{ "error": { "code": "IMAGE_TOO_LARGE", "message": "…" } }| Status | Code | Wann |
|---|---|---|
| 400 | DECODE_FAILED | Die Bytes sind ein Format, das wir akzeptieren, aber nicht dekodieren konnten. |
| 400 | VALIDATION_ERROR | Der Body oder ein Feld entsprach nicht dem Contract. |
| 401 | UNAUTHORIZED | Ein Authorization-Header, den wir nicht lesen konnten, oder ein unbekannter Schlüssel. |
| 413 | IMAGE_TOO_LARGE | Das Bild überschreitet das Pixel-Limit dieser Aufruferklasse. |
| 413 | PAYLOAD_TOO_LARGE | Der Body überschreitet das Byte-Limit dieser Aufruferklasse. |
| 415 | UNSUPPORTED_FORMAT | Für das angeforderte Ausgabeformat gibt es in diesem Build keinen Exporter. |
| 415 | UNSUPPORTED_INPUT_FORMAT | Die Bytes entsprechen keinem der akzeptierten Rasterformate. |
| 429 | RATE_LIMITED | Stundenbudget aufgebraucht. Retry-After sagt, wann Sie wiederkommen können. |
| 500 | ENGINE_ERROR | Der Tracer lief und ist an diesem Bild gescheitert. |
| 500 | INTERNAL_ERROR | Unser Fehler. Einmal erneut versuchen, dann uns Bescheid geben. |
Ratenlimits
| Stufe | Max. Body | Max. Pixel | Anfragen | Gezählt nach |
|---|---|---|---|---|
| Anonym | 2 MB | 1 MP | 20 / Stunde | Client-IP |
| Mit Schlüssel | 20 MB | 16 MP | 600 / Stunde | Schlüssel-Handle |
Ein Bild über dem Pixel-Limit wird abgelehnt, nicht herunterskaliert. Der Konverter in Ihrem Browser verkleinert übergroßes Artwork, weil die Alternative eine Viertel-Gigabyte-Allokation im eigenen Tab wäre; hier ist die Obergrenze ein Budget, und Koordinaten zurückzugeben, die nicht auf das gesendete Artwork passen, wäre schlimmer als ein Fehler.
OpenAPI
Die obige Referenz wird aus denselben Zod-Schemas generiert, mit denen der Server validiert — es gibt also keine handgeschriebene Spezifikation, die veralten könnte. Richten Sie einen Client-Generator darauf aus.
GET https://vectortrace.app/api/openapi.json
llms.txt
Eine Klartext-Zusammenfassung des Produkts, der Seiten und dieses Endpunkts, geschrieben für Sprachmodelle und Agenten. Die vollständige Version ergänzt den Seitenindex und die Preset-Tabelle.
GET https://vectortrace.app/llms.txt GET https://vectortrace.app/llms-full.txt
CLI
Woche 10Die Engine als Kommando. Dieselben Presets, dieselbe Ausgabe, kein Server im Spiel.
npx @vectortrace/cli in.png -o out.svg --preset laser
MCP
Woche 10Ein MCP-Server, der die Engine Agenten über stdio oder streamable HTTP zur Verfügung stellt. Drei Tools:
| Tool | Macht |
|---|---|
| vectorize_image | Vektorisiert ein Bild und liefert ein Dokument-Handle plus Statistiken zurück. |
| list_presets | Liefert die Preset-Tabelle mit jedem Optionswert. |
| export_document | Serialisiert ein Handle in eines der Exportformate. |