콘텐츠로 이동
무료 가입
GPT Image

이미지 생성 API

BetterToken의 OpenAI 호환 API로 GPT Image 이미지를 생성하세요. API Key, Base URL, 매개변수, Python·JavaScript 예제와 오류 해결을 안내합니다.

POST /v1/images/generations

text-to-image endpoint는 application/json request body를 사용합니다. prompt를 제출하고 HTTP request를 열어 둔 뒤 같은 response의 data[].b64_json에서 모든 이미지를 읽으세요.

알맞은 작업 흐름 선택

  • 텍스트로 이미지를 생성하고 결과 저장: 이 페이지를 계속 사용하세요. curl 예제로 시작한 다음 이미지 저장에서 data[]의 각 항목을 decode하세요.
  • 기존 이미지 편집: 이미지 편집 API에 reference image를 하나 이상 업로드하세요. 일반 reference edit에는 mask가 필요하지 않습니다. local edit가 필요한 경우 선택한 model과 size에서 지원할 때만 mask를 추가하세요.
  • 모델과 parameters를 선택하고 budget 추정: 현재 Model ID와 가격은 모델 광장에서 확인하고 request parameters는 아래 권장 값을 참고하세요. 전체 흐름은 GPT Image 가이드에서 확인할 수 있습니다.

curl 빠른 시작

https://bettertoken.ai/v1을 Base URL로 사용하고 https://bettertoken.ai/v1/images/generations로 request를 보내세요.

터미널 창
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"
}
Parameter보낼 값목적
modelgpt-image-2, gpt-image-2.5-flare 또는 gpt-image-2.5-sunburstmodel plaza에서 사용 가능한 Model ID를 선택합니다. ID가 유효해도 요청에서 모델, 크기 또는 작업을 사용할 수 있다고 보장하지 않습니다.
prompttext description필수입니다. subject, style, composition 및 중요한 constraints를 설명하세요.
size생략, auto 또는 1024x1024 같은 dimensions출력 크기와 비율을 요청합니다. 실제 제공 크기는 다를 수 있습니다.
n1~10 정수요청할 최대 image 수입니다. 1부터 시작하고 더 적게 반환될 수 있습니다.
qualitygpt-image-2는 auto, low, medium, high; 두 2.5 모델은 xhigh, max도 허용선택적 품질 설정입니다. 생략하거나 JSON null을 지정하면 기본값을 사용합니다. 매개변수가 허용되어도 설정을 높였을 때 이미지 품질이 향상된다고 보장하지 않습니다.
response_formatb64_json각 이미지를 data[].b64_json의 base64로 반환합니다.
output_format예: png요청 형식이며 실제 인코딩을 보장하지 않습니다. 저장 전에 bytes로 실제 형식을 확인하세요.

응답은 n보다 적은 이미지를 포함할 수 있습니다. data[]의 모든 항목을 처리하세요. n=1 권장은 서버 제한이 아닙니다.

권장 크기

size비율사용 사례
auto자동자동 size 선택
1024x10241:1정사각형 images, avatars, covers, assets
1536x10243:2가로 posters, banners, scenes
1024x15362:3세로 mobile covers 및 posters
1536x11524:3표준 가로 images, product images, content graphics
1152x15363:4표준 세로 images, mobile covers, vertical posters
2048x20481:1고해상도 정사각형 images
2048x115216:9고해상도 가로 images
3840x216016:94K 가로 images
2160x38409:164K 세로 images

표의 값은 예시이며 전체 목록이 아닙니다. size를 생략하거나 auto를 지정할 수 있고, JSON null도 자동 선택을 사용합니다. 명시적 width와 height는 양수인 16의 배수이며 각각 최대 3840, aspect ratio는 3:1 이하, 총 pixels는 655360~8294400이어야 합니다. 2080x2080도 유효합니다. 실제 반환 dimensions는 다를 수 있으므로 이미지를 확인하고 강제로 crop하지 마세요.

이미지 저장

성공한 response는 다음 OpenAI-compatible image response shape를 따릅니다. 아래 금액은 receipt 형식의 예시이며 고정 가격이 아닙니다.

{
"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 등의 extra fields도 허용하세요. BetterToken은 root bettertoken_image_billing object에 billing details를 반환합니다. settled_amount와 각 outputs[].amount는 decimal string이며 outputs[].index는 0부터 시작합니다.

output_format은 요청 형식일 뿐 실제 encoding이나 변환을 보장하지 않습니다. image bytes를 확인하고 일치하는 확장자로 저장하세요.

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요청의 총 정산 금액이며 decimal string입니다.
requested_resolution요청에서 식별한 해상도 등급입니다.
outputs[].indexdata[]와 대응하는 0부터 시작하는 이미지 인덱스입니다.
outputs[].width, height이미지의 실제 너비와 높이이며 단위는 픽셀입니다.
outputs[].billing_resolution이미지에 최종 적용된 과금 등급입니다.
outputs[].currency, amount이미지별 정산 통화와 금액입니다.

요청 크기와 과금 등급은 다를 수 있습니다. 1024x1024 요청에서 1254x1254가 반환되어 2K로 과금된 사례가 있습니다. 영수증의 실제 금액을 사용하고 현재 가격은 모델 광장에서 확인하세요. 표시에는 문자열을 유지하고 계산에는 decimal 연산을 사용하세요. 영수증이 없다고 비용을 0으로 기록하지 마세요.

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는 synchronous입니다. POST /images/generations를 보낸 후 server가 response할 때까지 현재 HTTP request를 열어 두세요. 성공하면 모든 이미지가 data[].b64_json으로 반환됩니다.

endpoint는 task_id를 반환하지 않으며 별도의 status query 또는 result download endpoint가 없습니다.

처리 전에 BetterToken은 가장 높은 적용 단가에 n을 곱한 상한을 사전 승인할 수 있습니다. 제공된 1K 이미지 금액을 지불할 balance가 있어도 이 hold에는 부족할 수 있으며, 이 경우 403과 error.code=insufficient_user_quota로 거부됩니다. 최종 billing은 실제 제공된 이미지 수를 기준으로 합니다.

시간 초과와 재시도

  • HTTP client timeouts를 몇 분으로 설정하세요.
  • timeout, disconnect 또는 모호한 5xx는 실행이나 billing 여부를 알려주지 않습니다. 자동으로 재전송하지 말고 consumption records 또는 request logs를 확인하세요. 반환된 request ID와 수신한 X-BetterToken-Image-Receipt, X-BetterToken-Billing-State headers를 보관하세요.
  • 입력 또는 인증 오류, missing parameters 또는 malformed requests는 자동 retry하지 마세요.
  • 429는 request가 reject되었음을 확인한 경우에만 backoff로 retry하세요. client-generated request ID는 server idempotency를 보장하지 않으며 별도 status query endpoint도 없습니다.

오류 처리

errors는 일반적으로 JSON을 반환합니다. error를 표시할 때는 error.message를 먼저 읽고 message, HTTP status text 순서로 읽으세요.

HTTP status의미수행할 작업
400malformed JSON, missing parameter 또는 unsupported sizerequest body를 확인하세요. 자동 retry하지 마세요.
401API Key가 없거나 invalid함Authorization: Bearer YOUR_API_KEY header를 확인하세요.
402 또는 403balance 또는 quota 부족error.code를 확인하세요. 403과 error.code=insufficient_user_quota는 실제 delivered image 금액은 있어도 preauthorization 한도에는 부족할 수 있습니다.
429rate limit, concurrency limit 또는 busy upstreamrequest rejection을 확인한 경우에만 backoff로 retry하세요.
5xxgateway 또는 upstream failure실행 및 billing 여부가 불명확할 수 있습니다. 재전송 전에 logs와 consumption을 확인하세요.

연결 확인 목록

  • 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필수

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

본문 application/json

modelenum<string>기본값: gpt-image-2필수

GPT Image Model ID. One BetterToken API Key works with all available models.

사용 가능한 옵션: gpt-image-2, gpt-image-2.5-flare, gpt-image-2.5-sunburst

예제:"gpt-image-2"
promptstring필수

A detailed description of the image to generate.

예제:"A futuristic AI product poster on a light background, with glass textures, a clean composition, and a premium technology aesthetic."
ninteger | null기본값: 1

Allowed range: 1–10; start with 1. Fewer images may be delivered than requested. Iterate data[] and use actual-delivery billing.

필수 범위: 1 <= x <= 10

예제:1
sizestring | null기본값: 1024x1024

Omit or use auto for automatic sizing. For WxH, both dimensions must be positive multiples of 16, each at most 3840, aspect ratio at most 3:1, total pixels 655360–8294400. Examples are not an exhaustive enum; 2080x2080 also meets the geometry rules. Inspect actual decoded dimensions. Valid parameters do not guarantee an available service.

예제:"1024x1024"
예제: ["auto","1024x1024","2048x2048","2080x2080","3840x2160"]
response_formatenum<string>기본값: b64_json

Use b64_json.

사용 가능한 옵션: b64_json

예제:"b64_json"
output_formatstring기본값: png

Requested output format; png is recommended, but the response is not guaranteed to have been transcoded to PNG. Detect PNG, JPEG, or WebP from actual bytes before choosing an extension. Convert locally if a specific format is required.

예제:"png"
qualityenum<string | null>기본값: auto

gpt-image-2 accepts auto, low, medium, high. The two 2.5 models also accept xhigh and max. Omit for the model default; JSON null is treated as omitted, while multipart requires a nonempty string. Valid values do not guarantee an available service for every model, size, and editing combination. Acceptance does not guarantee that a higher setting improves image quality.

사용 가능한 옵션: auto, low, medium, high, xhigh, max, null

예제:"auto"

응답

200BetterToken billing extension. Settlement follows the actual delivered pixels and billing tier, which can differ from the requested tier. Amounts are decimal strings; use the returned values.

OpenAI-compatible image response. Iterate data[] and read each image from b64_json. Fewer images may be delivered than requested.

createdinteger
예제:1710000000
dataobject[]
Show child attributes

Base64-encoded image content.

예제:"iVBORw0KGgoAAAANSUhEUgAA...(truncated)"

BetterToken billing extension. Settlement follows the actual delivered pixels and billing tier, which can differ from the requested tier. Amounts are decimal strings; use the returned values.

Show child attributes

Settlement currency; do not assume a fixed currency.

Final request amount as a decimal string; use decimal arithmetic for calculations.

Delivered image indices, actual dimensions, billing tiers, and per-image amounts. index is zero-based and corresponds to data[].

필수 범위: x >= 0

필수 범위: x >= 1

필수 범위: x >= 1

사용 가능한 옵션: 1K, 2K, 4K

Settled amount for this image as a decimal string.

Resolution tier inferred from the request; it may differ from the actual billing tier.

예제
{
  "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>"
  }
}
400Invalid request format, missing parameters, malformed JSON or multipart data, or invalid dimensions.
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"
}
401The BetterToken API Key is missing or invalid.
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"
}
402The account has insufficient credit or balance.
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"
}
403Insufficient balance or token quota: error.code is insufficient_user_quota. Funds must also cover the reservation of the highest-tier unit price times the image-count upper bound, before actual-delivery settlement. Inspect error.code rather than treating every 403 as an authorization error.
errorobject
Show child attributes
예제
{
  "error": {
    "code": "insufficient_user_quota",
    "message": "Insufficient balance or token quota."
  }
}
429A rate or concurrency limit was reached, or the upstream service is busy.
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"
}
500The gateway or upstream service returned an error.
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"
}