GPT-6 Sol et Claude Opus 5.5 disponiblesGPT-6 Sol à moitié prix par rapport à 5.6 Sol

API GPT Image 2.5 : générer et modifier des images en Python

Un POST crée la tâche, un GET en lit le résultat. Voici le code de la requête, les tailles testées le 29 octobre 2026 et une modification avec l'avant et l'après.

Kiki, OmniaKey COO7 minutes de lecture
Sur cette page

Envoyez un POST à https://api.omniakey.com/v1/media/tasks avec model sur gpt-image-2.5-flare, interrogez l'id de tâche renvoyé, puis téléchargez assets[0].url dès que le statut affiche succeeded. Le 29 octobre 2026, nous avons généré en 1K, 2K et 1536x1024 et modifié une photo de café, puis ouvert chaque fichier pour lire la taille réelle en pixels : 1024×1024, 2048×2048, 1536×1024 et 1024×682. La génération en 1K a pris 29.5 s et celle en 2K, 45.2 s.

Quel id de modèle 2.5 utiliser

Utilisez gpt-image-2.5-flare. C'est l'id appelé dans toutes les exécutions ci-dessous. La page du modèle GPT-Image 2.5 Flare (vérifiée le 29 octobre 2026) indique OpenAI comme fournisseur, mentionne la génération à partir de texte et la modification d'image, et porte la note « Guide updated 2026-10-27 ». La même page donne un second id 2.5, gpt-image-2.5-sunburst.

Flare assure les deux tâches. La génération envoie un prompt ; la modification envoie un prompt et une image source. La qualité accepte low, medium ou high, et la même page précise que le niveau ne change pas le prix. Toutes les exécutions ici ont utilisé medium. Nous n'avons pas testé sunburst, les qualités low et high, le 4K ni le 3840x2160, les masques, ni plusieurs images de référence : prévoyez donc Flare en medium avec une seule image source jusqu'à ce que vous testiez le reste.

Le code de la requête

Le script ci-dessous est celui exécuté, sans modification : deux fonctions utilitaires, puis un appel de génération et un appel de modification. Il n'utilise que la bibliothèque standard de Python, lit votre clé dans OMNIAKEY_API_KEY et écrit chaque PNG dans le dossier depuis lequel vous le lancez.

python
import base64
import json
import os
import time
import urllib.request
import uuid

API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "gpt-image-2.5-flare"

def request(method, url, body=None, extra_headers=None):
    headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
    data = None
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode()
    headers.update(extra_headers or {})
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    with urllib.request.urlopen(req, timeout=120) as resp:
        return json.load(resp)

def run_task(body, out_path):
    task = request("POST", API, body, {"Idempotency-Key": str(uuid.uuid4())})["id"]
    for _ in range(150):
        time.sleep(4)
        state = request("GET", f"{API}/{task}")
        if state["status"] not in ("queued", "processing"):
            break
    if state["status"] != "succeeded":
        raise RuntimeError(state.get("error") or state["status"])
    asset_url = state["assets"][0]["url"]  # lien signé : valable environ une heure, téléchargez tout de suite
    req = urllib.request.Request(asset_url, headers={"User-Agent": "omniakey-example/1"})
    with urllib.request.urlopen(req, timeout=120) as resp, open(out_path, "wb") as f:
        f.write(resp.read())
    return task

def generate_image(prompt, out_path, size="1K", quality="medium"):
    body = {
        "model": MODEL,
        "type": "image",
        "operation": "generate",
        "input": {"prompt": prompt},
        "parameters": {"size": size, "quality": quality},
    }
    return run_task(body, out_path)

def edit_image(source_path, prompt, out_path, size="1K", quality="medium"):
    with open(source_path, "rb") as f:
        image = base64.b64encode(f.read()).decode()
    body = {
        "model": MODEL,
        "type": "image",
        "operation": "edit",
        "input": {"prompt": prompt, "image": {"data": image, "mime_type": "image/jpeg"}},
        "parameters": {"size": size, "quality": quality},
    }
    return run_task(body, out_path)

if __name__ == "__main__":
    task = generate_image(
        "A small glass greenhouse on a hillside at sunrise, morning fog in the valley, "
        "soft watercolor style, a wooden bench outside the door, no people, no text.",
        "greenhouse.png",
    )
    print("generate task", task)
    task = edit_image(
        "cafe-base.jpg",
        "Change the red bicycle to matte black. Keep everything else exactly the same: "
        "the table, the cup, the window frame and the daylight. Photorealistic, no text, no logos.",
        "cafe-edited.png",
    )
    print("edit task", task)

Authorization: Bearer <key> accompagne chaque appel, et l'appel de création demande en plus un Idempotency-Key, que le script remplit avec un UUID neuf. Le corps fixe type sur "image", operation sur "generate" ou "edit", le texte sous input.prompt, et la taille et la qualité sous parameters. L'API accepte aussi n, et seul 1 est valide, donc le script l'omet. Une création répond en HTTP 202 avec un id de tâche, le statut commence à queued, et la boucle attend 4 s entre deux vérifications jusqu'à sortir des deux états de travail.

Une modification ajoute le JPEG sous input.image comme objet Base64 en ligne avec son type MIME. Les corps de requête, Base64 compris, sont limités à 1 MiB, donc le script envoie un JPEG de 1024 pixels d'environ 230 KB.

Les tailles testées et ce qui est revenu

Quatre exécutions, toutes en qualité medium, le 29 octobre 2026. Trois sont revenues à la taille demandée. La modification en 1K non, lors d'une de ses deux exécutions.

  • 1K, générer — Pixels lus dans le fichier: 1024×1024; Date: 29 octobre 2026
  • 2K, générer — Pixels lus dans le fichier: 2048×2048; Date: 29 octobre 2026
  • 1536x1024, générer — Pixels lus dans le fichier: 1536×1024; Date: 29 octobre 2026
  • 1K, modifier — Pixels lus dans le fichier: 1024×682; Date: 29 octobre 2026

La serre ci-dessous est une génération en 1K avec le même corps de requête que le code plus haut.

Serre en verre style aquarelle sur une colline au lever du soleil, brouillard dans la vallée et banc en bois devant la porte.
Généré avec GPT-Image 2.5 Flare via l'API OmniaKey le 29 octobre 2026, taille 1K, qualité medium.

Deux choses ressortent de la liste. D'abord, lisez la taille dans le fichier téléchargé. La modification en 1K demandait un carré et est revenue en 1024×682, la forme du JPEG 1024×683 envoyé, et une autre exécution de cette même modification en 1K est revenue en 1024×1024. Ensuite, la liste de tailles de la documentation de l'API d'images (vérifiée le 29 octobre 2026) propose auto, 1K, 2K, 4K et 3840x2160 pour ce modèle, et précise qu'elle refuse les tailles hors liste avant toute facturation ; notre appel en 1536x1024 du 29 octobre 2026 n'a pas été refusé et a renvoyé 1536×1024. Vérifiez le fichier réel avant de construire une mise en page sur une seule taille.

Une modification garde la scène et change une chose

Une modification répond à deux questions : ce qui change, et ce qui reste. Nous avons demandé un seul changement et nommé ce qui devait survivre.

Prompt : "Change the red bicycle to matte black. Keep everything else exactly the same: the table, the cup, the window frame and the daylight. Photorealistic, no text, no logos."

À gauche : une vitrine de café avec un vélo rouge devant. À droite : la même vitrine après la modification, le vélo est désormais sombre.
À gauche : la photo source envoyée. À droite : la sortie d'une modification le 29 octobre 2026, taille 1K, qualité medium. Seul le vélo devait changer ; la table, la tasse et la plante sont toujours en place.

Le vélo est revenu sombre, et la table, la tasse, la plante et le cadre de la fenêtre étaient toujours dans l'image. La source était un JPEG de 1024×683, la sortie mesurait 1024×682, et l'exécution a duré 38.0 s. Écrivez la liste de ce qui reste à chaque fois. Pour la structure des prompts en général, voyez notre guide des prompts GPT Image 2.

Erreurs et limites

Deux en-têtes font le travail avant qu'un seul pixel existe : le jeton bearer et un Idempotency-Key unique. Si les deux sont bons, le reste de l'appel se réessaie simplement.

Ce que vous envoyezCe qui revient
Création sans clé400 missing_idempotency_key
Même clé, même corps, deux fois200 avec la tâche existante, rien de facturé en plus
Même clé, corps modifié409 idempotency_key_reused

La clé peut faire jusqu'à 255 caractères, d'après la documentation vérifiée le 29 octobre 2026. La réutiliser avec le même corps est le réessai sûr : vous récupérez la tâche existante et rien de nouveau n'est facturé. Gardez le corps sous 1 MiB, Base64 compris, donc réduisez ou compressez la source avant l'envoi.

Quand une tâche réussit, assets[0].url est un lien signé qui dure environ une heure, d'après la documentation : téléchargez tout de suite ou interrogez à nouveau la même tâche pour obtenir un lien neuf. Les enregistrements de tâche sont conservés 24 heures.

Un en-tête nous a surpris le 29 octobre 2026 : un POST envoyé avec le User-Agent par défaut d'urllib de Python a renvoyé HTTP 403 avec le corps « error code: 1010 » de Cloudflare. Le même POST avec notre propre en-tête User-Agent: omniakey-example/1 a atteint l'API, qui a répondu 400 invalid_request pour le corps vide envoyé, sans rien facturer. La documentation ne nomme qu'Authorization et Idempotency-Key, donc définissez un User-Agent dans votre client.

GPT Image 2.5 ou GPT Image 2 pour travailler avec l'API ?

Flare est l'id 2.5 que nous avons testé. GPT Image 2 utilise l'id gpt-image-2, comme l'indique sa page du modèle GPT Image 2. Si un script produit déjà ce qu'il vous faut avec cet id, il n'y a aucune raison d'en changer.

Pour une photo qui doit garder sa scène pendant qu'un objet change, Flare en medium est ce que couvrent nos exécutions du 29 octobre 2026 : trois tailles générées et la modification en 1024×682. La comparaison GPT Image 2.5 et GPT Image 2 donne les tailles et les résultats du même prompt pour les deux modèles, de quoi choisir avec les chiffres sous les yeux. Les tarifs actuels sont sur la page des prix.

Questions fréquentes

Quel id de modèle choisir, gpt-image-2.5-flare ou gpt-image-2.5-sunburst ?

Toutes les exécutions ci-dessus ont utilisé Flare, et sa modification a conservé la scène demandée. La page du modèle liste Sunburst comme second id 2.5 : commencez par Flare, puis faites passer votre modification la plus difficile par Sunburst avant de changer.

Puis-je demander une taille paysage comme 1536x1024 ?

Le 29 octobre 2026, une génération en 1536x1024 est revenue en 1536×1024. La liste de tailles de la documentation de l'API d'images ne contient pas cette valeur pour ce modèle, donc lisez le fichier et vérifiez la documentation avant de vous y fier en production.

Pourquoi ma modification revient-elle dans une autre taille que celle demandée ?

La même modification en 1K est revenue en 1024×682 lors d'une exécution et en 1024×1024 lors d'une autre : considérez la taille demandée comme une demande, pas comme une promesse. Ouvrez le PNG et lisez sa largeur et sa hauteur avant de le placer.

Faut-il un en-tête User-Agent ?

Le 29 octobre 2026, une requête avec le User-Agent par défaut de Python a reçu HTTP 403 avec l'erreur 1010 de Cloudflare. La même requête avec notre propre en-tête User-Agent a atteint l'API, donc envoyez-en un.

Combien de temps durent les liens des images ?

La documentation indique que le lien signé dure environ une heure. Interrogez de nouveau la tâche pour obtenir un lien frais, et téléchargez le fichier dès que la tâche réussit.

Modèles cités dans cet article

GPT Image 2.5API d'imagesPythonretouche d'imagesAPI

Articles similaires

Articles récents