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"
}'
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())
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));
{
"code": 202,
"request_id": "2026081111342261665927mpb4IPDb",
"data": {
"id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
"object": "generation.task",
"type": "image",
"status": "pending",
"progress": 0,
"poll_url": "/v1/tasks/task_01KZQE5CM0Y3KZ6M1N1BK619MX"
}
}
{
"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"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed. Please check your API key",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient balance. Please top up and try again",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "Too many requests. Please try again later",
"type": "rate_limit_error"
}
}
Grok Imagine 2.0 Ext
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
POST
/
v1
/
images
/
generations
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"
}'
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())
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));
{
"code": 202,
"request_id": "2026081111342261665927mpb4IPDb",
"data": {
"id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
"object": "generation.task",
"type": "image",
"status": "pending",
"progress": 0,
"poll_url": "/v1/tasks/task_01KZQE5CM0Y3KZ6M1N1BK619MX"
}
}
{
"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"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed. Please check your API key",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient balance. Please top up and try again",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "Too many requests. Please try again later",
"type": "rate_limit_error"
}
}
Texte vers image · tâches asynchrones. Envoyez
Nom de modèle fixe :
POST /v1/images/generations, puis interrogez Obtenir le statut de la tâche.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.Pour les calques d’objets et l’édition de zones sélectionnées, consultez Calques et édition de zones.
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.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"
}'
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())
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));
{
"code": 202,
"request_id": "2026081111342261665927mpb4IPDb",
"data": {
"id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
"object": "generation.task",
"type": "image",
"status": "pending",
"progress": 0,
"poll_url": "/v1/tasks/task_01KZQE5CM0Y3KZ6M1N1BK619MX"
}
}
{
"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"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed. Please check your API key",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient balance. Please top up and try again",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "Too many requests. Please try again later",
"type": "rate_limit_error"
}
}
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
string
requis
Jeton Bearer. Obtenez une clé sur la page des clés API.
Authorization: Bearer YOUR_API_KEY
| 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
string
requis
Valeur fixe :
grok-imagine-2.0-extboolean
défaut:"false"
Indique s’il faut modérer le contenu avant d’envoyer la tâche d’image.
true: vérifier les prompts et les images d’entrée avecomni-moderation-latestfalseou omis : ne pas envoyer de requête de modération, sans coût ni latence de modération supplémentaires (par défaut)
string
requis
Prompt. Ne doit pas être vide après trim. Trimmez avant l’envoi.
integer
défaut:"1"
Nombre d’images :
1–12. Un 0 explicite provoque une erreur. Omettre pour 1.string
Ratio d’aspect. Préférez les chaînes de ratio (l’UI ne devrait afficher que les ratios) :
Alias pixel :
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 |
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).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.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"
1K / 2K / 4K ; le cadrage est contrôlé par size.N’envoyez pas de champ public
quality — vous obtiendrez 400 invalid_quality. Utilisez resolution.string
défaut:"url"
Seul
url est autorisé. Peut être omis. b64_json / base64 → 400 invalid_response_format.string
URL de base HTTPS publique facultative. En statut terminal, la plateforme envoie un POST à
{webhook}/callback. Côté serveur uniquement — voir Webhook.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 |
Exemples de requête
Minimal
{
"model": "grok-imagine-2.0-ext",
"prompt": "A red apple on a white ceramic plate, clean studio product photo"
}
Recommandé
{
"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érezX-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.idpour l’interrogationrequest_idpour le débogage de la passerelle- la
Idempotency-Keypour 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 |
Interroger les tâches
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.
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 |
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
{
"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
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
- Utilisez
url[]pour l’affichage ; sin>1, parcourez toutes les entrées - Associez par index uniquement si
image_ids.length === url.length - L’absence de
image_idspermet toujours l’affichage - 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_costest 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)
{
"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_secretest défini, la signature esthex(HMAC-SHA256(secret, raw_body))sur les octets bruts - Le corps du callback correspond au
datade 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 |
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 |