跳转到内容
免费注册
GPT Image

GPT Image 文生图 API

通过 BetterToken 的 OpenAI-compatible API 调用 GPT Image 生成图片,包含 API Key、Base URL、参数、Python、JavaScript 与错误处理。

POST /v1/images/generations

文生图接口使用 application/json 请求体。你提交提示词后,接口会同步等待生成完成,并在同一个响应的 data[].b64_json 中返回各张图片。

选择对应场景

  • 根据文本生成并保存图片:继续使用本页。先运行下方 curl 示例,再按照 保存返回图片 读取并解码 data[] 中的每张图片。
  • 编辑已有图片:前往图片编辑 API,上传一张或多张参考图;需要局部编辑时可额外上传 mask。
  • 选择模型、查看参数并估算预算:在模型广场核对当前可用 Model ID 和价格。完整工作流可阅读 GPT Image 2 指南。

使用 curl 快速调用

先将 YOUR_API_KEY 替换为你的 BetterToken API Key。一个 Key 可调用所有可用模型。以下请求将完整响应保存到 response.json,供后面的 Python 示例读取:

终端窗口
curl --max-time 300 -X POST "https://bettertoken.ai/v1/images/generations" \
-o response.json \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A product photo of a green ceramic mug on a studio table",
"size": "1024x1024",
"n": 1,
"response_format": "b64_json",
"output_format": "png"
}'

推荐请求值

以下是起步建议,并非固定要求。建议先使用 n=1;接口接受 1 到 10 的整数,但实际返回图片数可能少于请求数。

{
"model": "gpt-image-2",
"n": 1,
"response_format": "b64_json",
"output_format": "png"
}
参数填写内容作用
modelgpt-image-2、gpt-image-2.5-flare 或 gpt-image-2.5-sunburst选择模型广场中显示可用的 Model ID。ID 和参数合法不代表当前请求一定能使用该模型、尺寸或操作。
prompt文本描述必填。描述主体、风格、构图和重要限制。
size省略、使用 auto 或提供如 1024x1024 的尺寸请求输出尺寸和比例;实际交付尺寸可能不同。
n1 到 10 的整数请求图片数上限。建议从 1 开始;实际返回数可能更少。
qualitygpt-image-2 支持 auto、low、medium、high;两个 2.5 模型还接受 xhigh、max可选质量偏好。省略或在 JSON 中设为 null 时使用默认值。参数被接受不保证画面质量随档位提高。
response_formatb64_json在 data[].b64_json 中以 base64 返回每张图片。
output_format例如 png请求输出格式。保存前根据文件字节识别实际格式,需要固定编码时按需转码。

实际返回图片数可能少于 n。请处理 data[] 中的每一项;建议使用 n=1 不代表服务端限制为一张。

推荐尺寸

size比例适用场景
auto自动自动选择尺寸
1024x10241:1方图,通用头像、封面、素材图
1536x10243:2横图,海报、banner、场景图
1024x15362:3竖图,移动端封面、人物海报
1536x11524:3标准横图,商品图、内容配图、横版素材
1152x15363:4标准竖图,移动端封面、竖版海报、人物图
2048x20481:1高清方图
2048x115216:9高清横图
3840x216016:94K 横图
2160x38409:164K 竖图

表格列出常用示例,并非封闭清单。你可以省略 size 或设为 auto;JSON 中的 size: null 也会自动选择尺寸。显式宽高必须为正数且是 16 的倍数,各不超过 3840,宽高比不超过 3:1,像素总数为 655360 到 8294400。例如 2080x2080 是合法尺寸。请求尺寸表示目标,实际交付尺寸可能不同;请读取图片真实尺寸,不要强行裁切。

保存返回图片

成功响应为 OpenAI 兼容图片响应结构。下面的金额用于展示回执格式,不代表固定价格:

{
"created": 1710000000,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA...(truncated)",
"revised_prompt": "Optional revised prompt"
}
],
"bettertoken_image_billing": {
"currency": "CNY",
"settled_amount": "0.15",
"outputs": [
{
"index": 0,
"width": 1254,
"height": 1254,
"billing_resolution": "2K",
"currency": "CNY",
"amount": "0.15"
}
]
}
}

客户端应读取 data[].b64_json 并允许 revised_prompt 等额外字段。BetterToken 在根级 bettertoken_image_billing 对象中返回计费明细,其中 settled_amount 和每张图片的 amount 是十进制字符串,outputs[].index 从 0 开始。该对象中的实际交付尺寸和 billing_resolution 是本次请求计费结果的依据。

保存图片时按返回字节识别真实格式,再选择文件扩展名。以下标准库示例可识别 PNG、JPEG 和 WebP,无需新增依赖。

import base64
import json
from pathlib import Path
result = json.loads(Path("response.json").read_text(encoding="utf-8"))
for index, item in enumerate(result["data"], start=1):
encoded = item["b64_json"]
if "," in encoded and "base64" in encoded.split(",", 1)[0]:
encoded = encoded.split(",", 1)[1]
image_bytes = base64.b64decode(encoded)
if image_bytes.startswith(b"\x89PNG\r\n\x1a\n"):
extension = "png"
elif image_bytes.startswith(b"\xff\xd8\xff"):
extension = "jpg"
elif image_bytes.startswith(b"RIFF") and image_bytes[8:12] == b"WEBP":
extension = "webp"
else:
raise ValueError("Unsupported image signature")
Path(f"output-{index}.{extension}").write_bytes(image_bytes)

JavaScript 示例(Node.js)

import { writeFile } from "node:fs/promises";
const response = await fetch("https://bettertoken.ai/v1/images/generations", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-image-2",
prompt: "A green ceramic mug on a studio table",
size: "1024x1024",
n: 1,
response_format: "b64_json",
output_format: "png",
}),
});
if (!response.ok) {
throw new Error(await response.text());
}
const result = await response.json();
const { data } = result;
for (const [index, item] of data.entries()) {
const b64Json = item.b64_json.replace(/^data:.*;base64,/, "");
const imageBytes = Buffer.from(b64Json, "base64");
let extension;
if (imageBytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
extension = "png";
} else if (imageBytes[0] === 0xff && imageBytes[1] === 0xd8 && imageBytes[2] === 0xff) {
extension = "jpg";
} else if (imageBytes.toString("ascii", 0, 4) === "RIFF" && imageBytes.toString("ascii", 8, 12) === "WEBP") {
extension = "webp";
} else {
throw new Error("Unsupported image signature");
}
await writeFile(`output-${index + 1}.${extension}`, imageBytes);
}

若业务要求固定的 PNG、JPEG 或 WebP 编码,请在识别实际格式后按需转码;仅修改扩展名不会转换图片。

读取实际费用

bettertoken_image_billing 随生成结果一起返回,无需额外调用费用查询接口。

字段含义
currency本次结算币种。不要假定始终为 USD 或 CNY。
settled_amount本次请求实际结算总额,使用十进制字符串表示。
requested_resolution根据请求识别的尺寸档位。
outputs[].index图片编号,从 0 开始,对应 data[]。
outputs[].width、height对应图片的实际宽、高,单位为像素。
outputs[].billing_resolution对应图片最终使用的计费档位。
outputs[].currency、amount对应图片的结算币种和金额。

请求尺寸与计费档位可能不同。例如,已有请求 1024×1024、实际返回 1254×1254 并按 2K 结算的结果。请读取回执中的实际金额;当前单价在模型广场查看。

下面的代码接在 Python 保存示例后使用。金额保留为字符串展示;需要计算时使用十进制类型,避免浮点误差。缺少回执时不能把费用记为零。

from decimal import Decimal
billing = result.get("bettertoken_image_billing")
if billing is None:
print("Billing receipt unavailable; check your usage records.")
else:
total = Decimal(billing["settled_amount"])
print(f"Total: {billing['currency']} {total}")
for output in billing.get("outputs", []):
print(
f"Image {output['index'] + 1}: "
f"{output['width']}x{output['height']}, "
f"{output['billing_resolution']}, "
f"{output['currency']} {output['amount']}"
)

响应流程

文生图接口是同步响应模式。客户端提交 POST /images/generations 后,应保持当前 HTTP 请求连接并等待服务端返回。生成成功时,每张图片都在同一响应的 data[].b64_json 中返回,并附有交付与计费明细。

文生图不会返回 task_id,也没有单独的状态查询接口或结果下载接口。不需要轮询任务状态,也不能通过额外的 /images/... URL 再获取结果。

超时、重试和计费

HTTP 客户端超时建议设置为数分钟。超时、断连或含义不明的 5xx 不能证明生成是否执行或计费;结算后写回结果时连接也可能失败,因此存在重复计费风险。不要自动重复生成或编辑 POST。先检查消费记录或请求日志,保留返回的 request ID,以及已收到时的 X-BetterToken-Image-Receipt 和 X-BetterToken-Billing-State 响应头。客户端自行生成的 request ID 不会让服务端具备幂等性;主动重发可能产生新请求和新费用。没有单独的状态查询接口。

先修正被拒绝的输入、认证或额度问题。只有确认 429 表示请求已被拒绝后,才可退避重试。不要把所有 5xx 或传输异常都视为可安全重试。

处理请求前,BetterToken 可能按最高适用单价乘以 n 预授权上限,再按实际交付图片结算。因此,余额可能足以支付实际交付的 1K 图片,却不足以通过这笔预授权;此时请求返回 403,且 error.code=insufficient_user_quota。根级 bettertoken_image_billing 返回最终 settled_amount、币种,以及每张图片的 amount、billing_resolution 和交付尺寸;金额为十进制字符串。实际交付数可能少于 n。

错误处理

错误响应通常是 JSON。展示错误时,建议按顺序读取:

  1. error.message
  2. message
  3. HTTP status text
HTTP 状态码含义建议处理
400请求格式错误、缺少参数、JSON 解析失败、尺寸格式错误检查请求体,不要自动重试。
401API Key 缺失或无效检查 Authorization header。
402 或 403额度或余额不足,包括余额冻结检查 error.code 及账户额度/余额。403 且 error.code=insufficient_user_quota 表示余额可能低于预授权上限。
429触发限速、并发限制或上游繁忙确认请求已被拒绝后再退避重试。
5xx网关或上游服务异常执行与计费状态可能未知。考虑主动重发前,先核对请求日志和消费记录。

接入检查清单

  • Base URL 是 https://bettertoken.ai/v1。
  • Header 包含 Authorization: Bearer sk-...。
  • 请求使用 application/json。
  • 选择当前请求可用的 Model ID:gpt-image-2、gpt-image-2.5-flare 或 gpt-image-2.5-sunburst。
  • 使用 response_format=b64_json;output_format 只是请求值,保存时按字节识别格式。
  • n 可设为 1 到 10;建议使用 1,实际返回数可能更少。
  • size 可省略、设为 auto 或填写有效尺寸;上表不是封闭清单。
  • 客户端能处理数分钟级别的生成耗时。
  • 日志和报错截图中不会泄露 API Key 或完整 base64 图片内容。

相关文档

POST/v1/images/generations

授权

Authorizationstringheader必填

Use your BetterToken API Key as a bearer token. Do not expose API keys in frontend browser code, screenshots, logs, tickets, or Git repositories.

请求体 application/json

modelenum<string>默认值: gpt-image-2必填

GPT Image 模型 ID。一个 BetterToken API Key 可调用所有可用模型。

可用选项: gpt-image-2, gpt-image-2.5-flare, gpt-image-2.5-sunburst

示例:"gpt-image-2"
promptstring必填

图片生成提示词。

示例:"一张未来感 AI 产品海报,浅色背景,玻璃质感,干净构图,高级科技感"
ninteger | null默认值: 1

允许 1~10,建议先用 1。实际交付可能少于请求张数;遍历 data[] 并按交付结果结算。

必填范围: 1 <= x <= 10

示例:1
sizestring | null默认值: 1024x1024

省略或 auto 使用自动尺寸。WxH 的宽高必须为正数且均为 16 的倍数,单边不超过 3840,长短边比不超过 3:1,总像素为 655360~8294400。示例不是封闭枚举,例如 2080x2080 也符合几何约束。实际输出以解码尺寸为准;参数合法不保证有对应可用服务。

示例:"1024x1024"
示例: ["auto","1024x1024","2048x2048","2080x2080","3840x2160"]
response_formatenum<string>默认值: b64_json

推荐固定为 b64_json,便于稳定保存图片。

可用选项: b64_json

示例:"b64_json"
output_formatstring默认值: png

请求的输出格式,例如 png。保存时按实际图片字节识别 PNG、JPEG 或 WebP,再选择对应扩展名;需要固定编码时按需转码。

示例:"png"
qualityenum<string | null>默认值: auto

画质选项:gpt-image-2 使用 auto、low、medium、high;两款 2.5 模型还接受 xhigh、max。省略时使用模型默认值;JSON null 按未填写处理,multipart 必须填写非空字符串。参数合法不保证当前有对应模型、尺寸和编辑组合的可用服务。参数接受不保证画面质量随档位提高。

可用选项: auto, low, medium, high, xhigh, max, null

示例:"auto"

响应

200BetterToken 扩展计费信息。按实际交付图片的像素与计费档位结算;请求档位不保证等于计费档位。金额是十进制字符串,以响应为准。

OpenAI 兼容图片响应。遍历 data[],读取每张图片的 b64_json,并允许 revised_prompt 等额外字段。实际交付数量可能少于请求数量。

createdinteger
示例:1710000000
dataobject[]
Show child attributes

Base64-encoded image content.

示例:"iVBORw0KGgoAAAANSUhEUgAA...(truncated)"

Optional revised prompt.

BetterToken 扩展计费信息。按实际交付图片的像素与计费档位结算;请求档位不保证等于计费档位。金额是十进制字符串,以响应为准。

Show child attributes

本次结算币种,不应假定为固定币种。

本次实际结算总额,十进制字符串;计算时使用十进制类型。

实际交付图片的编号、真实尺寸、计费档位和单张金额。index 从 0 开始,对应 data[] 中的图片。

必填范围: x >= 0

必填范围: x >= 1

必填范围: x >= 1

可用选项: 1K, 2K, 4K

对应图片的实际结算金额,十进制字符串。

根据请求识别的尺寸档位,可能与实际计费档位不同。

示例
{
  "created": 1710000000,
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUgAA...(truncated)",
      "revised_prompt": "<string>"
    }
  ],
  "bettertoken_image_billing": {
    "currency": "<string>",
    "settled_amount": "<string>",
    "outputs": [
      {
        "index": 0,
        "width": 1,
        "height": 1,
        "billing_resolution": "1K",
        "currency": "<string>",
        "amount": "<string>"
      }
    ],
    "partial": false,
    "requested_resolution": "<string>"
  }
}
400请求格式错误、缺少参数、JSON 或 multipart 解析失败、尺寸格式错误。
errorobject
Show child attributes
示例:"invalid request"
示例:"invalid_request_error"
示例:"invalid_request"
messagestring
示例:"insufficient quota"
示例
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
401API Key 缺失或无效。
errorobject
Show child attributes
示例:"invalid request"
示例:"invalid_request_error"
示例:"invalid_request"
messagestring
示例:"insufficient quota"
示例
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
402额度或余额不足。
errorobject
Show child attributes
示例:"invalid request"
示例:"invalid_request_error"
示例:"invalid_request"
messagestring
示例:"insufficient quota"
示例
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
403余额或令牌额度不足,error.code 为 insufficient_user_quota。也可能不足以预占最高档单价乘图片数量上限的额度;按实际交付结算。结合 error.code 判断,不要只按 403 认定为权限错误。
errorobject
Show child attributes
示例
{
  "error": {
    "code": "insufficient_user_quota",
    "message": "Insufficient balance or token quota."
  }
}
429触发限速、并发限制或上游繁忙。
errorobject
Show child attributes
示例:"invalid request"
示例:"invalid_request_error"
示例:"invalid_request"
messagestring
示例:"insufficient quota"
示例
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
500网关或上游服务异常。
errorobject
Show child attributes
示例:"invalid request"
示例:"invalid_request_error"
示例:"invalid_request"
messagestring
示例:"insufficient quota"
示例
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}