> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Grok Imagine 2.0 Ext génération d’images

>  - Texte vers image asynchrone ; interroger le résultat avec task_id
- 1–12 images par requête ; facturation par image livrée avec succès ($0.08 chacune)
- Sortie URL uniquement ; pas d’image-vers-image / streaming
- Les URL d’images expirent après 72 heures 

<Info>
  **Texte vers image · tâches asynchrones.** Envoyez `POST /v1/images/generations`, puis interrogez [Obtenir le statut de la tâche](/fr/api-reference/tasks/status).\
  Nom de modèle fixe : `grok-imagine-2.0-ext`. **Non pris en charge** : images de référence, `stream`, ou valeurs de `response_format` autres que `url`.
</Info>

<Warning>
  N’intégrez pas les clés API dans les bundles navigateur (`VITE_*` / `NEXT_PUBLIC_*`, LocalStorage, etc.). Préférez appeler votre propre BFF depuis le navigateur ; conservez la clé APIMart côté serveur.
</Warning>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/v1/images/generations \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Idempotency-Key: 8eacb46d-ef4e-4f4e-82de-830bd8bc67e2' \
    --header 'X-APIMart-Response-Version: 2026-07-27' \
    --data '{
      "model": "grok-imagine-2.0-ext",
      "prompt": "A red apple on a white ceramic plate, clean studio product photo",
      "n": 1,
      "size": "1:1",
      "resolution": "quality",
      "response_format": "url"
    }'
  ```

  ```python Python theme={null}
  import requests
  import uuid

  url = "https://api.apimart.ai/v1/images/generations"

  payload = {
      "model": "grok-imagine-2.0-ext",
      "prompt": "A red apple on a white ceramic plate, clean studio product photo",
      "n": 1,
      "size": "1:1",
      "resolution": "quality",
      "response_format": "url",
  }

  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json",
      "Accept": "application/json",
      "Idempotency-Key": str(uuid.uuid4()),
      "X-APIMart-Response-Version": "2026-07-27",
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.status_code, response.json())
  ```

  ```javascript JavaScript theme={null}
  const url = "https://api.apimart.ai/v1/images/generations";

  const payload = {
    model: "grok-imagine-2.0-ext",
    prompt: "A red apple on a white ceramic plate, clean studio product photo",
    n: 1,
    size: "1:1",
    resolution: "quality",
    response_format: "url",
  };

  const headers = {
    Authorization: "Bearer <token>",
    "Content-Type": "application/json",
    Accept: "application/json",
    "Idempotency-Key": crypto.randomUUID(),
    "X-APIMart-Response-Version": "2026-07-27",
  };

  fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(payload),
  })
    .then(async (response) => {
      console.log(response.status, await response.json());
    })
    .catch((error) => console.error("Error:", error));
  ```
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "code": 202,
    "request_id": "2026081111342261665927mpb4IPDb",
    "data": {
      "id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
      "object": "generation.task",
      "type": "image",
      "status": "pending",
      "progress": 0,
      "poll_url": "/v1/tasks/task_01KZQE5CM0Y3KZ6M1N1BK619MX"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "request_id": "20260811...",
    "error": {
      "message": "`response_format` for grok-imagine-2.0-ext only supports `url` (got: b64_json)",
      "type": "invalid_response_format",
      "param": "",
      "code": "invalid_response_format"
    }
  }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "code": 401,
      "message": "Authentication failed. Please check your API key",
      "type": "authentication_error"
    }
  }
  ```

  ```json 402 theme={null}
  {
    "error": {
      "code": 402,
      "message": "Insufficient balance. Please top up and try again",
      "type": "payment_required"
    }
  }
  ```

  ```json 429 theme={null}
  {
    "error": {
      "code": 429,
      "message": "Too many requests. Please try again later",
      "type": "rate_limit_error"
    }
  }
  ```
</ResponseExample>

## Capacités et limites

| Dimension          | Contrat                                                                           |
| ------------------ | --------------------------------------------------------------------------------- |
| Modèle             | Fixe `grok-imagine-2.0-ext`                                                       |
| Capacité           | **Texte vers image uniquement**                                                   |
| Mode               | Tâche asynchrone                                                                  |
| Nombre `n`         | `1`–`12`, défaut `1`                                                              |
| `size`             | 7 ratios d’aspect + 5 alias pixel (ci-dessous)                                    |
| Sortie             | `response_format=url` uniquement (également la valeur par défaut)                 |
| Qualité            | Champ public `resolution` ; valeur vérifiée `quality`                             |
| Non pris en charge | Image vers image, `stream=true`, `quality` public, `style`, `b64_json` / `base64` |
| Facturation        | Prix unitaire fixe ; facturation des images **livrées avec succès**               |

## Authentification et en-têtes recommandés

<ParamField header="Authorization" type="string" required>
  Jeton Bearer. Obtenez une clé sur la [page des clés API](https://apimart.ai/keys).

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

| En-tête                      | Remarques                                                                                                                                                          |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Content-Type`               | `application/json` (soumission)                                                                                                                                    |
| `Accept`                     | `application/json`                                                                                                                                                 |
| `Idempotency-Key`            | Fortement recommandé. Nouvel UUID par génération confirmée par l’utilisateur ; les nouvelles tentatives réseau **doivent réutiliser** la même clé et le même corps |
| `X-APIMart-Response-Version` | Préférez `2026-07-27` pour une structure de soumission stable (`data.id`)                                                                                          |

## Paramètres de la requête

<ParamField body="model" type="string" required>
  Valeur fixe : `grok-imagine-2.0-ext`
</ParamField>

<ParamField body="prompt" type="string" required>
  Prompt. Ne doit pas être vide après trim. Trimmez avant l’envoi.
</ParamField>

<ParamField body="n" type="integer" default="1">
  Nombre d’images : `1`–`12`. Un `0` explicite provoque une erreur. Omettre pour `1`.
</ParamField>

<ParamField body="size" type="string">
  Ratio d’aspect. **Préférez les chaînes de ratio** (l’UI ne devrait afficher que les ratios) :

  | `size` | Orientation | Usage typique                  |
  | ------ | ----------- | ------------------------------ |
  | `1:1`  | Carré       | Produit, avatar                |
  | `2:3`  | Portrait    | Affiche, plein corps           |
  | `3:2`  | Paysage     | Photo, scène large             |
  | `3:4`  | Portrait    | E-commerce, personnes          |
  | `4:3`  | Paysage     | Visuels d’affichage            |
  | `9:16` | Vertical    | Story / couverture short-video |
  | `16:9` | Large       | Bannière, couverture vidéo     |

  Alias pixel : `1024x1024` (1:1), `1024x1792` (2:3), `1792x1024` (3:2), `720x1280` (9:16), `1280x720` (16:9).

  Les valeurs hors liste blanche renvoient `400 invalid_size` (ex. `1:2`, `2:1`, `4:5`, `auto`).

  <Note>
    Les pixels réels pour un ratio donné peuvent différer du tableau d’alias (ex. `1:1` peut renvoyer 1408×1408). Faites confiance à l’image renvoyée ; ne réécrivez pas `size` à partir des pixels mesurés.
  </Note>
</ParamField>

<ParamField body="resolution" type="string">
  Champ de mode qualité. Valeur vérifiée : `quality`.

  * Omettre (le modèle est en mode qualité par défaut), ou
  * Envoyer explicitement `resolution: "quality"`

  **Ce n’est pas** un palier pixel `1K` / `2K` / `4K` ; le cadrage est contrôlé par `size`.

  <Warning>
    N’envoyez pas de champ public `quality` — vous obtiendrez `400 invalid_quality`. Utilisez `resolution`.
  </Warning>
</ParamField>

<ParamField body="response_format" type="string" default="url">
  Seul `url` est autorisé. Peut être omis. `b64_json` / `base64` → `400 invalid_response_format`.
</ParamField>

<ParamField body="webhook" type="string">
  **URL de base** HTTPS publique facultative. En statut terminal, la plateforme envoie un POST à `{webhook}/callback`. Côté serveur uniquement — voir [Webhook](#webhook-facultatif).
</ParamField>

### Paramètres non pris en charge

| Paramètre                                  | Comportement                                  |
| ------------------------------------------ | --------------------------------------------- |
| `quality`                                  | `400 invalid_quality` → utiliser `resolution` |
| `style`                                    | `400 invalid_style`                           |
| `image_urls` / `image_with_roles`          | `400 invalid_image_input`                     |
| `stream: true`                             | `400 invalid_stream`                          |
| `response_format: "b64_json"` / `"base64"` | `400 invalid_response_format`                 |

Construisez les requêtes avec une liste blanche ; ne transmettez pas un objet de formulaire générique issu d’autres modèles d’image.

## Exemples de requête

### Minimal

```json theme={null}
{
  "model": "grok-imagine-2.0-ext",
  "prompt": "A red apple on a white ceramic plate, clean studio product photo"
}
```

### Recommandé

```json theme={null}
{
  "model": "grok-imagine-2.0-ext",
  "prompt": "A red apple on a white ceramic plate, clean studio product photo",
  "n": 1,
  "size": "1:1",
  "resolution": "quality",
  "response_format": "url"
}
```

## Réponse de soumission

Préférez `X-APIMart-Response-Version: 2026-07-27`. Le succès est HTTP **`202`** ; l’identifiant de tâche est **`data.id`** (ne vous fiez pas au format hérité `data[0].task_id`).

Conservez :

* `data.id` pour l’interrogation
* `request_id` pour le débogage de la passerelle
* la `Idempotency-Key` pour des nouvelles tentatives sûres lorsque le résultat est inconnu
* les paramètres de requête d’origine pour l’UI / le support

## Idempotence et nouvelles tentatives sûres

La génération d’images est facturable — **fortement recommandé** : `Idempotency-Key` (1–191 caractères ASCII imprimables ; UUID le plus simple ; conservation \~24 heures).

| Scénario                           | Comportement                                  | Action                                                    |
| ---------------------------------- | --------------------------------------------- | --------------------------------------------------------- |
| Même clé + même corps déjà terminé | Rejeu ; en-tête `Idempotency-Replayed: true`  | Utiliser le même identifiant de tâche                     |
| Même clé encore en cours           | `409 idempotency_in_progress` + `Retry-After` | Attendre, réessayer avec **la même clé et le même corps** |
| Même clé, corps différent          | `409 idempotency_key_reused`                  | Un nouveau job logique nécessite une nouvelle clé         |
| Résultat indéterminé               | `409 idempotency_result_indeterminate`        | Ne pas créer de nouvelle clé ; enquêter avec l’ancienne   |

En cas de timeout réseau POST sans savoir si le serveur a accepté le job, **ne créez pas immédiatement une nouvelle clé** — réessayez avec la même clé / corps / version de réponse.

## Interroger les tâches

```http theme={null}
GET /v1/tasks/{task_id}?language=en
Authorization: Bearer YOUR_API_KEY
Accept: application/json
```

`language` facultatif : `zh` / `en` / `ko` / `ja` (localisation des messages d’échec uniquement). Voir [Obtenir le statut de la tâche](/fr/api-reference/tasks/status).

### Statuts

| `status`                 | Terminal | Traitement                                                                                        |
| ------------------------ | :------: | ------------------------------------------------------------------------------------------------- |
| `pending` / `processing` |    Non   | Continuer d’interroger (`result` peut être absent — ce n’est pas un échec)                        |
| `completed`              |    Oui   | Parser `result.images`                                                                            |
| `failed`                 |    Oui   | Afficher `error.message` ; `cost` vaut `0` (pré-débit remboursé)                                  |
| `unknown`                |    Non   | Courtes nouvelles tentatives ; si cela persiste, contacter le support avec l’identifiant de tâche |

Interrogez environ toutes les **2 secondes** ; plafond près de **10 minutes** ou **120** tentatives. Respectez `Retry-After` sur `429`. Les tâches sont conservées \~3 jours par défaut — gardez l’identifiant de tâche si le client expire.

### Exemple de tâche terminée

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
    "status": "completed",
    "progress": 100,
    "created": 1786419262,
    "completed": 1786419275,
    "actual_time": 13,
    "estimated_time": 100,
    "cost": 0.08,
    "credits_cost": 0.8,
    "result": {
      "images": [
        {
          "expires_at": 1786505675,
          "url": [
            "https://example.com/image/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.jpg"
          ],
          "image_ids": [
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          ]
        }
      ]
    }
  }
}
```

### Parser `url` et `image_ids`

```text theme={null}
result.images[]
  ├─ url[]          ← champ d’affichage/téléchargement faisant autorité (tableau)
  ├─ image_ids[]    ← ID opaques optionnels
  └─ expires_at     ← secondes Unix ; multiplier par 1000 pour JS Date
```

1. Utilisez `url[]` pour l’affichage ; si `n>1`, parcourez toutes les entrées
2. Associez par index uniquement si `image_ids.length === url.length`
3. L’absence de `image_ids` permet toujours l’affichage
4. Les liens durent **72 heures** — téléchargez rapidement ; faites aussi confiance à `expires_at`

## Facturation

Prix de base **\$0.08 par image** (livraisons réussies) :

| `n` | Base estimée |
| --: | -----------: |
|   1 |       \$0.08 |
|   4 |       \$0.32 |
|   8 |       \$0.64 |
|  12 |       \$0.96 |

* L’UI avant envoi doit indiquer une « estimation » ; le montant USD final est **`data.cost`**
* **`data.credits_cost`** est la vue crédits (actuellement \~ USD × 10)
* Pré-débit selon le nombre demandé ; règlement sur le nombre réussi (remboursements partiels en cas d’échec partiel)
* Échec total : `cost=0`, pré-débit remboursé
* Ne construisez pas de clés de prix à partir de `resolution` ; ce modèle a un tarif forfaitaire par image

## Webhook (facultatif)

```json theme={null}
{
  "webhook": "https://your-service.example.com/apimart"
}
```

* Fournissez une **URL de base** ; la plateforme appelle `{base}/callback`
* Doit être publique et passer les contrôles SSRF
* Si `webhook_secret` est défini, la signature est `hex(HMAC-SHA256(secret, raw_body))` sur les octets bruts
* Le corps du callback correspond au `data` de l’interrogation de tâche (sans enveloppe `{code,data}` supplémentaire)
* Conservez tout de même une interrogation basse fréquence en secours

## Erreurs courantes

| HTTP | `error.code`              | Cause                       | Action                                                         |
| ---: | ------------------------- | --------------------------- | -------------------------------------------------------------- |
|  400 | `invalid_request`         | Prompt vide / JSON invalide | Valider l’entrée                                               |
|  400 | `invalid_n`               | `n` hors de 1–12            | Limiter le nombre                                              |
|  400 | `invalid_size`            | Size hors liste blanche     | Options de sélection fixes                                     |
|  400 | `invalid_response_format` | Pas `url`                   | Corriger ou omettre                                            |
|  400 | `invalid_quality`         | `quality` public envoyé     | Utiliser `resolution`                                          |
|  400 | `invalid_style`           | `style` envoyé              | Supprimer                                                      |
|  400 | `invalid_image_input`     | Images de référence         | Changer de modèle                                              |
|  400 | `invalid_stream`          | `stream=true`               | Supprimer                                                      |
|  400 | `invalid_idempotency_key` | Clé invalide                | Utiliser un UUID                                               |
|  401 | Échec d’auth              | Mauvaise clé                | Corriger les identifiants serveur                              |
|  402 | Paiement requis           | Solde insuffisant           | Recharger                                                      |
|  409 | `idempotency_*`           | Conflit d’idempotence       | Voir le tableau ci-dessus                                      |
|  429 | Limite de débit           | Trop rapide                 | Respecter `Retry-After`                                        |
|  5xx | Erreur serveur            | —                           | Conserver l’Idempotency-Key ; ne pas faire tourner aveuglément |

Préférez `error.message` pour l’UI. Ne pas exposer les détails internes d’authentification aux utilisateurs finaux.

## Différences avec 1.5 (résumé)

| Élément          | Grok Imagine 1.5                 | 2.0 Ext                                            |
| ---------------- | -------------------------------- | -------------------------------------------------- |
| Modèle           | `grok-imagine-1.5-apimart`, etc. | `grok-imagine-2.0-ext`                             |
| Image vers image | Pris en charge (voir docs 1.5)   | **Non pris en charge**                             |
| Nombre           | Voir docs 1.5                    | **1–12**                                           |
| Champ qualité    | Voir docs 1.5                    | `resolution` (`quality`) ; jamais `quality` public |
| Sortie           | Voir docs 1.5                    | **URL uniquement**                                 |
| TTL URL          | Voir docs 1.5 (souvent 24 h)     | **72 heures**                                      |
| Prix unitaire    | Voir docs 1.5                    | **\$0.08 / image**                                 |
