Product mockups
A plain product photo on a white background rarely sells the product on its own — it needs a setting that shows how it's used or where it belongs. This endpoint takes your product image and places it into a generated scene, producing a lifestyle-style mockup without a photo shoot.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The problem: every product needs context, not every seller has a studio
A studio product shot proves the item exists and shows its shape, but it does very little to help a buyer imagine it in their kitchen, on their desk, or worn on the street. Producing that context traditionally means a photo shoot, a stylist, and a location, none of which is realistic for a seller listing hundreds of SKUs or a small brand testing a new product line. This endpoint replaces that shoot with a generation step: give it your product image and a description of the scene, and it composes the two together.
What you send and what comes back
You submit your product image, by URL or upload, along with a description of the scene you want it placed into, a kitchen counter, an outdoor setting, a minimalist studio backdrop with props, and the task returns a generated mockup with your product composited into that environment. Because the endpoint is asynchronous, you get a task_id immediately and the finished mockup arrives later by webhook or a signed link, matching how a real render or edit job takes measurable time to complete.
Why placing a real product into a generated scene is harder than it sounds
Generating a scene from scratch is one problem; keeping your specific product looking like itself while it sits inside that scene is a different and harder one, since the model has to respect the product's actual shape, proportions and details rather than reinvent them. That's the core technical distinction between this endpoint and plain image generation: the product is a fixed input to be preserved, not a subject to be reimagined, and the generated scene has to build itself around that constraint.
Where it fits in a catalogue or launch workflow
Because results come back asynchronously, this endpoint plugs naturally into a listing pipeline: a seller uploads a clean product photo, the system requests several mockups in different settings, and each one lands via webhook ready to attach to a listing or a marketing asset. It pairs well with background removal as a prep step, since a product already isolated from its original background tends to composite more cleanly into a new scene.
What quality to expect
The mockup is a generated composition, not a physical photograph, so lighting and shadow are inferred rather than captured, and very small or intricate product details may not survive the compositing perfectly. For most catalogue, marketing and social use, that trade-off is a clear win over no lifestyle image at all; for a flagship hero shot on a major campaign, treat the generated mockup as a strong draft to review before it goes out as the final asset.
What you can do with it
Marketplace listings without a photo shoot
A small seller uploads a plain product photo and generates several lifestyle mockups to use across a listing instead of booking a studio session.
Testing a new product line quickly
A brand generates mockups of a prototype in different settings to gauge interest before committing budget to a full photo shoot.
Multi-scene catalogue variety
An ecommerce store generates the same product in several different scenes, kitchen, office, outdoors, to give shoppers more context without reshooting anything.
Ad creative from existing product photography
A performance marketing team turns a single approved product photo into several scene-based mockups for testing across ad placements.
FAQ
How do I generate a product mockup through the api?
Send a POST to /image/product-mockup with your product image and a description of the scene you want it placed into; you get a task_id back and the mockup arrives by webhook or a signed link.
Will my product look exactly like the original photo?
The task works to preserve the product's real shape and details while generating the surrounding scene, but as with any generated composition, very fine details may not render perfectly, especially at small scale.
What kind of scenes can I request?
Any scene you can describe in text, a kitchen counter, an outdoor setting, a studio backdrop with props, is a valid target for the mockup composition.
Should I remove the background from my product photo first?
It helps. A product already isolated from its original background tends to composite more cleanly into the new generated scene.
Is there a free tier for the product mockup api?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How much does a product mockup cost?
$0.002 per request plus $0.0065 per image, billed only for mockups the task actually completes.
What happens if the mockup generation fails?
The task retries automatically up to three times; if it still can't complete, you receive a clear error and are never charged for the failed attempt.
Can I generate mockups for many products at once?
Submit one asynchronous request per product image in parallel and collect each finished mockup as its webhook fires, which scales cleanly across a catalogue.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/image/product-mockup \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/imagen.jpg"}'const res = await fetch("https://api.kit.forhosting.com/image/product-mockup", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/imagen.jpg"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/product-mockup",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/imagen.jpg"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/product-mockup", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/imagen.jpg"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/imagen.jpg"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/product-mockup", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"image": "https://ejemplo.com/imagen.jpg"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.product_mockup",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 15 |
max_megapixels | 12 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |