Перейти к содержимому
Зарегистрироваться бесплатно
GPT Image

API генерации изображений

Генерируйте изображения по текстовому запросу через GPT Image и OpenAI-совместимый API BetterToken. Описаны API Key, Base URL, параметры, примеры, оплата и ошибки.

POST /v1/images/generations

Endpoint text-to-image использует тело запроса application/json. Передайте prompt, держите HTTP-запрос открытым и обработайте все изображения из data[].b64_json в том же ответе.

Выберите нужный сценарий

  • Сгенерировать изображение из текста и сохранить результат: оставайтесь на этой странице. Начните с примера curl, затем в разделе Сохранение изображения декодируйте каждый элемент data[].
  • Отредактировать изображение: загрузите одну или несколько референсных картинок через API редактирования изображений. Для обычного редактирования mask не нужна; добавьте её только для локального редактирования, если выбранные модель и размер поддерживают эту операцию.
  • Выбрать модель, параметры и оценить бюджет: проверьте доступные Model ID и цены в model plaza. Полный рабочий процесс описан в руководстве GPT Image 2.

Быстрый старт с curl

Используйте https://bettertoken.ai/v1 как Base URL и отправьте запрос на https://bettertoken.ai/v1/images/generations:

Окно терминала
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; endpoint принимает целое число от 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, доступный в model plaza. Допустимый ID не гарантирует доступность модели, размера или операции для конкретного запроса.
promptТекстовое описаниеОбязательное описание изображения. Укажите объект, стиль, композицию и важные ограничения.
sizeПропустите, укажите auto или задайте размеры, например 1024x1024Запрошенный размер и соотношение сторон; фактические размеры могут отличаться.
nЦелое число от 1 до 10Максимум изображений в запросе. Начните с 1; ответ может содержать меньше изображений.
qualityauto, low, medium, high для gpt-image-2; две модели 2.5 также принимают xhigh и maxНеобязательное предпочтение качества. Пропустите поле или передайте JSON null, чтобы использовать значение по умолчанию. Приём параметра не гарантирует улучшение изображения при повышении уровня.
response_formatb64_jsonВозвращает каждое изображение в base64 в data[].b64_json.
output_formatНапример, pngЗапрашивает формат, но не гарантирует соответствующую кодировку файла. Перед сохранением определите фактический формат по байтам.

Ответ может содержать меньше изображений, чем n. Обрабатывайте каждый элемент data[]; рекомендация использовать n=1 не является серверным ограничением.

Рекомендуемые размеры

sizeСоотношениеСценарий
autoAutoАвтоматический выбор размера
1024x10241:1Квадратные изображения, аватары, обложки, assets
1536x10243:2Landscape-постеры, баннеры, сцены
1024x15362:3Portrait-обложки для мобильных и постеры
1536x11524:3Стандартные landscape-изображения, product images, content graphics
1152x15363:4Стандартные portrait-изображения, mobile covers, vertical posters
2048x20481:1High-resolution квадратные изображения
2048x115216:9High-resolution landscape-изображения
3840x216016:94K landscape-изображения
2160x38409:164K portrait-изображения

Таблица содержит примеры, а не закрытый список. size можно пропустить или задать как auto; null в JSON включает автоматический выбор. Явные ширина и высота должны быть положительными кратными 16, каждая не больше 3840; соотношение сторон не должно превышать 3:1, а число пикселей должно быть от 655360 до 8294400. Например, 2080x2080 допустим. Фактический размер может отличаться от запрошенного, поэтому проверяйте размер изображения и не обрезайте его принудительно.

Сохранение изображения

Успешный ответ следует OpenAI-совместимой форме image response. Суммы ниже показывают формат квитанции и не являются фиксированными ценами:

{
"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 являются decimal strings, а outputs[].index начинается с 0. Фактические размеры и billing_resolution в этом объекте описывают завершённый расчёт.

output_format — запрос формата, а не гарантия кодирования или конвертации. Определяйте формат по байтам и используйте соответствующее расширение. Приведённые примеры распознают 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Индекс с нуля, соответствующий изображению в data[].
outputs[].width, heightФактические размеры изображения в пикселях.
outputs[].billing_resolutionИтоговый тарифный уровень изображения.
outputs[].currency, amountВалюта и сумма расчёта за изображение.

Размер запроса и тарифный уровень могут различаться: запрос 1024x1024 возвращал 1254x1254 с тарификацией 2K. Используйте сумму из квитанции; текущие цены указаны на модельной площадке. Для отображения сохраняйте суммы строками, для вычислений используйте десятичную арифметику. Отсутствующая квитанция не означает нулевую стоимость.

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']}"
)

Поток ответа

Endpoint синхронный. После отправки POST /images/generations держите HTTP-запрос открытым до ответа сервера. При успехе каждое изображение возвращается в data[].b64_json со сведениями о доставке и расчёте.

Endpoint не возвращает task_id; отдельного status query или endpoint для скачивания результата нет.

Тайм-ауты, повторные запросы и списания

Задайте timeout HTTP-клиента в несколько минут. Timeout, disconnect или неоднозначный 5xx не показывают, была ли генерация выполнена и списана ли оплата; соединение может прерваться при записи результата после расчёта, поэтому возможны повторные списания. Не повторяйте автоматически POST генерации или редактирования. Сначала проверьте записи потребления или логи запросов; сохраните возвращённый request ID и, если получены, заголовки X-BetterToken-Image-Receipt и X-BetterToken-Billing-State. Собственный request ID клиента не обеспечивает идемпотентность сервера; повторная отправка может создать новый запрос и списание. Отдельного endpoint проверки статуса нет.

Перед повторной отправкой исправьте отклонённые данные, аутентификацию или проблему квоты. Повторяйте 429 с backoff только после подтверждения отказа запроса. Не считайте все 5xx или транспортные ошибки безопасными для повтора.

Для предварительной авторизации BetterToken может удержать максимум: наибольшая применимая цена за единицу, умноженная на n. Поэтому баланса, достаточного для фактически доставленного изображения 1K, может не хватить на предварительную авторизацию; такой отказ возвращается как 403 с error.code=insufficient_user_quota. После обработки сумма рассчитывается по фактически доставленным изображениям. Корневой bettertoken_image_billing содержит итоговый settled_amount, валюту и amount, billing_resolution и размеры каждого результата. Денежные значения — decimal strings; фактическое число изображений может быть меньше n.

Обработка ошибок

Ошибка обычно возвращается как JSON. При отображении сообщения сначала прочитайте error.message, затем message, а после этого HTTP status text.

HTTP statusЗначениеЧто делать
400Некорректный JSON, отсутствует параметр или неподдерживаемый размерПроверьте тело запроса. Не повторяйте автоматически.
401API Key отсутствует или недействителенПроверьте header Authorization: Bearer YOUR_API_KEY.
402 или 403Недостаточно квоты или баланса, включая удержание средствПроверьте error.code и квоту/баланс аккаунта. 403 с error.code=insufficient_user_quota означает, что баланс может быть ниже предварительной авторизации по верхнему пределу.
429Rate limit, ограничение concurrency или занятый upstreamПовторяйте с backoff только после подтверждения отказа запроса.
5xxОшибка gateway или upstreamВыполнение и списание могут быть неизвестны. Перед осознанной повторной отправкой проверьте логи и потребление.

Чек-лист подключения

  • Base URL: https://bettertoken.ai/v1.
  • Заголовок содержит 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 или указать допустимые размеры. Таблица выше не является закрытым списком.
  • HTTP-клиент допускает ожидание генерации в течение нескольких минут.
  • Логи и скриншоты ошибок не раскрывают API Key или полное содержимое изображения в base64.

Смежные документы

POST/v1/images/generations

Авторизации

Authorizationstringheaderобязательно

Используйте API Key BetterToken как bearer token. Не публикуйте API keys во frontend-коде, скриншотах, логах, тикетах или Git-репозиториях.

Тело application/json

modelenum<string>по умолчанию: gpt-image-2обязательно

Model ID GPT Image. Один BetterToken API Key работает со всеми доступными моделями.

Доступные опции: gpt-image-2, gpt-image-2.5-flare, gpt-image-2.5-sunburst

Пример:"gpt-image-2"
promptstringобязательно

Prompt для генерации изображения.

Пример:"Футуристичный постер 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 не гарантируется. Определяйте 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"

Ответ

200Расширение тарификации BetterToken. Сумма определяется фактическими пикселями и тарифным уровнем результата, который может отличаться от запрошенного. Денежные суммы — десятичные строки; используйте значения из ответа.

OpenAI-совместимый ответ с изображениями. Перебирайте data[] и читайте b64_json каждого изображения, допуская дополнительные поля, например revised_prompt. Фактическое число изображений может быть меньше запрошенного.

createdinteger
Пример:1710000000
dataobject[]
Show child attributes

Содержимое изображения в кодировке Base64.

Пример:"iVBORw0KGgoAAAANSUhEUgAA...(truncated)"

Необязательный переписанный 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Сработал rate limit, лимит параллельных запросов или upstream временно перегружен.
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Ошибка gateway или upstream-сервиса.
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"
}