Skip to content

API reference, v1

VectoSolve API

Base URL https://vectosolve.com/api/v1. JSON in, JSON out, except /vectorize which takes a multipart form. Building a platform integration? See the Platform plan. The machine-readable spec is at /openapi.json.

Authentication

Create a key in your dashboard (up to 5 per account). Keys start with vs_ and are shown once. Send it as a bearer token on every call. A key can be locked to a list of browser origins; server-to-server calls are never blocked by that lock.

curl https://vectosolve.com/api/v1/credits \
  -H "Authorization: Bearer vs_your_key"

A missing, revoked or mistyped key answers 401 with { "success": false, "error": "Invalid or inactive API key" }.

Vectorize one image

POST /vectorize, multipart form. Send file (PNG, JPG, WebP, GIF) or image_url (public https link).

FieldValuesDefault
modestandard, laser, cricut, embroidery, centerlinestandard
output_formatsvg, dxfsvg
exportscomma list of pdf, eps, ai, png, returned in the same responsenone
dxf_version, unitsR12 or AC1015; mm, cm or inR12, mm
colors, palettelimit the number of colors, or force a paletteautomatic
verifytrue: adds a fidelity report against the sourcefalse
curl https://vectosolve.com/api/v1/vectorize \
  -H "Authorization: Bearer vs_your_key" \
  -F image_url=https://example.com/logo.png \
  -F mode=laser -F output_format=dxf
{
  "success": true,
  "data": {
    "svg": "<svg ...>",
    "dxf": "0\nSECTION ...",      // when output_format=dxf
    "svg_url": "https://...",
    "format": "dxf",
    "mode": "laser",
    "source_quality": { ... },
    "processing_time_ms": 6200
  }
}

Batch

POST /batch, JSON. Up to 25 images per call, 3 processed in parallel. Each item takes a public url, an operation (vectorize, remove_bg, upscale) and an optional mode(standard, laser, cricut, embroidery). Failed items are refunded; the others are charged.

curl https://vectosolve.com/api/v1/batch \
  -H "Authorization: Bearer vs_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "standard",
    "images": [
      { "url": "https://example.com/a.png", "operation": "vectorize" },
      { "url": "https://example.com/b.jpg", "operation": "vectorize", "mode": "cricut" }
    ]
  }'

Background jobs

Add "async": true to a batch call to get 202 and a job_id right away, then poll GET /jobs/{job_id} or wait for the webhook. A job is processing, completed (with results) or failed.

{ "images": [ ... ], "async": true, "webhook_url": "https://your-app.com/hooks/vectosolve" }

GET https://vectosolve.com/api/v1/jobs/9b2c...  ->  { "status": "completed", "results": [ ... ], "webhook_status": "delivered" }

Webhooks

When a background job ends we POST to your webhook_url (https only), with one retry after 30 seconds. Every call carries a VectoSolve-Signature header. Read your signing secret once with GET /webhook-secret, then check each call before trusting it.

POST https://your-app.com/hooks/vectosolve
VectoSolve-Signature: t=1762200000,v1=5f1c...
{ "event": "job.completed", "job_id": "9b2c...", "status": "completed",
  "total_items": 25, "failed_items": 1, "created": 1762200000 }
// Node.js: verify before using the payload
import { createHmac, timingSafeEqual } from 'node:crypto'

function verify(secret, rawBody, header) {
  const { t, v1 } = Object.fromEntries(header.split(',').map((x) => x.split('=')))
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')
  return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(v1, 'hex'))
}

Machine and print formats

POST /export converts an SVG you already have (svg_content) into another format: gcode, eps, ai, dst, pes, jef, pdf, png, dxf. GET /export lists the options of each format.

Balance

GET /credits is free and returns your balance, the conversions it covers and your limits. Call it before sending a large batch.

{ "success": true, "credits": { "balance": 27.27, "remaining_conversions": 136 },
  "limits": { "per_minute": 60, "daily_spend_cap_usd": 5 } }

Limits and idempotency

  • 60 requests per minute per key by default. A batch counts one request per image. Over the limit: 429 with Retry-After.
  • A daily spend cap protects your balance; it rises with your balance and plan. Platform accounts get custom limits.
  • Images up to 10 MB. URLs must be public https links.
  • Paid calls accept an Idempotency-Key header: a retry with the same key within 24 hours returns the first result and is not charged twice.

Errors

400Invalid input: the error message names the field.
401Missing or invalid API key.
402Not enough credits. Nothing was charged.
422The image could not be converted. Refunded.
429Rate limit or daily spend cap reached.
502 / 503Temporary upstream problem. Refunded; retry with the same Idempotency-Key.

Billing

Self-serve keys draw on your credit balance: one vectorization costs 0.20 credit, the same as on the website. On the Platform plan, usage is billed monthly by Stripe: one billable file per successful vectorization (credits used divided by 0.20, at least 1 per request), 10,000 files included in the $499 minimum, then $0.05 per file. Every call is listed in your usage log.