Product Shot
imageimage/product-shotOne product photo becomes a full shoot: new scenes, surfaces and lighting, the product itself untouched.
The product photo
Restaged on wet slate, product untouchedIts own feature, not a flag on a general edit. What makes it a product shot is the fidelity clause the server appends: the render is instructed to reproduce your product exactly, down to the labels and proportions, while everything around it is new.
Billed per image. $0.15 per look, or $0.53 with fineDetails on. Live rate from GET /v3/pricing.
A complete call
Restage a saved product photo on wet slate.
1Upload the product photo
POST /v3/files/upload returns a file id. A clean shot on any background works; the scene is replaced.
curl -X POST "https://api.neurall.io/v3/files/upload" \
-H "Authorization: nl-YOUR_API_KEY" \
-F "files=@candle.jpg"It answers with the file ids
{
"files": [
{
"id": "f_9c21e0b4",
"originalName": "candle.jpg",
"size": 468920
}
]
}2Submit the render
POST /v3/generations with feature image/product-shot and the file id from step 1.
curl -X POST "https://api.neurall.io/v3/generations" \
-H "Authorization: nl-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"feature": "image/product-shot",
"args": {
"image": "f_9c21e0b4",
"description": "hand-poured soy candle in amber glass, sea salt and sage",
"prompt": "Product on wet slate with rippling water, moody side light, dramatic reflections, deep shadow falloff.",
"aspectRatio": "4:5",
"fineDetails": true
}
}'It answers immediately
{
"generation": {
"id": "c9b2…",
"feature": "image/product-shot",
"kind": "image",
"status": "pending"
}
}3Poll until it lands
Poll GET /v3/generations/{id}, or pass webhookUrl and skip polling.
# repeat every 2s or so until status is done, error or timeout
curl "https://api.neurall.io/v3/generations/9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43" \
-H "Authorization: nl-YOUR_API_KEY"Once status is done
{
"generation": {
"status": "done",
"output": {
"image": "https://cdn.neurall.io/…/image.png",
"mime": "image/png"
}
}
}output holds the finished asset on a signed CDN URL. Download it rather than hotlinking: API-created outputs expire 24 hours after the request.
Arguments
imagestringrequired- The file id of the product photo. Singular: this feature takes exactly one.
- PNG, JPEG, WebP, GIF, HEIC or AVIF, up to 30 MB and 30 megapixels per file, 10 files per upload request.
- An uploaded file is deleted 24 hours after it lands, so upload again for a later render rather than caching an id.
- Exactly one image. A second reference is rejected: a product shot is about the product.
args.imageThe product- Say "the product" in the prompt when you need to place it ("the product on wet slate"). Do not describe what it looks like.
descriptionstring- What the product IS, in plain words. Ground truth the prompt author cannot guess from pixels, and the one thing worth saying about the product itself.
args.descriptionWhat the product is- Not a prompt: it is a fact the render can rely on, like "amber glass candle". Use it when the shape alone is ambiguous.
promptstringrequired- The scene: surface, backdrop, light, mood. Pure style, no fidelity language needed.
- At most 2000 characters.
aspectRatio'W:H'defaults to '1:1'- Any ratio written as width:height.
- Between 1:3 and 3:1.
fineDetailsbooleandefaults to false- The render tier, as one switch. Off is the standard render; on costs more and holds fine texture and small type. Sending quality here is an error: this feature owns the mapping so the tier that renders and the tier that bills cannot disagree.
How the prompt refers to this
How the prompt refers to this
Describing the product in the prompt competes with the photograph. Describe the scene; let the image be the product.
Output
Once status is done, the generation carries an output object with these fields. On any other status, output is absent.
imagestring- The finished shot, as a URL.
- A signed URL that expires 24 hours after the request (expiresAt on the generation). Download the file rather than hotlinking it.
mimestring- The image's MIME type, e.g. image/png.
Limits and failure
- Images
- Exactly one, 30 MB and 30 megapixels max, deleted 24 hours after upload.
- Aspect ratio
- Any W:H between 1:3 and 3:1.
- Render time
- A generation that has not finished in 15 minutes is marked timeout and refunded.
- Concurrency
- Your plan caps how many generations run at once. Over it the API answers 429 with a Retry-After header.
- Output lifetime
- API-created outputs expire 24 hours after the request. Download the file rather than hotlinking it.
- Deletion
- DELETE /v3/generations/{id} removes the generation and its rendered assets immediately, rather than waiting for the 24 hour expiry. It does not refund anything and cannot cancel a render already in flight.
- Failure
- A failed or timed-out generation is refunded automatically.
Worth knowing
- Its own feature key since 2026-08-13, so it prices, counts and lists on its own rather than hiding inside image/edit.
- The upscaler is never run here. It is a face and skin model, so on a product it buys nothing but time, and the price quoted is the plain render.