curl --request POST \
--url https://api.budgetpixel.com/v1/images/nano-banana-2.1 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "<string>",
"aspect_ratio": "auto",
"google_search": false,
"image_search": false,
"num_images": 1,
"output_format": "png",
"reference_images": [
"<string>"
],
"size": "1K"
}
'import requests
url = "https://api.budgetpixel.com/v1/images/nano-banana-2.1"
payload = {
"prompt": "<string>",
"aspect_ratio": "auto",
"google_search": False,
"image_search": False,
"num_images": 1,
"output_format": "png",
"reference_images": ["<string>"],
"size": "1K"
}
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({
prompt: '<string>',
aspect_ratio: 'auto',
google_search: false,
image_search: false,
num_images: 1,
output_format: 'png',
reference_images: ['<string>'],
size: '1K'
})
};
fetch('https://api.budgetpixel.com/v1/images/nano-banana-2.1', 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.budgetpixel.com/v1/images/nano-banana-2.1",
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([
'prompt' => '<string>',
'aspect_ratio' => 'auto',
'google_search' => false,
'image_search' => false,
'num_images' => 1,
'output_format' => 'png',
'reference_images' => [
'<string>'
],
'size' => '1K'
]),
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.budgetpixel.com/v1/images/nano-banana-2.1"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"auto\",\n \"google_search\": false,\n \"image_search\": false,\n \"num_images\": 1,\n \"output_format\": \"png\",\n \"reference_images\": [\n \"<string>\"\n ],\n \"size\": \"1K\"\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.budgetpixel.com/v1/images/nano-banana-2.1")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"auto\",\n \"google_search\": false,\n \"image_search\": false,\n \"num_images\": 1,\n \"output_format\": \"png\",\n \"reference_images\": [\n \"<string>\"\n ],\n \"size\": \"1K\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.budgetpixel.com/v1/images/nano-banana-2.1")
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 \"prompt\": \"<string>\",\n \"aspect_ratio\": \"auto\",\n \"google_search\": false,\n \"image_search\": false,\n \"num_images\": 1,\n \"output_format\": \"png\",\n \"reference_images\": [\n \"<string>\"\n ],\n \"size\": \"1K\"\n}"
response = http.request(request)
puts response.read_body{
"id": "img_a1b2c3d4e5f6",
"message": "<string>",
"model": "<string>",
"status": "pending"
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}Generate image with Nano Banana 2.1
Google Nano Banana 2.1 — fast text-to-image and image editing with sharper output and cleaner in-image text than Nano Banana 2. Edit or compose from up to 9 reference images (free), render at 1K, 2K or 4K, and optionally ground the image in live web results or web images. Billing: per image by size — 1K = 45, 2K = 70, 4K = 150 credits. Search grounding is off by default and adds per image: google_search +10, image_search +20 (it includes a web search). Use POST /v1/cost for an exact quote.
Asynchronous. Returns a job id (the image is not in this response). Poll GET /v1/images/{id} until status is succeeded — the generated image URLs are in that response’s images array (each { url, position }).
Examples, sample output and pricing: Nano Banana 2.1
curl --request POST \
--url https://api.budgetpixel.com/v1/images/nano-banana-2.1 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "<string>",
"aspect_ratio": "auto",
"google_search": false,
"image_search": false,
"num_images": 1,
"output_format": "png",
"reference_images": [
"<string>"
],
"size": "1K"
}
'import requests
url = "https://api.budgetpixel.com/v1/images/nano-banana-2.1"
payload = {
"prompt": "<string>",
"aspect_ratio": "auto",
"google_search": False,
"image_search": False,
"num_images": 1,
"output_format": "png",
"reference_images": ["<string>"],
"size": "1K"
}
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({
prompt: '<string>',
aspect_ratio: 'auto',
google_search: false,
image_search: false,
num_images: 1,
output_format: 'png',
reference_images: ['<string>'],
size: '1K'
})
};
fetch('https://api.budgetpixel.com/v1/images/nano-banana-2.1', 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.budgetpixel.com/v1/images/nano-banana-2.1",
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([
'prompt' => '<string>',
'aspect_ratio' => 'auto',
'google_search' => false,
'image_search' => false,
'num_images' => 1,
'output_format' => 'png',
'reference_images' => [
'<string>'
],
'size' => '1K'
]),
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.budgetpixel.com/v1/images/nano-banana-2.1"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"auto\",\n \"google_search\": false,\n \"image_search\": false,\n \"num_images\": 1,\n \"output_format\": \"png\",\n \"reference_images\": [\n \"<string>\"\n ],\n \"size\": \"1K\"\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.budgetpixel.com/v1/images/nano-banana-2.1")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"auto\",\n \"google_search\": false,\n \"image_search\": false,\n \"num_images\": 1,\n \"output_format\": \"png\",\n \"reference_images\": [\n \"<string>\"\n ],\n \"size\": \"1K\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.budgetpixel.com/v1/images/nano-banana-2.1")
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 \"prompt\": \"<string>\",\n \"aspect_ratio\": \"auto\",\n \"google_search\": false,\n \"image_search\": false,\n \"num_images\": 1,\n \"output_format\": \"png\",\n \"reference_images\": [\n \"<string>\"\n ],\n \"size\": \"1K\"\n}"
response = http.request(request)
puts response.read_body{
"id": "img_a1b2c3d4e5f6",
"message": "<string>",
"model": "<string>",
"status": "pending"
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}Authorizations
API key as a bearer token: Authorization: Bearer bpx_live_xxx
Body
Text description of the image to generate, or of the edit to apply to the reference images.
Output aspect ratio. "auto" (default) follows the first reference image when editing and gives a square image for text-to-image.
auto, 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 5:4, 4:5, 21:9, 1:4, 4:1, 1:8, 8:1 Ground the image in live Google Search results (weather, scores, recent events, current facts). Off by default. Adds 10 credits per image.
Let the model look up web images as visual context before rendering. Off by default. Runs a web search too, so it adds 20 credits per image in total, with or without google_search.
Number of images to generate. Each image is billed at its size's price, plus search grounding if enabled.
1 <= x <= 4Output image format (default png, at full resolution). jpeg gives a much smaller file, but its long edge is limited to 4096 px, so a wide 4K image comes back smaller than its PNG (16:9 at 4K: 5504x3072 as PNG, about 25 MB; 4096x2286 as JPEG). Results generated with image_search are returned as JPEG regardless.
png, jpeg Optional reference images (up to 9) for image editing and multi-reference composition. Each item is a public image URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads. Omit for text-to-image. Reference images cost nothing extra.
9Output resolution tier. Sets the price: 1K = 45, 2K = 70, 4K = 150 credits per image.
1K, 2K, 4K