Quickstart
Upload a photo, create a product, register a webhook and queue your first render. Four calls, about five minutes.
This walkthrough takes the single-product path so every step is visible. If you are bringing in a catalogue, skip steps 1 and 2 and start from Imports, which fetches the photos for you.
You need an API key. Mint one in the dashboard under Settings → API Keys and keep it in VEETON_KEY; see Authentication for how keys behave.
-
Upload a photo.
Images are uploaded as
multipart/form-data. The type is read from the bytes, so declare whatever you like; JPEG, PNG and WebP up to 10 MB are accepted. The response is an image id you can reference from then on.Terminal window IMG=$(curl -s https://api.veeton.com/v1/images \-H "Authorization: Bearer $VEETON_KEY" \-F "file=@./tee-front.jpg" | jq -r .id) -
Create the product.
A product is your
reference(the SKU in your own system, unique within your organization), aname, and one or more images each labelled with the view it shows.Terminal window PROD=$(curl -s https://api.veeton.com/v1/products \-H "Authorization: Bearer $VEETON_KEY" \-H "Content-Type: application/json" \-d "{\"name\":\"Crewneck Tee\",\"reference\":\"TEE-001\",\"images\":[{\"image_id\":\"$IMG\",\"orientation\":\"front\"}]}" \| jq -r .id) -
Register where to receive results.
Renders take a minute or two. Register an
https://endpoint once and every terminal event is delivered there, signed. Thesigning_secretin the response is shown once; store it.Terminal window curl https://api.veeton.com/v1/webhooks \-H "Authorization: Bearer $VEETON_KEY" \-H "Content-Type: application/json" \-d '{"url":"https://your.app/veeton","events":["task.succeeded","task.failed"]}' -
Queue a render.
Pick the task family that matches what you want back. Both return
202with a taskidimmediately.# A clean render of the product alone, on a chosen backgroundcurl https://api.veeton.com/v1/tasks/beautifier \-H "Authorization: Bearer $VEETON_KEY" \-H "Content-Type: application/json" \-d "{\"subtype\":\"clothing\",\"inputs\":{\"product_id\":\"$PROD\",\"background\":\"#ffffff\",\"angle_shot\":\"front\",\"style\":\"ghost\"}}"# The product worn by a model from GET /v1/modelsMODEL=$(curl -s "https://api.veeton.com/v1/models?limit=1" \-H "Authorization: Bearer $VEETON_KEY" | jq -r .data[0].id)curl https://api.veeton.com/v1/tasks/tryon \-H "Authorization: Bearer $VEETON_KEY" \-H "Content-Type: application/json" \-d "{\"inputs\":[{\"product_id\":\"$PROD\",\"model_id\":\"$MODEL\",\"background\":\"park\",\"angle_shot\":\"full_body_relaxed_symmetric\"}]}"
What happens next
The task moves through queued → running → succeeded | failed. When it reaches a terminal state your webhook receives a task.succeeded or task.failed event with the task id; fetch the task to get the output.
curl https://api.veeton.com/v1/tasks/$TASK \ -H "Authorization: Bearer $VEETON_KEY"{ "id": "01HX5K2MZ7A3Q4FBNDC0EVDXY2", "type": "beautifier", "subtype": "clothing", "status": "succeeded", "product_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1", "output_image": { "id": "01HX5K2MZ7A3Q4FBNDC0EVDXYS", "url": "https://…signed…", "url_expires_at": "2026-09-03T15:32:00Z" }, "failure_reason": null, "started_at": "2026-09-03T14:30:12Z", "finished_at": "2026-09-03T14:31:40Z", "created_at": "2026-09-03T14:30:09Z"}Signed URLs last one hour. The image id is permanent: re-fetch a fresh URL with GET /v1/images/{id} rather than re-running anything.
Where to go from here
- Imports for catalogue-sized ingestion.
- Tasks for the full set of inputs, backgrounds and models.
- Exports to read everything back into a PIM or DAM.
- The API reference for every field.