API reference
Products
A product is one SKU: your reference, a name and the photos you hold for it. Everything else in the API hangs off a product — renders are generated from it, exports are grouped by it.
The Product object
Attributes
idstringCrockford-base32 ULID (26 chars).namestringreferencestringdescriptionstring, nullablesexenum, nullablemalefemaleotherkid
imagesarray of objectsShow child attributesHide child attributes
idstringCrockford-base32 ULID (26 chars).orientationstringoriginenumuserbeautifierother
created_attimestampWhen the product was created. For products that predate timestamp tracking (2026-09), the date of its first image.updated_attimestampLast change to the product's own fields (name, reference, description, sex). Attaching or removing images does not bump it; use the export delta for asset changes.
The Product object
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"description": "A short description.",
"sex": "male",
"images": [
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front",
"origin": "user"
}
],
"created_at": "2026-04-27T14:32:00Z",
"updated_at": "2026-04-27T14:32:00Z"
}Create a product
POST/v1/products
The single-product path. Two steps:
- Upload each image with
POST /v1/images(multipart). You get back an image_id. - Call this endpoint with the image_ids and the orientation each one represents.
Creating more than a handful? Use POST /v1/imports: one JSON line per product with the URLs of its photos, fetched by us, validated whole, processed as a job, retry-safe by reference. This endpoint stays supported for one-at-a-time creation (a back-office form, a manual fix) — it is simply the wrong shape for a catalogue.
Image references must belong to the calling organization and not be soft-deleted. The same image_id can be referenced by multiple Products if you want to reuse a shot.
Parameters
namestringrequiredreferencestringrequiredYour own product code (e.g. the SKU in your PIM). Required and unique within your organization for products created through the API; surrounding whitespace is trimmed.descriptionstringoptionalsexenumoptionalmalefemaleotherkid
imagesarray of objectsrequiredReferences to images previously uploaded via POST /v1/images. Each entry pairs an image_id with the orientation it represents on this Product.Show child attributesHide child attributes
image_idstringrequiredID returned from POST /v1/images.orientationenumrequiredPossible enum values (11)
frontbackleftrighttopbottomthree-quarter-leftthree-quarter-rightdetailunlabeledside
Returns
Returns a Product object with status 201.
Errors
400Invalid request
401Unauthorized
404One or more image_ids not found
409A product with this reference already exists in the organization
500Server error
POST/v1/products
curl https://api.veeton.com/v1/products \
-H "Authorization: Bearer $VEETON_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"images": [
{
"image_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front"
}
]
}'Response · 201
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"description": "A short description.",
"sex": "male",
"images": [
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front",
"origin": "user"
}
],
"created_at": "2026-04-27T14:32:00Z",
"updated_at": "2026-04-27T14:32:00Z"
}List products
GET/v1/products
Cursor-paginated list. Soft-deleted Products are excluded.
Parameters
limitinteger· queryoptionalcursorstring· queryoptionalqstring· queryoptionalFree-text search over name and reference.
Returns
Returns a ProductList object with status 200.
Errors
400Invalid request
500Server error
GET/v1/products
curl https://api.veeton.com/v1/products \
-H "Authorization: Bearer $VEETON_KEY"Response · 200
{
"data": [
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"description": "A short description.",
"sex": "male",
"images": [
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front",
"origin": "user"
}
],
"created_at": "2026-04-27T14:32:00Z",
"updated_at": "2026-04-27T14:32:00Z"
}
],
"next_cursor": "eyJpZCI6InByb2RfMDFIWCJ9",
"has_more": true
}Retrieve a product
GET/v1/products/{product_id}
Parameters
product_idstringrequiredCrockford-base32 ULID (26 chars).
Returns
Returns a Product object with status 200.
Errors
404Not found
500Server error
GET/v1/products/{product_id}
curl https://api.veeton.com/v1/products/01HX5K2MZ7A3Q4FBNDC0EVDXY1 \
-H "Authorization: Bearer $VEETON_KEY"Response · 200
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"description": "A short description.",
"sex": "male",
"images": [
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front",
"origin": "user"
}
],
"created_at": "2026-04-27T14:32:00Z",
"updated_at": "2026-04-27T14:32:00Z"
}Update a product
PATCH/v1/products/{product_id}
JSON Merge Patch semantics. Omitted fields are unchanged; explicit null clears a nullable field. To attach more images, use POST /v1/products/{product_id}/images with image_ids returned from POST /v1/images.
Parameters
product_idstringrequiredCrockford-base32 ULID (26 chars).
Body · application/merge-patch+json
namestringoptionalreferencestringoptionaldescriptionstring, nullableoptionalsexenum, nullableoptionalmalefemaleotherkid
Returns
Returns a Product object with status 200.
Errors
404Not found
409Another product in the organization already uses the new reference
500Server error
PATCH/v1/products/{product_id}
curl -X PATCH \
https://api.veeton.com/v1/products/01HX5K2MZ7A3Q4FBNDC0EVDXY1 \
-H "Authorization: Bearer $VEETON_KEY" \
-H "Content-Type: application/merge-patch+json" \
-d '{
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"description": "A short description.",
"sex": "male"
}'Response · 200
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"name": "Crewneck Tee — Sage",
"reference": "TEE-SAGE-001",
"description": "A short description.",
"sex": "male",
"images": [
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front",
"origin": "user"
}
],
"created_at": "2026-04-27T14:32:00Z",
"updated_at": "2026-04-27T14:32:00Z"
}Delete a product
DELETE/v1/products/{product_id}
Parameters
product_idstringrequiredCrockford-base32 ULID (26 chars).
Returns
An empty response with status 204.
Errors
404Not found
500Server error
DELETE/v1/products/{product_id}
curl -X DELETE \
https://api.veeton.com/v1/products/01HX5K2MZ7A3Q4FBNDC0EVDXY1 \
-H "Authorization: Bearer $VEETON_KEY"Attach images to a product
POST/v1/products/{product_id}/images
Reference image_ids returned from POST /v1/images. Each entry pairs an image_id with the orientation it represents on this Product.
Parameters
product_idstringrequiredCrockford-base32 ULID (26 chars).
Body · application/json
imagesarray of objectsrequiredShow child attributesHide child attributes
image_idstringrequiredID returned from POST /v1/images.orientationenumrequiredPossible enum values (11)
frontbackleftrighttopbottomthree-quarter-leftthree-quarter-rightdetailunlabeledside
Returns
Returns array of objects with status 201.
Errors
404Product or image_id not found
500Server error
POST/v1/products/{product_id}/images
curl https://api.veeton.com/v1/products/01HX5K2MZ7A3Q4FBNDC0EVDXY1/images \
-H "Authorization: Bearer $VEETON_KEY" \
-H "Content-Type: application/json" \
-d '{
"images": [
{
"image_id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front"
}
]
}'Response · 201
[
{
"id": "01HX5K2MZ7A3Q4FBNDC0EVDXY1",
"orientation": "front",
"origin": "user"
}
]Remove an image from a product
DELETE/v1/products/{product_id}/images/{image_id}
Removes the link between this Product and this Image. The image asset itself is not immediately destroyed — images that are no longer associated with any Product or Task are cleaned up automatically after a while, so you do not need to manage their lifecycle.
Returns 422 with cannot_drop_last_image when the Product would be left with zero images. Delete the Product instead in that case.
Parameters
product_idstringrequiredCrockford-base32 ULID (26 chars).image_idstringrequiredCrockford-base32 ULID (26 chars).
Returns
An empty response with status 204.
Errors
404Product or image-on-this-product not found
422Cannot drop the last image
DELETE/v1/products/{product_id}/images/{image_id}
curl -X DELETE \
https://api.veeton.com/v1/products/01HX5K2MZ7A3Q4FBNDC0EVDXY1/images/01HX5K2MZ7A3Q4FBNDC0EVDXY1 \
-H "Authorization: Bearer $VEETON_KEY"