Product variants
SKUs of a product (sizes, colors, bundles) that carry their own images for ad generation.
A product variant is a specific SKU of a product — a size, color, bundle, or other variation. Each variant has its own ordered list of images that the API uses during image ad generation.
Mental model
If your product is "Trail Runner Pro", variants are "Red / 10", "Black / 11", "Limited Edition Blue". When you generate an image ad and pass product_variant_id, the API uses that variant's images instead of the default product images. Useful when different SKUs need different hero shots.
ID prefix: pv_.
Fields
| Field | Type | Description |
|---|---|---|
id | string | pv_… |
product_id | string | Owning product (prod_…) |
name | string | Variant name (e.g., "Red / Large") |
sort_order | number | Display sort order |
image_ids | string[] | Ordered list of image IDs (img_…) for this variant |
duplicated_from_id | string | null | The variant this one was duplicated from, if any |
created_at / updated_at | string | ISO timestamps |
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/product-variants | Create a variant |
GET | /v1/product-variants | List variants |
GET | /v1/product-variants/:id | Get a variant |
PATCH | /v1/product-variants/:id | Update a variant |
DELETE | /v1/product-variants/:id | Delete a variant |
POST | /v1/product-variants/:id/duplicate | Duplicate a variant |
Common patterns
Create a variant with images
const response = await fetch("https://api.staticadslab.com/v1/product-variants", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
product_id: "prod_YOUR_PRODUCT_ID",
name: "Red / Large",
image_ids: ["img_red_lg_hero", "img_red_lg_lifestyle"],
}),
});Use a variant when generating an image ad
await fetch("https://api.staticadslab.com/v1/image-ads", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({
reference_ad_url: "https://cdn.example.com/reference-ad.png",
brand_id: "brand_...",
product_id: "prod_...",
audience_id: "aud_...",
product_variant_id: "pv_red_lg",
}),
});Duplicate a variant to reshoot it
The most common reason to duplicate: you want the same SKU shot with a different model or in a different setting. The copy arrives attached to the same images, so you swap them out rather than starting from an empty variant.
const response = await fetch(
"https://api.staticadslab.com/v1/product-variants/pv_red_lg/duplicate",
{
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY" },
},
);
const { data } = await response.json();
// data.name → "Red / Large - copy"
// data.duplicated_from_id → "pv_red_lg"
// data.image_ids → same image IDs as the source
// Replace the photos on the copy. The source variant is untouched: attaching
// and detaching edits this variant's list, not the image records themselves.
await fetch(`https://api.staticadslab.com/v1/product-variants/${data.id}`, {
method: "PATCH",
headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ image_ids: ["img_new_model_01", "img_new_model_02"] }),
});Pitfalls
- Duplicating shares image records rather than copying files. Detaching an image from the copy leaves the original variant's images intact, but deleting an image through
/v1/images/:idremoves it everywhere it is attached. - Variants have no
descriptionfield. Variant-specific copy comes from the product description and the audience. image_idsorder matters — the API treats earlier IDs as primary candidates for hero shots.- A variant must belong to a product in the same brand as the image ad request.
Related
Prompt for your agent
Read https://www.staticadslab.com/docs/resources/product-variants.mdx and create variants for product prod_YOUR_PRODUCT_ID. I have a CSV with columns name, image_urls — for each row, upload the images, then create the variant with those image IDs.