- Supports 1K resolution only (passing 2K/4K/0.5K is automatically downgraded to 1K without an error)
- Supports text-to-image and image-to-image, up to 14 reference images
- Billed by input / output tokens; connects directly to the official Gemini channel, with asynchronous task-based image generation
Model-name compatibility note: gemini-3.1-flash-lite-image also accepts the alias nano-banana-2-lite, and gemini-3.1-flash-lite-image-ext also accepts the alias nano-banana-2-lite-ext; each name and its alias are equivalent and interchangeable.
Request example
# model can be "gemini-3.1-flash-lite-image", the alias "nano-banana-2-lite" also works
curl --request POST \
--url https://api.openveer.com/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "gemini-3.1-flash-lite-image",
"prompt": "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size": "16:9",
"resolution": "1K",
"n": 1
}'import requests
url = "https://api.openveer.com/v1/images/generations"
payload = {
"model": "gemini-3.1-flash-lite-image",
"prompt": "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size": "16:9",
"resolution": "1K",
"n": 1
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())const url = "https://api.openveer.com/v1/images/generations";
const payload = {
model: "gemini-3.1-flash-lite-image",
prompt: "赛博朋克风格的城市夜景,霓虹灯闪烁",
size: "16:9",
resolution: "1K",
n: 1
};
const headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.openveer.com/v1/images/generations"
payload := map[string]interface{}{
"model": "gemini-3.1-flash-lite-image",
"prompt": "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size": "16:9",
"resolution": "1K",
"n": 1,
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://api.openveer.com/v1/images/generations";
String payload = """
{
"model": "gemini-3.1-flash-lite-image",
"prompt": "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size": "16:9",
"resolution": "1K",
"n": 1
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}<?php
$url = "https://api.openveer.com/v1/images/generations";
$payload = [
"model" => "gemini-3.1-flash-lite-image",
"prompt" => "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size" => "16:9",
"resolution" => "1K",
"n" => 1
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer <token>",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>require 'net/http'
require 'json'
require 'uri'
url = URI("https://api.openveer.com/v1/images/generations")
payload = {
model: "gemini-3.1-flash-lite-image",
prompt: "赛博朋克风格的城市夜景,霓虹灯闪烁",
size: "16:9",
resolution: "1K",
n: 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 = payload.to_json
response = http.request(request)
puts response.bodyimport Foundation
let url = URL(string: "https://api.openveer.com/v1/images/generations")!
let payload: [String: Any] = [
"model": "gemini-3.1-flash-lite-image",
"prompt": "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size": "16:9",
"resolution": "1K",
"n": 1
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
}
task.resume()using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var url = "https://api.openveer.com/v1/images/generations";
var payload = @"{
""model"": ""gemini-3.1-flash-lite-image"",
""prompt"": ""赛博朋克风格的城市夜景,霓虹灯闪烁"",
""size"": ""16:9"",
""resolution"": ""1K"",
""n"": 1
}";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer <token>");
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}#include <stdio.h>
#include <curl/curl.h>
int main(void) {
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
const char *url = "https://api.openveer.com/v1/images/generations";
const char *payload = "{"
"\"model\":\"gemini-3.1-flash-lite-image\","
"\"prompt\":\"赛博朋克风格的城市夜景,霓虹灯闪烁\","
"\"size\":\"16:9\","
"\"resolution\":\"1K\","
"\"n\":1"
"}";
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSURL *url = [NSURL URLWithString:@"https://api.openveer.com/v1/images/generations"];
NSDictionary *payload = @{
@"model": @"gemini-3.1-flash-lite-image",
@"prompt": @"赛博朋克风格的城市夜景,霓虹灯闪烁",
@"size": @"16:9",
@"resolution": @"1K",
@"n": @1
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload
options:0
error:&error];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"Bearer <token>" forHTTPHeaderField:@"Authorization"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
return;
}
NSString *result = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"%@", result);
}];
[task resume];
[[NSRunLoop mainRunLoop] run];
}
return 0;
}(* Requires cohttp and yojson libraries *)
open Lwt
open Cohttp
open Cohttp_lwt_unix
let url = "https://api.openveer.com/v1/images/generations"
let payload = {|{
"model": "gemini-3.1-flash-lite-image",
"prompt": "赛博朋克风格的城市夜景,霓虹灯闪烁",
"size": "16:9",
"resolution": "1K",
"n": 1
}|}
let () =
let headers = Header.init ()
|> fun h -> Header.add h "Authorization" "Bearer <token>"
|> fun h -> Header.add h "Content-Type" "application/json"
in
let body = Cohttp_lwt.Body.of_string payload in
let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) ->
body |> Cohttp_lwt.Body.to_string >|= fun body_str ->
print_endline body_str
in
Lwt_main.run responseimport 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
final url = Uri.parse('https://api.openveer.com/v1/images/generations');
final payload = {
'model': 'gemini-3.1-flash-lite-image',
'prompt': '赛博朋克风格的城市夜景,霓虹灯闪烁',
'size': '16:9',
'resolution': '1K',
'n': 1
};
final response = await http.post(
url,
headers: {
'Authorization': 'Bearer <token>',
'Content-Type': 'application/json',
},
body: jsonEncode(payload),
);
print(response.body);
}library(httr)
library(jsonlite)
url <- "https://api.openveer.com/v1/images/generations"
payload <- list(
model = "gemini-3.1-flash-lite-image",
prompt = "赛博朋克风格的城市夜景,霓虹灯闪烁",
size = "16:9",
resolution = "1K",
n = 1
)
response <- POST(
url,
add_headers(
Authorization = "Bearer <token>",
`Content-Type` = "application/json"
),
body = toJSON(payload, auto_unbox = TRUE),
encode = "raw"
)
cat(content(response, "text"))Response example
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
}
]
}{
"error": {
"code": 400,
"message": "请求参数无效",
"type": "invalid_request_error"
}
}{
"error": {
"code": 401,
"message": "身份验证失败,请检查您的API密钥",
"type": "authentication_error"
}
}{
"error": {
"code": 402,
"message": "账户余额不足,请充值后再试",
"type": "payment_required"
}
}{
"error": {
"code": 403,
"message": "访问被禁止,您没有权限访问此资源",
"type": "permission_error"
}
}{
"error": {
"code": 429,
"message": "请求过于频繁,请稍后再试",
"type": "rate_limit_error"
}
}{
"error": {
"code": 500,
"message": "服务器内部错误,请稍后重试",
"type": "server_error"
}
}{
"error": {
"code": 502,
"message": "网关错误,服务器暂时不可用",
"type": "bad_gateway"
}
}Authorizations
Authorization stringAll API endpoints require Bearer Token authentication
Get your API Key:
Visit the API Key Management Page to get your API Key
Add it to the request header:
Authorization: Bearer YOUR_API_KEYBody
model stringImage generation model name
The following model names are supported:
gemini-3.1-flash-lite-image(Nano Banana Lite, compatible aliasnano-banana-2-lite)gemini-3.1-flash-lite-image-ext(compatible aliasnano-banana-2-lite-ext)
Both share the same parameters and constraints (1K only, google_search / official_fallback not supported, up to 14 reference images). Neither has a -official variant, and neither supports the official_fallback fallback parameter. Billing is subject to the backend configuration of each channel.
The aliases `nano-banana-2-lite` (for `gemini-3.1-flash-lite-image`) and `nano-banana-2-lite-ext` (for `gemini-3.1-flash-lite-image-ext`) are equivalent to their original names and interchangeable.
nsfw_check booleanWhether to run content moderation before submitting the image task.
true: useomni-moderation-latestto review prompts and input imagesfalseor omitted: do not send a moderation request, adding no moderation cost or latency (default)
prompt stringText description for image generation
size stringImage aspect ratio
Supported ratios:
auto- Automatically choose the aspect ratio1:1- Square, avatars, social media3:2/2:3- Standard photos4:3/3:4- Traditional display ratio16:9/9:16- Widescreen / vertical video covers5:4/4:5- Instagram images21:9- Ultra-wide banner
For text-to-image, when size is auto, the default is 1:1 or 16:9; for image-to-image, the aspect ratio follows the upstream response. (We recommend specifying an aspect ratio.)
resolution stringOutput image resolution
Supported values:
1K- \~1024px, standard resolution (the only tier Lite supports)
Lite only supports 1K. Passing 2K / 4K / 0.5K is silently downgraded to 1K — it won't raise an error, nor will it actually output higher resolution. The frontend UI does not need to expose a resolution option.
n integerNumber of images to generate
Range: 1 to 4, default 1
When n>1, the backend sends multiple concurrent requests upstream and bills by the actual number of successful images. We recommend the frontend always send 1 (to show progress image by image and make billing more intuitive).
⚠️ Note: Must enter a plain number (e.g., 1), do not use quotes or it will cause an error
image_urls arrayReference image URL list for image-to-image generation
Two formats are supported:
1. Full image URL
- Publicly accessible image URL (http\:// or https\://)
- Example:
https://example.com/image.jpg
2. Base64 encoded format
- Must use the full Data URI format
- Format:
data:image/{format};base64,{base64data} - Supported image formats: jpeg, png, webp
- Example:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABg... - ⚠️ Note: Must include the
data:image/jpeg;base64,prefix
Limitations:
- Maximum 14 reference images (recommended: up to 10 object refs + 4 character refs)
- Single image size: not exceeding 10MB
- Supported formats: jpeg, png, webp
webhook stringTask callback URL (base)
When a task succeeds / fails, the platform calls back to webhook + /callback (it does not forward the upstream request). Passing this parameter can significantly reduce polling; we still recommend keeping polling as a fallback.
Lite usage notes
google_search/google_image_searchare not supported: Lite uses the Developer API'sinteractionsendpoint, and the upstream has not enabled the Search tool (it returns "Search as tool is not enabled for this model"), so the platform adapter does not send this parameter either. Passing it won't raise an error and images are generated as usual, but there is no search enhancement effect at all. If you need search enhancement, switch togemini-3.1-flash-image-preview.mask_urlinpainting is not supported (the Gemini family uses aspect ratio + reference images rather than masks).- Billed by token (unlike the fixed per-image price of flash/pro): input is about $0.25 per million tokens, image output is about $30 per million tokens, and a single 1K image ≈ 1120 output tokens ≈ \$0.0336/image. The actual price is subject to the backend multiplier configuration.
- All generated images contain Google's SynthID invisible watermark (upstream behavior, cannot be disabled).
Response
code integerResponse status code
data arraystatus stringTask status
* submitted - Submitted
task_id stringUnique task identifier
This documentation is built and hosted on Mintlify, a developer documentation platform.