API
esc

Type to search.

Generating renders

Two task families on one workflow. The Product beautifier renders the product alone on a background; a photo shoot puts it on a model. Both return a task you poll or subscribe to.

Every task shares the same shape: the same authentication, the same lifecycle queued → processing → completed | failed, the same delivery contract. Pick the endpoint by what you want back.

Product beautifier

POST/v1/tasks/beautifier

A clean render of the product alone on a chosen background. subtype selects the flow.

Subtype Inputs
clothing style is required: ghost_mannequin (“Ghost mannequin” in the dashboard) or flatlay. angle_shot names which uploaded view to render from (front or back).
shoes style is forbidden. angle_shot is the desired output view from the shoes catalog. The product needs at least one user-uploaded photo.
headwear Same shape as shoes, with the headwear angle catalog.
glasses Same shape as shoes, with the glasses angle catalog.
bags Same shape as shoes, with the bags angle catalog. top_open needs a photo of the bag open: without one the task fails and is not billed.
Terminal window
curl https://api.veeton.com/v1/tasks/beautifier \
-H "Authorization: Bearer $VEETON_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"subtype": "clothing",
"inputs": { "product_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1", "background": "#ffffff",
"angle_shot": "front", "style": "ghost_mannequin" }
}'

background is a slug from the backgrounds catalog, shared by every beautifier subtype. Hex-coded slugs include the leading # and are case-insensitive. The full galleries of backgrounds, angle shots and styles are in the API reference.

Photo shoot

POST/v1/tasks/tryon

The product worn by a model, on a scene of your choice. A photo shoot (tryon) has a single flow: the product’s own type drives the worker, so there is no subtype.

Terminal window
curl https://api.veeton.com/v1/tasks/tryon \
-H "Authorization: Bearer $VEETON_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"inputs": [
{ "product_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"model_id": "01HX5K2MZ7A3Q4FBNDC0EVDXMD1",
"outfit_product_ids": ["01HX5K2MZ7A3Q4FBNDC0EVDXPN"],
"background": "park",
"angle_shot": "full_body_relaxed_symmetric",
"gaze": "camera" }
]
}'
Input Meaning
product_id The main product. Must be yours and have at least one user-uploaded photo.
model_id A model from GET /v1/models: Veeton-curated public models and models generated by your organization share one id space. Treat ids as opaque.
outfit_product_ids The styling items: up to 10 more products worn alongside the main one (main is a top, styling is pants and shoes). Cannot include the main product.
background A slug from the photo shoot catalog: every Product beautifier category plus indoor and outdoor scenes.
angle_shot A slug from the angle shots catalog. Your organization’s custom angle shots are accepted too.
gaze The dashboard’s “Gaze”: auto (default) keeps the gaze of the angle shot, camera makes the model look into the lens (a back view keeps its pose), away makes the model look away.
aspect_ratio The shape of the output, width/height: auto (default) or one of 1/1, 2/3, 3/4, 4/5, 9/16, 3/2, 4/3, 16/9. auto follows the angle shot: a square angle shot gives a square image, as a photo shoot launched from the dashboard with Format on Auto does. An explicit ratio overrides it and the framing adapts to it.

The body is always an array of 1 to 20 inputs and the response is always { "data": Task[] }, one task per input in submission order.

Consistency groups

Inputs that share the same model_id, product_id and outfit_product_ids are dispatched together as a consistency group: identity and styling are computed once and reused, so the outputs look like one set. Vary angle_shot, background or gaze across the entries of one request to get coherent variants. Separate requests do not share a group.

Validation

If any input fails validation the whole request is refused with 400 and every bad input listed, so you never retry-and-bisect.

400 Bad Request
{
"errors": [
{ "input_index": 1, "type": "not_found", "code": "model_not_found", "param": "model_id",
"message": "Model 01HX… was not found." }
]
}

Edit with AI

POST/v1/tasks/edit

Change a finished result with a prompt. Name the image to edit and say what you want changed.

Request
{
"inputs": {
"image_id": "01HX5K2MZ7A3Q4FBNDC0EVDXIM",
"prompt": "Remove the wrinkle on the left sleeve."
}
}

You can edit the output of a completed beautifier or tryon task, or of a completed edit. Your own uploaded photos, and results still running or that failed, are refused with 422 image_not_editable.

An edit makes a new image with its own id. The image you named never changes, and neither does its task’s output_image. Both images are listed in GET /v1/images and in exports, and the new one names its source in edited_from_image_id. To follow a chain of edits, an image nothing was edited from is the end of it. Which version to publish is your choice.

Reading a task

GET/v1/tasks/{task_id}
200 OK
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY2",
"type": "tryon",
"subtype": null,
"status": "completed",
"product_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"inputs": { "product_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1", "background": "wood", "angle_shot": "front", "style": "ghost_mannequin" },
"output_image": { "id": "01HX…", "mime_type": "image/webp", "width": 1536, "height": 2048, "url": "https://…signed…", "url_expires_at": "2026-09-03T15:32:00Z", "created_at": "2026-09-03T14:31:40Z" },
"failure_reason": null,
"started_at": "2026-09-03T14:30:12Z",
"finished_at": "2026-09-03T14:31:40Z",
"created_at": "2026-09-03T14:30:09Z"
}

inputs echoes what the task was created with, so a task can be understood on its own. output_image is set once the task has completed and is the same Image object every endpoint returns. Its id is an image id: use it with GET /v1/images/{id} for a fresh URL, and it is what the export lists under the product with role: beautifier or tryon.

GET/v1/tasks lists your tasks newest first with status, type, subtype and product_id filters. Use it for reconciliation after webhook downtime; the canonical “tell me when it finishes” channel is a webhook.

Billing

Each task consumes credits from your subscription when it is created. A request without an active subscription or with insufficient credits is refused with 402 payment_required and nothing is queued. A task that fails to dispatch is marked failed and refunded.