Nano Banana 2.1
curl --request POST \
--url https://api.snapgen.org/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": [
"<string>"
]
}
'import requests
url = "https://api.snapgen.org/v1/images/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": ["<string>"]
}
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: '<string>',
prompt: '<string>',
resolution: '<string>',
size: '<string>',
n: 123,
image_urls: ['<string>']
})
};
fetch('https://api.snapgen.org/v1/images/generations', 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.snapgen.org/v1/images/generations",
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' => '<string>',
'prompt' => '<string>',
'resolution' => '<string>',
'size' => '<string>',
'n' => 123,
'image_urls' => [
'<string>'
]
]),
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.snapgen.org/v1/images/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\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.snapgen.org/v1/images/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snapgen.org/v1/images/generations")
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\": \"<string>\",\n \"prompt\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyImage Series
Nano Banana 2.1
Generate and edit 1K, 2K and 4K images with nano-banana-2.1 and predictable per-image billing.
POST
/
v1
/
images
/
generations
Nano Banana 2.1
curl --request POST \
--url https://api.snapgen.org/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": [
"<string>"
]
}
'import requests
url = "https://api.snapgen.org/v1/images/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": ["<string>"]
}
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: '<string>',
prompt: '<string>',
resolution: '<string>',
size: '<string>',
n: 123,
image_urls: ['<string>']
})
};
fetch('https://api.snapgen.org/v1/images/generations', 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.snapgen.org/v1/images/generations",
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' => '<string>',
'prompt' => '<string>',
'resolution' => '<string>',
'size' => '<string>',
'n' => 123,
'image_urls' => [
'<string>'
]
]),
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.snapgen.org/v1/images/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\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.snapgen.org/v1/images/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snapgen.org/v1/images/generations")
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\": \"<string>\",\n \"prompt\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyUse
100 SnapGen credits = $1. References have no extra charge. Confirm current availability and prices with
This route does not support
A normal request waits for a terminal result (default 180 seconds). Success returns image URLs:
nano-banana-2.1 to generate a new image from text or edit with reference images. Each request delivers one image. This model is separate from Nano Banana 2 and does not substitute the older model on failure.
| Property | Value |
|---|---|
| Public model ID | nano-banana-2.1 |
| Resolutions | 1K (default), 2K, 4K |
| Size | auto (default) or one of ten supported ratios |
| Count | n: 1 only |
| References | Up to 16 public URLs or PNG/JPEG/WebP Data URLs |
| Waiting response | data[].url, or HTTP 202 with a task if still running |
| Resolution | Price per delivered image |
|---|---|
1K | $0.04 (4 SnapGen credits) |
2K | $0.05 (5 SnapGen credits) |
4K | $0.06 (6 SnapGen credits) |
GET /v1/models and the live model page.
string
required
Set to
nano-banana-2.1.string
required
A non-empty visual brief of at most 100,000 characters. For edits, describe
what to change and what to preserve.
string
default:"1K"
1K, 2K or 4K. This selects the billed resolution tier.string
default:"auto"
auto, 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 5:4, 4:5 or
21:9.integer
default:"1"
This route accepts one image per request. Submit separate requests for
variants.
string[]
Optional, up to 16 publicly reachable HTTP(S) URLs or PNG, JPEG and WebP Data
URLs. Private, loopback and credentialed URLs are rejected. Data URL images
must be valid Base64 and at most 20 MiB decoded per image, with at most 50 MiB
decoded in total. The whole JSON request is subject to the gateway
request-size cap (default 10 MiB), so use public URLs for larger references.
quality, custom pixel sizes, version, masks, video inputs or search controls. Official token-priced fallback is disabled; official_fallback: true is rejected before a billing reservation.
Generate an image
curl https://api.snapgen.org/v1/images/generations \
-H "Authorization: Bearer $SNAPGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-2.1",
"prompt": "A ceramic coffee mug on a walnut table, soft window light, product photo",
"resolution": "1K",
"size": "1:1",
"n": 1
}'
{
"created": 1791460800,
"data": [{ "url": "https://cdn.example.com/generated-image.png" }]
}
Edit with a reference
{
"model": "nano-banana-2.1",
"prompt": "Preserve the mug shape and replace the background with warm linen",
"resolution": "2K",
"size": "4:3",
"n": 1,
"image_urls": ["https://cdn.example.com/reference-mug.png"]
}
Run asynchronously
SendPrefer: respond-async to receive HTTP 202 immediately. Use Idempotency-Key (1–200 characters) for retries of the same submission. A normal waiting request can also return 202 when the job is still running. Read the gateway task ID and poll GET /v1/tasks/{id} with the same key until succeeded or failed.
curl https://api.snapgen.org/v1/images/generations \
-H "Authorization: Bearer $SNAPGEN_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: respond-async" \
-H "Idempotency-Key: mug-concept-001" \
-d '{"model":"nano-banana-2.1","prompt":"A blue ceramic mug on linen","resolution":"1K","size":"16:9","n":1}'
curl "https://api.snapgen.org/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $SNAPGEN_API_KEY"
The gateway reserves the selected resolution price before submitting the
request and settles the delivered image count against that immutable price
version. Explicit failure or cancellation releases the reservation. Uncertain
or invalid results are held for reconciliation. Repeated status polls do not
charge twice. Result URLs are temporary: download successful files promptly
and respect any returned expiry time.
Try Nano Banana 2.1
Generate from text or references in the model Playground and compare live
rates.