HiAPI
Blog

Tutoriel

Comment utiliser grok-imagine-quality/image-to-image via l'API hiapi : curl, Python et requêtes prêtes à l'emploi

Jul 11, 2026
Comment utiliser grok-imagine-quality/image-to-image via l'API hiapi : curl, Python et requêtes prêtes à l'emploi

Ce guide vous montre comment transformer une image existante avec grok-imagine-quality/image-to-image (le niveau de fidélité le plus élevé de la série Grok Imagine) via l'API de tâches unifiée de hiapi. Vous soumettez une image source et un prompt textuel, vous interrogez le résultat par polling, puis vous téléchargez l'image générée. Chaque structure de requête et de réponse ci-dessous a été vérifiée sur l'API en production.

Ce dont vous avez besoin

  • Une clé API hiapi — créez-en une dans le tableau de bord.
  • Une à trois URL d'images accessibles publiquement comme sources. La plateforme récupère et normalise vos médias d'entrée côté serveur, donc les chemins de fichiers locaux et les charges base64 ne fonctionnent pas — hébergez d'abord vos images à un emplacement accessible par l'API.

C'est tout. Aucun SDK n'est nécessaire ; l'API de tâches est du simple HTTPS + JSON.

Schéma de requête

grok-imagine-quality/image-to-image s'exécute sur le point de terminaison de tâches asynchrones : vous créez une tâche avec POST /v1/tasks, puis vous interrogez GET /v1/tasks/<taskId> (ou enregistrez un callback) jusqu'à ce qu'elle soit terminée.

Le schéma d'entrée est strict — les champs inconnus sont rejetés avec 400 :

Champ Type Requis Description
prompt string ✅ Ce qu'il faut faire avec l'image source
image_urls string[] ✅ 1–3 URL publiques d'images source/de référence
aspect_ratio string – L'une des valeurs suivantes : auto, 2:1, 20:9, 19.5:9, 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16, 9:19.5, 9:20, 1:2
resolution string – 1k ou 2k — en minuscules (1K renvoie une erreur 400)
output_format string – jpeg, png ou webp

Notez ce qui n'existe pas : pas de size, pas de n, pas de seed, pas de réglages strength ou consistency. La fidélité de la sortie par rapport à l'image source est contrôlée par votre prompt et les images de référence que vous fournissez — voir la FAQ ci-dessous.

Exemple minimal fonctionnel (curl)

Créer la tâche :

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-quality/image-to-image",
    "input": {
      "prompt": "Turn this product photo into a clean studio shot on a light gray background with soft shadows",
      "image_urls": ["https://your-cdn.example.com/source.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2k",
      "output_format": "png"
    }
  }'

Une création réussie renvoie l'ID de tâche :

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx"
  }
}

Interrogez jusqu'à ce que la tâche atteigne un état terminal :

curl https://api.hiapi.ai/v1/tasks/task_xxxxxxxxxxxx \
  -H "Authorization: Bearer sk-<your-key>"

Pendant l'exécution, data.status indique en cours ; une fois terminée, il devient success et l'image se trouve dans data.output :

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx",
    "status": "success",
    "output": [
      {
        "url": "https://.../result.png?...&expireAt=...",
        "expireAt": 1760000000
      }
    ]
  }
}

⚠️ Les URL de sortie sont temporaires (notez expireAt). Téléchargez les octets immédiatement après la réussite de la tâche et stockez-les dans votre propre stockage — ne faites pas de hotlinking vers l'URL du résultat.

Si la tâche échoue, data.status vaut fail et data.error contient code et message.

Python : créer, interroger, télécharger

Un script complet utilisant uniquement requests :

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def create_task(prompt: str, image_urls: list[str]) -> str:
    payload = {
        "model": "grok-imagine-quality/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # 1-3 public URLs
            "aspect_ratio": "1:1",
            "resolution": "2k",         # lowercase: "1k" or "2k"
            "output_format": "png",
        },
    }
    r = requests.post(API_BASE, headers=HEADERS, json=payload, timeout=60)
    data = r.json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id

def wait_task(task_id: str, timeout_s: int = 600, poll_interval: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(poll_interval)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        prompt="Turn this product photo into a clean studio shot on a light gray background",
        image_urls=["https://your-cdn.example.com/source.jpg"],
    )
    print("task:", task_id)

    task = wait_task(task_id)
    url = task["output"][0]["url"]

    # The output URL expires -- download immediately and persist yourself
    img = requests.get(url, timeout=120).content
    with open("result.png", "wb") as f:
        f.write(img)
    print(f"saved result.png ({len(img)} bytes)")

Considérations de production

Utiliser des callbacks au lieu du polling

Pour tout scénario au-delà d'un script ponctuel, enregistrez un callback et évitez la boucle de polling. Ajoutez un objet callback de premier niveau (au même niveau que model et input) :

{
  "model": "grok-imagine-quality/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

when ne prend en charge que "final" — vous recevez exactement un POST lorsque la tâche atteint un état terminal (success ou fail). Règle empirique :

  • Le polling convient aux CLI, aux notebooks et aux traitements par lots où le processus reste déjà actif. Interrogez toutes les 3 à 5 secondes ; ne martelez pas à des intervalles inférieurs à la seconde.
  • Les callbacks sont préférables pour un backend web : aucune connexion en attente, aucun thread de travail occupé pendant la génération. Récupérez à nouveau GET /v1/tasks/<taskId> côté serveur pour valider la charge utile, plutôt que de faire aveuglément confiance au corps du webhook.

Idempotence

La création de tâche n'est pas idempotente en elle-même — si votre processus plante après le POST /v1/tasks mais avant la persistance du taskId, une nouvelle tentative crée (et facture) une seconde tâche. Avant de commencer à attendre, persistez le taskId dans votre propre stockage sous votre ID de tâche interne, afin qu'au redémarrage vous repreniez en interrogeant le taskId stocké plutôt que de recréer la tâche.

Gestion des erreurs

Les erreurs que vous rencontrerez réellement :

  • 401 permission_denied — clé API invalide ou sans accès à ce modèle. Le corps de la réponse contient un request_id que vous pouvez transmettre au support :

    {
      "error": {
        "code": "permission_denied",
        "message": "This API key cannot use the selected model. ...",
        "request_id": "2026...",
        "type": "hiapi_error"
      }
    }
    
  • 400 INVALID_REQUEST — violation du schéma, avec un message précis. Exemples réels pour ce modèle :

    • prompt: missing required field "prompt" — vous avez oublié un champ requis.
    • image_urls: maxItems: got 12, want 3 — trop d'images de référence (3 maximum).
    • resolution: value must be one of '1k', '2k' — vous avez envoyé 1K/4K.
    • additional properties 'seed' not allowed — vous avez transmis un champ que ce modèle n'accepte pas.
  • État terminal fail — la tâche a été acceptée mais la génération a échoué (par exemple, l'URL source ne peut pas être récupérée). Vérifiez data.error.message, corrigez l'entrée, puis créez une nouvelle tâche.

Utilisez des nouvelles tentatives avec backoff pour les 5xx et les erreurs réseau ; ne réessayez pas les 400 — elles échoueront de la même manière tant que la charge utile n'est pas corrigée.

Choisir le niveau de qualité (et qu'en est-il de la « cohérence » ?)

Sur hiapi, la série Grok Imagine est divisée en identifiants de modèles distincts par niveau et par modalité. Pour l'image vers image, vous pouvez choisir :

Le niveau est l'identifiant du modèle — il n'y a pas de paramètre quality dans input (l'envoyer renvoie 400 additional properties 'quality' not allowed). La tarification par image des deux niveaux figure sur la page de tarification.

Lectures associées

FAQ

Y a-t-il un paramètre de cohérence ou de force ? Non. Le schéma d'entrée n'accepte que prompt, image_urls, aspect_ratio, resolution et output_format ; tout autre contenu est rejeté avec 400. Pour contrôler la fidélité de la sortie par rapport à l'image source, précisez explicitement dans votre prompt ce qui doit être conservé (« garde le produit et l'étiquette identiques, change seulement l'arrière-plan ») et fournissez jusqu'à 3 images de référence via image_urls.

Puis-je téléverser un fichier local ou envoyer du base64 ? Pas directement — image_urls accepte des URL et la plateforme les récupère côté serveur. Téléversez vos fichiers vers n'importe quel stockage accessible publiquement (S3, R2, CDN) et transmettez cette URL.

Combien d'images source puis-je transmettre ? De 1 à 3. Un tableau vide échoue avec minItems: got 0, want 1 ; plus de 3 échoue avec maxItems.

Quelles résolutions et quels ratios d'aspect sont pris en charge ? resolution vaut 1k ou 2k (minuscules uniquement). aspect_ratio prend en charge 14 valeurs allant de 2:1 à 1:2, dont auto, 16:9, 1:1, 9:16 ainsi que 9:19.5/9:20 adaptés au mobile.

Combien de temps les URL de sortie restent-elles valides ? Chaque sortie est accompagnée d'un horodatage expireAt. Traitez les résultats comme éphémères : téléchargez les octets immédiatement après la réussite de la tâche et stockez-les vous-même.

Comment générer plusieurs variantes ? Il n'y a pas de paramètre n — créez une tâche par variante. Les tâches s'exécutent indépendamment, vous pouvez donc en soumettre plusieurs en parallèle.

Que signifie 401 permission_denied si ma clé est correcte ? La clé existe mais ne peut pas utiliser ce modèle (offre ou périmètre de permissions). Vérifiez les permissions de modèle de la clé dans le tableau de bord, ou contactez le support en indiquant le request_id du corps de la réponse d'erreur.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API