生成图片(Gemini 原生,非流式)
curl --request POST \
--url https://api.hairoute.ai/v1/models/{model}:generateContent \
--header 'Content-Type: application/json' \
--header 'x-goog-api-key: <x-goog-api-key>' \
--data '
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "画一只橘猫"
}
]
}
],
"generationConfig": {
"responseModalities": [
"TEXT",
"IMAGE"
],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "1K"
}
}
}
'import requests
url = "https://api.hairoute.ai/v1/models/{model}:generateContent"
payload = {
"contents": [
{
"role": "user",
"parts": [{ "text": "画一只橘猫" }]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "1K"
}
}
}
headers = {
"x-goog-api-key": "<x-goog-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-goog-api-key': '<x-goog-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
contents: [{role: 'user', parts: [{text: '画一只橘猫'}]}],
generationConfig: {
responseModalities: ['TEXT', 'IMAGE'],
imageConfig: {aspectRatio: '1:1', imageSize: '1K'}
}
})
};
fetch('https://api.hairoute.ai/v1/models/{model}:generateContent', 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.hairoute.ai/v1/models/{model}:generateContent",
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([
'contents' => [
[
'role' => 'user',
'parts' => [
[
'text' => '画一只橘猫'
]
]
]
],
'generationConfig' => [
'responseModalities' => [
'TEXT',
'IMAGE'
],
'imageConfig' => [
'aspectRatio' => '1:1',
'imageSize' => '1K'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-goog-api-key: <x-goog-api-key>"
],
]);
$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.hairoute.ai/v1/models/{model}:generateContent"
payload := strings.NewReader("{\n \"contents\": [\n {\n \"role\": \"user\",\n \"parts\": [\n {\n \"text\": \"画一只橘猫\"\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"responseModalities\": [\n \"TEXT\",\n \"IMAGE\"\n ],\n \"imageConfig\": {\n \"aspectRatio\": \"1:1\",\n \"imageSize\": \"1K\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-goog-api-key", "<x-goog-api-key>")
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.hairoute.ai/v1/models/{model}:generateContent")
.header("x-goog-api-key", "<x-goog-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"contents\": [\n {\n \"role\": \"user\",\n \"parts\": [\n {\n \"text\": \"画一只橘猫\"\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"responseModalities\": [\n \"TEXT\",\n \"IMAGE\"\n ],\n \"imageConfig\": {\n \"aspectRatio\": \"1:1\",\n \"imageSize\": \"1K\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hairoute.ai/v1/models/{model}:generateContent")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-goog-api-key"] = '<x-goog-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"contents\": [\n {\n \"role\": \"user\",\n \"parts\": [\n {\n \"text\": \"画一只橘猫\"\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"responseModalities\": [\n \"TEXT\",\n \"IMAGE\"\n ],\n \"imageConfig\": {\n \"aspectRatio\": \"1:1\",\n \"imageSize\": \"1K\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": "<BASE64_IMAGE_DATA>"
}
}
]
},
"finishReason": "STOP"
}
],
"usageMetadata": {
"totalTokenCount": 1302
}
}{
"error": {
"code": 123,
"message": "<string>",
"status": "<string>"
}
}图片
Gemini 原生图片生成
通过 Gemini 原生 generateContent 接口生成或编辑图片,仅适用于 Google/Gemini 图片模型
POST
/
v1
/
models
/
{model}
:generateContent
生成图片(Gemini 原生,非流式)
curl --request POST \
--url https://api.hairoute.ai/v1/models/{model}:generateContent \
--header 'Content-Type: application/json' \
--header 'x-goog-api-key: <x-goog-api-key>' \
--data '
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "画一只橘猫"
}
]
}
],
"generationConfig": {
"responseModalities": [
"TEXT",
"IMAGE"
],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "1K"
}
}
}
'import requests
url = "https://api.hairoute.ai/v1/models/{model}:generateContent"
payload = {
"contents": [
{
"role": "user",
"parts": [{ "text": "画一只橘猫" }]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "1K"
}
}
}
headers = {
"x-goog-api-key": "<x-goog-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-goog-api-key': '<x-goog-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
contents: [{role: 'user', parts: [{text: '画一只橘猫'}]}],
generationConfig: {
responseModalities: ['TEXT', 'IMAGE'],
imageConfig: {aspectRatio: '1:1', imageSize: '1K'}
}
})
};
fetch('https://api.hairoute.ai/v1/models/{model}:generateContent', 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.hairoute.ai/v1/models/{model}:generateContent",
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([
'contents' => [
[
'role' => 'user',
'parts' => [
[
'text' => '画一只橘猫'
]
]
]
],
'generationConfig' => [
'responseModalities' => [
'TEXT',
'IMAGE'
],
'imageConfig' => [
'aspectRatio' => '1:1',
'imageSize' => '1K'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-goog-api-key: <x-goog-api-key>"
],
]);
$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.hairoute.ai/v1/models/{model}:generateContent"
payload := strings.NewReader("{\n \"contents\": [\n {\n \"role\": \"user\",\n \"parts\": [\n {\n \"text\": \"画一只橘猫\"\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"responseModalities\": [\n \"TEXT\",\n \"IMAGE\"\n ],\n \"imageConfig\": {\n \"aspectRatio\": \"1:1\",\n \"imageSize\": \"1K\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-goog-api-key", "<x-goog-api-key>")
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.hairoute.ai/v1/models/{model}:generateContent")
.header("x-goog-api-key", "<x-goog-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"contents\": [\n {\n \"role\": \"user\",\n \"parts\": [\n {\n \"text\": \"画一只橘猫\"\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"responseModalities\": [\n \"TEXT\",\n \"IMAGE\"\n ],\n \"imageConfig\": {\n \"aspectRatio\": \"1:1\",\n \"imageSize\": \"1K\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hairoute.ai/v1/models/{model}:generateContent")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-goog-api-key"] = '<x-goog-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"contents\": [\n {\n \"role\": \"user\",\n \"parts\": [\n {\n \"text\": \"画一只橘猫\"\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"responseModalities\": [\n \"TEXT\",\n \"IMAGE\"\n ],\n \"imageConfig\": {\n \"aspectRatio\": \"1:1\",\n \"imageSize\": \"1K\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": "<BASE64_IMAGE_DATA>"
}
}
]
},
"finishReason": "STOP"
}
],
"usageMetadata": {
"totalTokenCount": 1302
}
}{
"error": {
"code": 123,
"message": "<string>",
"status": "<string>"
}
}使用 Gemini 原生
生成成功后,图片在
将
这里使用原生
实际调用时不要手写或裁剪上一轮的
generateContent 请求和响应结构生成图片。在图片模型中,此端点仅供 Google/Gemini 图片模型使用;Seedream、GPT Image 等其他图片模型请使用 OpenAI 图片生成接口 或各自的专用接口。Gemini 聊天模型的原生调用不属于本图片接口文档的范围。
功能特性
- 使用 Gemini 原生
generateContent协议生成图片,不使用 OpenAI Images 的请求或响应结构 - 支持文生图、单图编辑、多图参考合成和多轮继续编辑
- 可通过
generationConfig.imageConfig指定模型支持的宽高比与输出档位 - 在
candidates[].content.parts[]中接收文本及 Base64 图片;流式输出请使用流式接口
认证方式
POST https://api.hairoute.ai/v1/models/{model}:generateContent
将 {model} 替换为你在 模型列表 中可用的 Google/Gemini 图片模型名;请求体中不传 model。使用 HaiRoute API Key,在请求头中传 x-goog-api-key: YOUR_API_KEY,也可用 Authorization: Bearer YOUR_API_KEY。请勿将 Google API Key 用作 HaiRoute Key。
支持的图片模型
此端点仅用于 Google/Gemini 图片模型。| 模型标识 | 模型类型 | 模型描述 |
|---|---|---|
gemini-3.1-flash-lite-image | 图片生成与编辑 | Gemini 3.1 Flash Lite Image;配置的输出档位为 1K。 |
gemini-3.1-flash-image | 图片生成与编辑 | Gemini 3.1 Flash Image;配置的输出档位为 512(约 0.5K)、1K、2K、4K。 |
gemini-3-pro-image | 图片生成与编辑 | Gemini 3 Pro Image;配置的输出档位为 1K、2K、4K。 |
快速示例
curl -X POST 'https://api.hairoute.ai/v1/models/YOUR_GEMINI_IMAGE_MODEL:generateContent' \
-H 'x-goog-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"contents": [{"role": "user", "parts": [{"text": "一只橘猫戴着宇航员头盔漂浮在太空中"}]}],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"}
}
}'
candidates[].content.parts[].inlineData 中,以 mimeType 和 Base64 编码的 data 返回;文本(如有)位于同一 parts 数组的 text 字段。下方示例中的 Base64 仅为占位,不是实际图片:
{
"candidates": [{
"content": {"role": "model", "parts": [
{"text": "生成的图片:"},
{"inlineData": {"mimeType": "image/png", "data": "<BASE64_IMAGE_DATA>"}}
]},
"finishReason": "STOP"
}],
"usageMetadata": {"promptTokenCount": 12, "candidatesTokenCount": 1290, "totalTokenCount": 1302}
}
inlineData.data 解码为图片字节后,按照 mimeType 保存文件。响应不会变成 OpenAI Images 的 data[].url 结构;用量、候选内容及可选字段会随模型和实际请求变化。
关键参数
| 字段 | 说明 |
|---|---|
contents | 必填。消息列表;文生图时传入 role: "user" 与 parts: [{"text": "..."}]。 |
contents[].parts[].inlineData | 可选。编辑或多图参考时传入一张或多张图片,mimeType 为图片 MIME 类型,data 为不带 data URI 前缀的 Base64 字符串。 |
generationConfig.responseModalities | 图片输出使用 ["TEXT", "IMAGE"];图片可能与文本一起返回。 |
generationConfig.imageConfig.aspectRatio | 可选,图片宽高比,例如 1:1、16:9;取值以所选模型能力为准。 |
generationConfig.imageConfig.imageSize | 可选,图片档位,如 1K、2K、4K;以所选模型能力为准。 |
systemInstruction | 可选,Gemini 原生系统指令,结构同 contents 中的单条消息。 |
generationConfig.imageConfig,不是 OpenAI Images 的 size、quality、response_format 参数;不同模型的可用宽高比和档位以模型配置为准。
生成方式
以下示例只展示请求体;四种方式都使用本页同一个端点与认证方式,不需要新增mode 参数。图片 Base64 均为占位符,需替换为真实图片的纯 Base64 数据。
文生图
只传文本提示词,不传输入图片;可直接使用上面的快速示例。局部修改、风格转换等是提示词要求,不是独立的接口参数。单图编辑
在同一条user 消息中传入一张图片和编辑指令。下面是更换背景的例子;也可以在文本中要求保留主体、修改局部元素或调整风格。
{
"contents": [{"role": "user", "parts": [
{"inlineData": {"mimeType": "image/png", "data": "<BASE64_INPUT_IMAGE>"}},
{"text": "将背景改为日落海滩,保留主体"}
]}],
"generationConfig": {"responseModalities": ["TEXT", "IMAGE"]}
}
多图参考合成
将多张参考图放入同一条user 消息的 parts,用文本说明各图的用途。图片数量、尺寸及实际效果取决于所选模型和渠道的限制。
{
"contents": [{"role": "user", "parts": [
{"inlineData": {"mimeType": "image/png", "data": "<BASE64_SUBJECT_IMAGE>"}},
{"inlineData": {"mimeType": "image/jpeg", "data": "<BASE64_BACKGROUND_IMAGE>"}},
{"text": "以第一张图的人物为主体,使用第二张图的场景作为背景,生成一张自然的合照"}
]}],
"generationConfig": {"responseModalities": ["TEXT", "IMAGE"]}
}
多轮继续编辑
把前一轮的user 请求、实际返回的 candidates[0].content(作为 model 消息)和本轮的新指令依次放进 contents。下面仅示意结构:
{
"contents": [
{"role": "user", "parts": [{"text": "画一只戴围巾的橘猫"}]},
{"role": "model", "parts": [
{"inlineData": {"mimeType": "image/png", "data": "<BASE64_FROM_PREVIOUS_RESPONSE>"}}
]},
{"role": "user", "parts": [{"text": "保持橘猫与围巾不变,把背景换成雪地"}]}
],
"generationConfig": {"responseModalities": ["TEXT", "IMAGE"]}
}
model 内容;请原样回传上一轮的 candidates[0].content,包括图片、文本及 thoughtSignature(如果返回)。多轮编辑和多图参考的效果取决于所选图片模型。
常见错误排查
先检查 HTTP 状态及返回体中的error。不要在日志或求助信息中贴出 API Key、完整图片 Base64。
| 现象 | 排查方法 |
|---|---|
| 认证失败(如 401/403) | 确认使用 HaiRoute API Key,并通过 x-goog-api-key 或 Authorization: Bearer 传入;不要把 Google API Key 填在这里。检查 Key 是否有效、是否有模型访问权限。 |
| 模型找不到或不可用 | 检查 URL 中的 {model} 是否为当前账户 模型列表 中可用的 Google/Gemini 图片模型;不要把模型名放在请求体里,也不要用其他图片模型调用此端点。 |
| 请求参数或输入图片报错 | 核对 contents[].parts、generationConfig.responseModalities(图片输出为 ["TEXT", "IMAGE"])和所选模型支持的 imageConfig;inlineData.data 必须是纯 Base64,不含 data:image/...;base64, 前缀,mimeType 要与输入图片格式一致。 |
| 响应成功但没找到图片 | 逐个检查 candidates[].content.parts[].inlineData;图片不在 data[].url。若没有图片,检查返回的 finishReason、promptFeedback 和文本内容,再调整提示词或请求配置;不要把 HTTP 200 等同于已出图。 |
| 多轮编辑失败或没有延续上轮 | 按顺序回传先前的 user 消息、上一轮完整的 candidates[0].content(包括 thoughtSignature,如果返回)以及新的 user 指令;不要只回传图片 Base64。 |
下一步
- 查看 OpenAI 图片生成接口 接入其他图片模型
请求头
HaiRoute API Key。此处展示原生请求头;也可改用 Authorization: Bearer YOUR_API_KEY 认证(二选一)。
路径参数
HaiRoute 可用的 Google/Gemini 图片模型名称
请求体
application/json