Product Images Service
Overview
Product Images manage the visual assets associated with products and their variants.
An image record can be linked at two levels:
- product level —
Variant Idisnull, image belongs to the product itself - variant level —
Variant Idis set, image is specific to that variant
This allows products to carry shared gallery images while also supporting variant-specific imagery (e.g. different photos per colour variant).
The Products service aggregates all images into the product response:
- all images appear in the top-level
Imagesarray - variant-specific images also appear nested inside each variant's
Imagesarray
All operations are tenant-aware and scoped to the current tenant.
Endpoints
GET
/api/v1/ProductImages/product/{productId}
Returns all images associated with a given product.
Behavior:
- Returns both product-level and variant-level images for the product
- Results are ordered by
Sort Order - Returns
404if no images exist for the product
Authorization:
- No authentication required
GET
/api/v1/ProductImages/variant/{variantId}
Returns all images associated with a specific product variant.
Behavior:
- Returns only images where
Variant Idmatches the givenvariantId - Results are ordered by
Sort Order - Returns
404if no images exist for the variant
Authorization:
- No authentication required
GET
/api/v1/ProductImages/{id}
Returns a single product image by its identifier.
Behavior:
- Looks up image by
Id - Returns
404if the image does not exist
Authorization:
- No authentication required
POST
/api/v1/ProductImages
Adds a new image to a product or variant.
Request body:
Product Id(long, required) - the parent productURL(string, required) - publicly accessible image URLVariant Id(long, optional) - if set, image is scoped to that variantAlt Text(string, optional) - accessibility descriptionIs Primary(bool, optional) - marks this image as the primary imageSort Order(int, optional) - display order
Behavior:
- Validation is handled in the service layer
- If
Variant Idis omitted, the image is assigned to the product level - Successful creation writes an audit log entry
Errors:
- Returns
400if validation fails
Authorization:
- Requires Bearer Token
PUT
/api/v1/ProductImages/{id}
Updates an existing product image.
Request:
- Image ID is taken from the route
- Body must include:
Id(long, required)Product Id(long, required)URL(string, required)
- Optional:
Variant Id(long)Alt Text(string)Is Primary(bool)Sort Order(int)
Behavior:
- All provided fields overwrite existing values
- Successful update writes an audit log entry
Errors:
- Returns
400if validation fails or image does not exist
Authorization:
- Requires Bearer Token
DELETE
/api/v1/ProductImages/{id}
Deletes a product image by its identifier.
Behavior:
- Performs a hard delete
- Record is permanently removed from the database
- Successful deletion writes an audit log entry
Errors:
- Returns
400if image does not exist or deletion fails
Authorization:
- Requires Bearer Token
Notes
- Validation is enforced in the service layer, not via model attributes
- Images without a
Variant Idare considered product-level images - The Products service includes all images at the product level and distributes variant images into each variant's nested response
Is Primaryflag is not enforced as unique — consumers should treat the first primary image found as the main image- All state-changing operations are audited
- Internal errors are logged but not exposed to clients