Aller au contenu
Inscrivez-vous gratuitement
GPT Image

API de génération d’images

Générez des images GPT Image via l’API compatible OpenAI de BetterToken. Configurez API Key, Base URL et paramètres ; consultez exemples, coûts et erreurs.

POST /v1/images/generations

L’endpoint texte à image utilise un corps de Request application/json. Envoyez un prompt, gardez la Request HTTP ouverte et lisez chaque image dans data[].b64_json de la même réponse.

Choisir le bon parcours

  • Générer une image à partir d’un texte et enregistrer le résultat : restez sur cette page. Commencez par l’exemple curl, puis utilisez Enregistrer l’image pour décoder chaque entrée de data[].
  • Modifier une image existante : téléversez une ou plusieurs images de référence via l’API de modification d’image. Une modification ordinaire avec des références ne nécessite pas de masque ; ajoutez-en un uniquement pour une modification locale si le modèle et la taille choisis le permettent.
  • Choisir un modèle, vérifier les paramètres et estimer le budget : consultez les Model ID et prix actuels dans le model plaza, puis utilisez Valeurs recommandées ci-dessous pour les paramètres. Le guide GPT Image décrit le parcours complet.

Démarrage rapide avec curl

Utilisez https://bettertoken.ai/v1 comme Base URL et envoyez une Request à https://bettertoken.ai/v1/images/generations :

Fenêtre de terminal
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"
}'

Valeurs recommandées

Voici des valeurs de départ, et non des exigences fixes. Commencez par n=1 ; l’endpoint accepte un entier de 1 à 10, mais peut renvoyer moins d’images.

{
"model": "gpt-image-2",
"n": 1,
"response_format": "b64_json",
"output_format": "png"
}
ParamètreValeur à envoyerObjectif
modelgpt-image-2, gpt-image-2.5-flare ou gpt-image-2.5-sunburstChoisissez un Model ID disponible dans le model plaza. Un ID valide ne garantit pas que le modèle, la taille ou l’opération soit disponible pour la requête.
promptUne description textuelleChamp obligatoire. Décrivez le sujet, le style, la composition et les contraintes importantes.
sizeOmettez-le, utilisez auto ou indiquez des dimensions comme 1024x1024Demande une taille et un ratio ; les dimensions livrées peuvent différer.
nEntier de 1 à 10Nombre maximal demandé. Commencez par 1 ; moins d’images peuvent être renvoyées.
qualityauto, low, medium, high pour gpt-image-2 ; les modèles 2.5 acceptent aussi xhigh et maxPréférence facultative. Omettez le champ ou utilisez JSON null pour la valeur par défaut. Son acceptation ne garantit pas une meilleure qualité avec un niveau supérieur.
response_formatb64_jsonRenvoie chaque image en base64 dans data[].b64_json.
output_formatPar exemple pngFormat demandé, sans garantie d’encodage. Détectez le format réel à partir des octets avant l’enregistrement.

La réponse peut contenir moins d’images que n. Traitez chaque élément de data[] ; la recommandation n=1 n’est pas une limite du serveur.

Tailles recommandées

sizeRatioCas d’utilisation
autoAutoSélection automatique de la taille
1024x10241:1Images carrées, avatars, couvertures, ressources
1536x10243:2Affiches, bannières et scènes au format paysage
1024x15362:3Couvertures et affiches mobiles au format portrait
1536x11524:3Images paysage standard, images de produit, illustrations de contenu
1152x15363:4Images portrait standard, couvertures mobiles, affiches verticales
2048x20481:1Images carrées haute résolution
2048x115216:9Images paysage haute résolution
3840x216016:9Images paysage 4K
2160x38409:16Images portrait 4K

Les valeurs du tableau sont des exemples, pas une liste exhaustive. Vous pouvez omettre size ou utiliser auto ; null en JSON déclenche aussi le choix automatique. Les dimensions explicites doivent être positives et multiples de 16, chacune au plus égale à 3840 ; le ratio ne dépasse pas 3:1 et le total est compris entre 655360 et 8294400 pixels. 2080x2080 est valide. Les dimensions livrées peuvent différer : vérifiez l’image et ne la recadrez pas de force.

Enregistrer l’image

Une réponse réussie suit la structure de réponse d’image OpenAI compatible. Les montants ci-dessous illustrent le format du reçu et ne sont pas des prix fixes :

{
"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"
}
]
}
}

Lisez chaque data[].b64_json et autorisez les champs supplémentaires tels que revised_prompt dans votre client. BetterToken renvoie les détails de facturation dans l’objet racine bettertoken_image_billing. settled_amount et chaque outputs[].amount sont des chaînes décimales ; outputs[].index commence à 0.

output_format indique le format demandé, mais ne garantit pas le format encodé. Inspectez les octets de l’image et utilisez l’extension correspondante.

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)

Exemple 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);
}

Si votre application exige un encodage fixe PNG, JPEG ou WebP, identifiez d’abord le format réel, puis convertissez l’image si nécessaire. Changer uniquement l’extension du fichier ne convertit pas l’image.

Lire le coût réel

bettertoken_image_billing est renvoyé avec le résultat ; aucune requête séparée n’est nécessaire.

ChampSignification
currencyDevise du règlement, qui n’est pas toujours USD ou CNY.
settled_amountTotal réglé pour la requête, sous forme de chaîne décimale.
requested_resolutionNiveau de résolution déduit de la requête.
outputs[].indexIndex à partir de 0 correspondant à data[].
outputs[].width, heightLargeur et hauteur réelles, en pixels.
outputs[].billing_resolutionNiveau de facturation final de l’image.
outputs[].currency, amountDevise et montant réglés par image.

Les dimensions demandées et le niveau facturé peuvent différer : une requête 1024x1024 a renvoyé 1254x1254 avec une facturation 2K. Utilisez le montant du reçu et consultez les tarifs actuels dans le model plaza. Gardez les montants sous forme de chaînes à l’affichage et utilisez l’arithmétique décimale pour les calculs. Un reçu absent ne vaut pas zéro.

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

Flux de réponse

Cet endpoint est synchrone. Après l’envoi de POST /images/generations, gardez la Request HTTP actuelle ouverte jusqu’à la réponse du serveur. En cas de succès, chaque image est renvoyée dans data[].b64_json.

L’endpoint ne renvoie pas de task_id, et il n’existe pas d’endpoint distinct de requête de statut ou de téléchargement de résultat.

Avant le traitement, BetterToken peut préautoriser le prix unitaire applicable le plus élevé multiplié par n. Le solde peut suffire pour l’image 1K livrée sans couvrir cette retenue ; la requête est alors rejetée avec 403 et error.code=insufficient_user_quota. Le montant final dépend des images livrées.

Délais d’attente et tentatives

  • Réglez les délais d’attente du client HTTP sur plusieurs minutes.
  • Un délai d’attente, une déconnexion ou un 5xx ambigu ne confirme ni l’exécution ni la facturation. Ne renvoyez pas automatiquement la requête ; vérifiez les journaux et la consommation, puis conservez l’ID de requête et les en-têtes X-BetterToken-Image-Receipt et X-BetterToken-Billing-State reçus.
  • Ne réessayez pas automatiquement les erreurs de saisie, d’authentification, les paramètres manquants ou les Request malformées.
  • Réessayez 429 avec backoff uniquement après confirmation du rejet. Un ID de requête client ne rend pas le serveur idempotent ; aucun endpoint distinct ne permet de consulter l’état.

Gestion des erreurs

Les erreurs renvoient généralement du JSON. Lors de l’affichage d’une erreur, lisez d’abord error.message, puis message, puis le texte de statut HTTP.

Statut HTTPSignificationAction à effectuer
400JSON malformé, paramètre manquant ou taille non prise en chargeVérifiez le corps de Request. Ne réessayez pas automatiquement.
401API Key manquante ou non valideVérifiez l’en-tête Authorization: Bearer YOUR_API_KEY.
402 ou 403Solde ou quota insuffisantVérifiez error.code et le quota. Avec 403 et error.code=insufficient_user_quota, le solde peut couvrir l’image livrée, mais pas la préautorisation.
429Limite de débit, de concurrence ou amont occupéRéessayez avec backoff uniquement après confirmation du rejet.
5xxÉchec de passerelle ou amontL’exécution et la facturation peuvent être inconnues. Consultez les journaux et la consommation avant tout nouvel envoi délibéré.

Checklist d’intégration

  • La Base URL est https://bettertoken.ai/v1.
  • L’en-tête contient Authorization: Bearer sk-....
  • La requête utilise application/json.
  • Choisissez un Model ID disponible pour cette requête : gpt-image-2, gpt-image-2.5-flare ou gpt-image-2.5-sunburst.
  • Utilisez response_format=b64_json. output_format est une valeur demandée ; identifiez le format réel par les octets avant l’enregistrement.
  • n accepte des entiers de 1 à 10. Commencez par 1 ; moins d’images peuvent être renvoyées.
  • Omettez size, utilisez auto ou indiquez des dimensions valides. Le tableau ci-dessus n’est pas une liste exhaustive.
  • Le client HTTP autorise plusieurs minutes d’attente pour la génération.
  • Les journaux et captures d’erreurs ne révèlent pas la clé API ni le contenu base64 complet de l’image.

Documents associés

POST/v1/images/generations

Autorisations

Authorizationstringheaderrequis

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

Corps application/json

modelenum<string>défaut: gpt-image-2requis

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

Options disponibles: gpt-image-2, gpt-image-2.5-flare, gpt-image-2.5-sunburst

Exemple:"gpt-image-2"
promptstringrequis

A detailed description of the image to generate.

Exemple:"A futuristic AI product poster on a light background, with glass textures, a clean composition, and a premium technology aesthetic."
ninteger | nulldéfaut: 1

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

Plage requise: 1 <= x <= 10

Exemple:1
sizestring | nulldéfaut: 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.

Exemple:"1024x1024"
Exemple: ["auto","1024x1024","2048x2048","2080x2080","3840x2160"]
response_formatenum<string>défaut: b64_json

Use b64_json.

Options disponibles: b64_json

Exemple:"b64_json"
output_formatstringdéfaut: 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.

Exemple:"png"
qualityenum<string | null>défaut: 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.

Options disponibles: auto, low, medium, high, xhigh, max, null

Exemple:"auto"

Réponse

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
Exemple:1710000000
dataobject[]
Show child attributes

Base64-encoded image content.

Exemple:"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[].

Plage requise: x >= 0

Plage requise: x >= 1

Plage requise: x >= 1

Options disponibles: 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.

Exemple
{
  "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
Exemple:"invalid request"
Exemple:"invalid_request_error"
Exemple:"invalid_request"
messagestring
Exemple:"insufficient quota"
Exemple
{
  "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
Exemple:"invalid request"
Exemple:"invalid_request_error"
Exemple:"invalid_request"
messagestring
Exemple:"insufficient quota"
Exemple
{
  "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
Exemple:"invalid request"
Exemple:"invalid_request_error"
Exemple:"invalid_request"
messagestring
Exemple:"insufficient quota"
Exemple
{
  "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
Exemple
{
  "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
Exemple:"invalid request"
Exemple:"invalid_request_error"
Exemple:"invalid_request"
messagestring
Exemple:"insufficient quota"
Exemple
{
  "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
Exemple:"invalid request"
Exemple:"invalid_request_error"
Exemple:"invalid_request"
messagestring
Exemple:"insufficient quota"
Exemple
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}