Reference — API

API Documentation

Integrate Vectorgram into your application. One endpoint to submit, one to poll, one to download — jobs are asynchronous by design. Base URL https://api.vectorgram.ai, authentication is Authorization: Bearer <api_key>. Keys look like vectorgram_sk_live_… — the prefix is deliberately spelled out, so a key found in an old .env can be identified without being tried.

A new account gets 25 API conversions free for 30 days — full quality, no watermark. After that the API needs a plan that includes it (Pro and above), and calls come out of that plan's monthly allowance. There is no overage: past the allowance calls answer 402 with the reset date. GET /v1/account reports both allowances and what is left of each.

Quick start

1 — Get your API key

Your API keys

Loading…

2 — Submit an image

curl -X POST https://api.vectorgram.ai/v1/vectorize \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: 8f1b0c2e-0a1d-4f77-9c3a-2b6e5d4c1a90" \
  -F "file=@image.png" \
  -F "image_type=clipart" \
  -F "detail=high" \
  -F "gradients=smooth" \
  -F "smoothing=strong" \
  -F "retention=24h"

The response is 202 Accepted with a queued job — conversion has not happened yet. Sending the same request twice with one Idempotency-Key returns the first job rather than making a second; changing the file or the settings under a key already used is a 409.

3 — Poll, or take a webhook

GET /v1/jobs/job_abc123

{
  "id": "job_abc123",
  "status": "queued",
  "progress": 0,
  "queue_position": 3,
  "mode": "logo",
  "retention": "24h",
  "megapixels": 2.1,
  "created_at": "2026-08-03T10:30:00Z"
}

status walks queued processing completed | failed | canceled | expired. While queued you get a real queue_position rather than an invented countdown; progress during processing is interpolated from the size estimate and caps at 95% until the file exists. Large images can take minutes — poll at a sane interval or, better, register a webhook.

4 — Download

{
  "id": "job_abc123",
  "status": "completed",
  "progress": 100,
  "download_url": "https://api.vectorgram.ai/v1/jobs/job_abc123/download",
  "completed_at": "2026-08-03T10:30:04Z",
  "expires_at": "2026-08-04T10:30:04Z"
}

download_url appears only once a result exists, needs the same bearer token, and streams the file as an attachment. With retention=none the file is deleted as it is served — download it once.

Conversion parameters

All fields are multipart form data on POST /v1/vectorize. The three marked manual are the trace controls: available on Pro, Studio, Agency and Enterprise. On Free and Lite they are accepted and then replaced with the defaults rather than rejected, so a client that always sends them still converts — it just gets the automatic result.

filePNG, JPEG, WebP, AVIF or BMP, ≤ 50 MB

Required. The image to convert. Detected from its bytes, not its filename.

image_typeauto · clipart · photo · scan · blueprint

What kind of image this is. Default auto, which lets the engine classify it.

output_formatsvg

Optional, and svg is the only value. SVG is what the engine writes and nothing converts it into anything else — EPS, PNG, PDF, DXF and AI are refused with 400 unsupported_output_format rather than queued to fail.

retentionnone · 24h · 3d · 7d · 10d

How long the result is kept. Default 24h; none deletes it after the first download. Clamped to your plan's maximum rather than rejected — Free cannot hold a result for 10 days by asking for it.

batch_idany string

Your own grouping key, echoed back on the job and usable as a filter. Submit one request per image. Batch conversion starts on Pro (30 files, 50 on Studio, 100 on Agency); below it the group holds one file and a second answers 400 batch_limit_exceeded.

folder_nameany string

The name of the folder the batch's files will lie in on the dashboard. Optional and requires batch_id (400 invalid_folder_name otherwise); bounded like batch_id — 128 characters, no control characters. The first file admitted names the folder; later files of the batch do not rename it. Left out, the folder is stamped with its creation date.

detailmanuallow · medium · high

How much of the image survives region merging. Default high — the loosest step the engine has since 1.3.0. A 1–100 slider value is accepted and bucketed.

gradientsmanualauto · smooth · stepped

Gradient handling. Default smooth; stepped and auto leave the engine's flat fills.

smoothingmanualoff · light · strong · maximum

Corner rounding. Default strong — real corners stay sharp, only what the tracer rounded off by accident comes back. A 0–100 slider value is accepted and bucketed.

Endpoints

POST/v1/vectorize
GET/v1/jobs
GET/v1/folders
DELETE/v1/folders/{id}
GET/v1/jobs/{id}
GET/v1/jobs/{id}/download
DELETE/v1/jobs/{id}
POST/v1/jobs/{id}/report
GET/v1/account
GET/v1/keys
POST/v1/keys
DELETE/v1/keys/{id}
GET/v1/webhooks
POST/v1/webhooks
DELETE/v1/webhooks/{id}

The generated reference — every field, every response shape — is the Swagger UI the service serves at /docs/swagger, with the OpenAPI document at /v3/api-docs.

Webhooks

Because jobs run asynchronously — minutes for large files — subscribe to webhooks instead of polling. Register an endpoint with POST /v1/webhooks; the signing secret is returned once, at creation, and never again.

processing.started
processing.completed
processing.failed
POST https://your-app.example/hooks/vectorgram
X-Vectorgram-Event: processing.completed
X-Vectorgram-Signature: sha256=<hmac of the raw body, hex>

{
  "id": "evt_9f2c…",
  "event": "processing.completed",
  "created_at": "2026-08-03T10:30:04Z",
  "data": { "job_id": "job_abc123", "status": "completed" }
}

Verify the signature by computing HMAC-SHA256 of the raw request body with your endpoint secret and comparing it in constant time — treat a mismatch as an unauthenticated request. Delivery is at least once: a non-2xx response is retried three times with exponential backoff, so make your handler idempotent on id. Endpoints must resolve to a public address; that is re-checked at delivery time, not just at registration.

Errors

Failures are JSON: { "error": { "code": "…", "message": "…", "details": { … } } }. Read code, not the message — messages get reworded.

400missing_file
400unreadable_file
400empty_file
400batch_limit_exceeded
400invalid_batch_id
400invalid_folder_name
401unauthorized
402quota_exhausted
402megapixels_exceeded
402high_detail_not_included
403forbidden
404not_found
409not_ready
409idempotency_key_reuse
409request_in_progress
410result_expired
413file_too_large
415unsupported_format
429too_many_active_jobs
429daily_fuse_tripped
503queue_full
503storage_full