AI Beauty Product Photography API — Shade and Packaging Variants
A cosmetics brand launching a lipstick line in 18 shades has one hero photo of the product from its manufacturer, but the storefront needs a clean bottle-and-swatch shot for every shade before launch day. Re-shooting the same bottle 18 times under studio lighting just to swap the lipstick color and swatch is a full day with a photographer, a light box, and careful color matching against the actual pigment. Generating each shade variant from the one reference photo removes the reshoot and keeps every listing on the same lighting setup by construction.
Direct answer: a reference-guided image generation API takes one product photo as image input plus a prompt describing the target shade or packaging change, and outputs a new image that holds the bottle geometry and label layout consistent while altering only the requested attribute — no separate photo shoot per variant.
How Does an API Generate Shade Variants From One Product Photo?
Reference-guided generation anchors the output to the shape, proportions, and label placement of the source image, then applies the color or texture change described in the prompt. This differs from text-to-image generation, which has no source object to match and would produce a plausible-looking lipstick rather than the exact packaging shipping to retailers.
Color accuracy is a prompt-level detail: describing the shade by name and a reference descriptor ("warm terracotta, matte finish" rather than just "orange") gives the model a tighter target than a bare color word, since cosmetics shade names carry finish and undertone information a single hue value doesn't capture.
Which Model Fits Beauty Product Photography?
Nano Banana Pro's reference-guided mode holds bottle shape and label text legible across shade and background changes, which matters for cosmetics because a warped cap or shifted logo reads as a counterfeit-looking listing rather than a rendering artifact. GPT-image-2 fits smaller instruction-based edits — a background swap or crop — on a photo that's otherwise already final.
| Model | Mode | Resolution / price | Label/shape consistency | Best for |
|---|---|---|---|---|
| Nano Banana Pro | Reference-guided | 1K $0.030 / 2K $0.030 / 4K $0.042 | High | Full shade-range variants from one base photo |
| Nano Banana 2 | Reference-guided | 1K $0.020 / 4K $0.036 | Medium-high | Lower-cost draft pass before a final render |
| GPT-image-2 | Instruction-based edit | $0.014/image | N/A (edits existing photo) | Background swap or crop on a near-final shot |
For a full shade-range launch, Nano Banana Pro at 2K is worth the small premium over Nano Banana 2 — legible label text and an accurate cap shape matter more on a symmetric bottle than on most product categories, since any drift is immediately visible next to the other 17 shades on the same page.
How Do I Generate a Shade Variant via API?
Submit the base product photo as image input with a prompt naming the target shade and finish; the endpoint returns a job ID to poll for the finished image.
import requests
import time
API_KEY = "YOUR_GENRELAY_KEY"
BASE_URL = "https://genrelay.ai/v1"
def submit_job(image_url, prompt, model="nano-banana-pro", resolution="2k"):
r = requests.post(
f"{BASE_URL}/images/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": model,
"mode": "reference-guided",
"image_url": image_url,
"prompt": prompt,
"resolution": resolution,
},
timeout=30,
)
return r.json()["id"]
def poll_job(job_id, interval=3, timeout=60):
elapsed = 0
while elapsed < timeout:
r = requests.get(
f"{BASE_URL}/images/generations/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = r.json()
if data["status"] in ("completed", "failed"):
return data
time.sleep(interval)
elapsed += interval
raise TimeoutError(f"job {job_id} did not finish in {timeout}s")
job_id = submit_job(
"https://cdn.example.com/lipstick/base-satin-nude.jpg",
"Same lipstick bottle and cap, warm terracotta matte shade, matching lipstick "
"swatch smear beside the bottle, white seamless background, soft studio lighting",
)
result = poll_job(job_id)
print(result.get("output_url"))
How Do I Generate a Full Shade Range Across a Catalog?
Loop each base product against its shade list, submitting with bounded concurrency so an 18-shade launch doesn't queue sequentially.
from concurrent.futures import ThreadPoolExecutor
BASE_PRODUCT = "https://cdn.example.com/lipstick/base-satin-nude.jpg"
SHADES = [
"warm terracotta, matte finish",
"dusty rose, satin finish",
"deep berry, matte finish",
"soft coral, glossy finish",
]
def build_prompt(shade):
return (
f"Same lipstick bottle and cap, {shade} shade, matching lipstick swatch "
"smear beside the bottle, white seamless background, soft studio lighting"
)
def generate_shade(shade):
job_id = submit_job(BASE_PRODUCT, build_prompt(shade))
return shade, poll_job(job_id)
with ThreadPoolExecutor(max_workers=4) as pool:
results = list(pool.map(generate_shade, SHADES))
for shade, r in results:
print(f"{shade}: {r.get('output_url')}")
See the batch image generation guide for retry and concurrency patterns at larger catalog sizes, such as a full 18-shade launch across multiple product lines.
How Do I Keep Swatches and Backgrounds Consistent Across the Line?
Reusing the same background, lighting, and swatch-placement phrasing across every prompt in a batch is what keeps a shade-range grid looking shot in one session — the model has no memory between calls, so consistency comes from the prompt text staying fixed while only the shade name changes. See the visual consistency guide for prompt-structuring patterns that extend to any repeated-object catalog, from lipstick to eyeshadow palettes.
What Does a Full Shade-Range Launch Cost?
As of September 2026, GenRelay per-image pricing: Nano Banana Pro $0.030 at 1K/2K resolution, Nano Banana 2 $0.020 at 1K, GPT-image-2 $0.014.
An 18-shade launch at 2K via Nano Banana Pro is 18 × $0.030 = $0.54. Adding a lower-cost draft pass with Nano Banana 2 for internal shade approval before the final render costs an extra 18 × $0.020 = $0.36, for a combined workflow total of $0.54 + $0.36 = $0.90.
| Approach | Composition | Cost |
|---|---|---|
| Nano Banana Pro only (2K) | 18 shades | $0.54 |
| Nano Banana 2 draft + Pro final | 18 draft + 18 final | $0.90 |
| GPT-image-2 touch-ups only | 18 images | $0.25 |
At $0.54 for an 18-shade shot set, generating the full launch costs a fraction of a single studio session, and every shade ships from the same lighting and framing by construction rather than by matching separate shoots across a launch week.
Internal Links
- Nano Banana Pro on GenRelay
- How to maintain visual consistency in AI-generated images
- Batch image generation via API
FAQ
Can the API match an exact Pantone or pigment color from a swatch code alone?
It approximates the described shade closely when given a descriptive prompt (undertone plus finish); for exact pigment matching against a physical swatch, reviewing generated output against a color reference before catalog publish is worth the extra step.
Does it handle glossy, matte, and shimmer finishes differently?
Yes — describing the finish explicitly in the prompt ("matte", "glossy", "shimmer") changes how the model renders light reflection on the swatch and product surface.
Can one API call generate the bottle and the swatch in the same image?
Yes, when the prompt describes both elements together, as in the example above; the model composes the swatch smear alongside the bottle in a single output rather than requiring two separate calls.
What resolution is needed for an e-commerce product page?
2K is sufficient for most storefront zoom interactions; 4K adds a $0.012 premium per image and is worth it mainly for print packaging mockups rather than web listings.
Is there a free tier to test shade accuracy before running a full range?
Yes. GenRelay includes free credits on signup, enough to generate a handful of shade variants from one base photo before committing to a full launch batch.
As of September 2026. Pricing subject to change — verify current rates at genrelay.ai.