curl --request POST \
--url https://api.bitstudio.ai/images/generate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model_version": "nano-banana-2",
"generate_mode": "presets",
"model_text": "An adult fashion model",
"outfit_image_ids": [
"11111111-1111-4111-8111-111111111111"
],
"prompt": "Full-length front view in a white studio, soft shadows.",
"resolution": "standard",
"aspect_ratio": "3:4",
"num_images": 1
}
'import requests
url = "https://api.bitstudio.ai/images/generate"
payload = {
"model_version": "nano-banana-2",
"generate_mode": "presets",
"model_text": "An adult fashion model",
"outfit_image_ids": ["11111111-1111-4111-8111-111111111111"],
"prompt": "Full-length front view in a white studio, soft shadows.",
"resolution": "standard",
"aspect_ratio": "3:4",
"num_images": 1
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model_version: 'nano-banana-2',
generate_mode: 'presets',
model_text: 'An adult fashion model',
outfit_image_ids: ['11111111-1111-4111-8111-111111111111'],
prompt: 'Full-length front view in a white studio, soft shadows.',
resolution: 'standard',
aspect_ratio: '3:4',
num_images: 1
})
};
fetch('https://api.bitstudio.ai/images/generate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bitstudio.ai/images/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model_version' => 'nano-banana-2',
'generate_mode' => 'presets',
'model_text' => 'An adult fashion model',
'outfit_image_ids' => [
'11111111-1111-4111-8111-111111111111'
],
'prompt' => 'Full-length front view in a white studio, soft shadows.',
'resolution' => 'standard',
'aspect_ratio' => '3:4',
'num_images' => 1
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bitstudio.ai/images/generate"
payload := strings.NewReader("{\n \"model_version\": \"nano-banana-2\",\n \"generate_mode\": \"presets\",\n \"model_text\": \"An adult fashion model\",\n \"outfit_image_ids\": [\n \"11111111-1111-4111-8111-111111111111\"\n ],\n \"prompt\": \"Full-length front view in a white studio, soft shadows.\",\n \"resolution\": \"standard\",\n \"aspect_ratio\": \"3:4\",\n \"num_images\": 1\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bitstudio.ai/images/generate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model_version\": \"nano-banana-2\",\n \"generate_mode\": \"presets\",\n \"model_text\": \"An adult fashion model\",\n \"outfit_image_ids\": [\n \"11111111-1111-4111-8111-111111111111\"\n ],\n \"prompt\": \"Full-length front view in a white studio, soft shadows.\",\n \"resolution\": \"standard\",\n \"aspect_ratio\": \"3:4\",\n \"num_images\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bitstudio.ai/images/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model_version\": \"nano-banana-2\",\n \"generate_mode\": \"presets\",\n \"model_text\": \"An adult fashion model\",\n \"outfit_image_ids\": [\n \"11111111-1111-4111-8111-111111111111\"\n ],\n \"prompt\": \"Full-length front view in a white studio, soft shadows.\",\n \"resolution\": \"standard\",\n \"aspect_ratio\": \"3:4\",\n \"num_images\": 1\n}"
response = http.request(request)
puts response.read_body[
{
"id": "11111111-1111-4111-8111-111111111111",
"status": "pending",
"path": null,
"width_px": null,
"height_px": null,
"created_timestamp": "2026-09-06T12:00:00Z"
}
]{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"cta": true,
"next_action": "<string>",
"current_plan": "<string>",
"user_message": "<string>",
"extra_context": "<string>"
}Generate product photos
Returns an array of pending image jobs. Save every id and poll each job until completed, failed, or policy_blocked.
curl --request POST \
--url https://api.bitstudio.ai/images/generate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model_version": "nano-banana-2",
"generate_mode": "presets",
"model_text": "An adult fashion model",
"outfit_image_ids": [
"11111111-1111-4111-8111-111111111111"
],
"prompt": "Full-length front view in a white studio, soft shadows.",
"resolution": "standard",
"aspect_ratio": "3:4",
"num_images": 1
}
'import requests
url = "https://api.bitstudio.ai/images/generate"
payload = {
"model_version": "nano-banana-2",
"generate_mode": "presets",
"model_text": "An adult fashion model",
"outfit_image_ids": ["11111111-1111-4111-8111-111111111111"],
"prompt": "Full-length front view in a white studio, soft shadows.",
"resolution": "standard",
"aspect_ratio": "3:4",
"num_images": 1
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model_version: 'nano-banana-2',
generate_mode: 'presets',
model_text: 'An adult fashion model',
outfit_image_ids: ['11111111-1111-4111-8111-111111111111'],
prompt: 'Full-length front view in a white studio, soft shadows.',
resolution: 'standard',
aspect_ratio: '3:4',
num_images: 1
})
};
fetch('https://api.bitstudio.ai/images/generate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bitstudio.ai/images/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model_version' => 'nano-banana-2',
'generate_mode' => 'presets',
'model_text' => 'An adult fashion model',
'outfit_image_ids' => [
'11111111-1111-4111-8111-111111111111'
],
'prompt' => 'Full-length front view in a white studio, soft shadows.',
'resolution' => 'standard',
'aspect_ratio' => '3:4',
'num_images' => 1
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bitstudio.ai/images/generate"
payload := strings.NewReader("{\n \"model_version\": \"nano-banana-2\",\n \"generate_mode\": \"presets\",\n \"model_text\": \"An adult fashion model\",\n \"outfit_image_ids\": [\n \"11111111-1111-4111-8111-111111111111\"\n ],\n \"prompt\": \"Full-length front view in a white studio, soft shadows.\",\n \"resolution\": \"standard\",\n \"aspect_ratio\": \"3:4\",\n \"num_images\": 1\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bitstudio.ai/images/generate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model_version\": \"nano-banana-2\",\n \"generate_mode\": \"presets\",\n \"model_text\": \"An adult fashion model\",\n \"outfit_image_ids\": [\n \"11111111-1111-4111-8111-111111111111\"\n ],\n \"prompt\": \"Full-length front view in a white studio, soft shadows.\",\n \"resolution\": \"standard\",\n \"aspect_ratio\": \"3:4\",\n \"num_images\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bitstudio.ai/images/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model_version\": \"nano-banana-2\",\n \"generate_mode\": \"presets\",\n \"model_text\": \"An adult fashion model\",\n \"outfit_image_ids\": [\n \"11111111-1111-4111-8111-111111111111\"\n ],\n \"prompt\": \"Full-length front view in a white studio, soft shadows.\",\n \"resolution\": \"standard\",\n \"aspect_ratio\": \"3:4\",\n \"num_images\": 1\n}"
response = http.request(request)
puts response.read_body[
{
"id": "11111111-1111-4111-8111-111111111111",
"status": "pending",
"path": null,
"width_px": null,
"height_px": null,
"created_timestamp": "2026-09-06T12:00:00Z"
}
]{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"cta": true,
"next_action": "<string>",
"current_plan": "<string>",
"user_message": "<string>",
"extra_context": "<string>"
}num_images: 1; omitting it also creates one output. See request settings.
Track jobs and versions.Authorizations
Create an API key in Studio → account menu → API Keys. Keep it on your server.
Body
Output quality. Send explicitly. Pixel dimensions depend on the image model.
standard, high "standard"
Avatar, preset, pose, set, or style asset IDs. Use at most one preset or set in total.
Resource ID.
Reusable outfit references. Use one source form per product.
3Resource ID.
Previously uploaded garment images.
3Resource ID.
Direct garment image URLs accessible to the service.
3Single-outfit alternative to outfit_asset_ids.
Single-image alternative to outfit_image_ids.
Single-URL alternative to outfit_image_urls.
Composition or extra preset directions.
Describe the avatar when not selecting one from the library.
How the selected garment should be worn.
Setting directions when needed.
Use presets for the standard reference workflow.
presets, legacy "presets"
Image model identifier. nano-banana-2 is used in this guide; availability depends on your account.
"nano-banana-2"
Model-dependent output ratio. 3:4 is supported by nano-banana-2 and nano-banana-pro.
"3:4"
Number of outputs. Defaults to 1. Account limits still apply.
1 <= x <= 81
Optional seed. It does not guarantee identical results across models or changes.
Studio onboarding identifier. Omit for normal generation.
Optional style directions.
Optional saved style asset ID.
Legacy set asset ID. Prefer a preset in asset_ids for the standard workflow.
Legacy scene mode. Use generate_mode: presets for the standard workflow.
Response
Returns an array of pending image jobs. Save every id and poll each job until completed, failed, or policy_blocked.
Resource ID.
Job state. Only completed has a finished result.
pending, generating, completed, failed, policy_blocked, nsfw_filtered Result URL. Can be null while the job is pending.
Whether the upload is a reusable asset reference.
Operation that created this job.
Human-readable failure detail.
Machine-readable failure category, when available.
input_rejected, provider_unavailable, queue_timeout, policy_blocked Linked reusable assets.
Resource ID.
Related versions. May be omitted or empty. Never infer a new version is completed from the parent status.
Show child attributes
Show child attributes