API
esc

Type to search.

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.

  1. 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)
  2. Create the product.

    A product is your reference (the SKU in your own system, unique within your organization), a name, 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)
  3. Register where to receive results.

    Renders take a minute or two. Register an https:// endpoint once and every terminal event is delivered there, signed. The signing_secret in 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"]}'
  4. Queue a render.

    Pick the task family that matches what you want back. Both return 202 with a task id immediately.

    # A clean render of the product alone, on a chosen background
    curl 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/models
    MODEL=$(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.

Terminal window
curl https://api.veeton.com/v1/tasks/$TASK \
-H "Authorization: Bearer $VEETON_KEY"
200 OK
{
"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.