Qwen-ImageRéférence API
Générez et retouchez des images avec les modèles Qwen-Image depuis votre code : un démarrage rapide en trois étapes, chaque champ, les crédits par image, les webhooks et l’idempotence.
L’accès à l’API développeur se fait sur demande.
L’API d’image est en bêta et ses champs peuvent changer. Le studio n’est pas concerné.
Démarrage rapideen trois appels
Définissez une clé, envoyez la tâche avec un plafond de prix, puis lisez le résultat.
- 01
Définissez votre clé
L’accès à l’API développeur se fait sur demande : demandez-le dans le studio, sous Clés API. La clé n’est affichée qu’une fois : gardez-la dans une variable d’environnement.
export API_KEY="sk_test_…" - 02
Envoyez la tâche
Envoyez l’image en POST avec un Idempotency-Key et un plafond max_credits. Les modèles de retouche prennent aussi image_url. Vous recevez un 202 et une tâche en file, et les crédits sont réservés.
curl https://api.pershot.app/v1/images/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen-image-2512", "prompt": "A ceramic mug on a walnut table, soft window light, product photo", "size": "1K", "aspect_ratio": "1:1", "max_credits": 2 }'{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "image", "status": "queued", "money_status": "reserved", "queue_position": 2, "requested_model": "qwen-image-2512", "credits_quoted": 2, "credits_charged": null } - 03
Lisez le résultat
Faites un GET sur la tâche jusqu’à ce que son statut soit succeeded. outputs[].url est signé et expire au bout de 24 heures : téléchargez ce que vous gardez.
curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \ -H "Authorization: Bearer $API_KEY"
Paramètreset limites
Lus dans le document OpenAPI, généré à partir des mêmes schémas que ceux utilisés par l’API pour valider. Les champs inconnus sont refusés.
| Champ | Type | Valeurs admises | Remarques |
|---|---|---|---|
modelObligatoire | string | qwen-image-2512-lightning · qwen-image-2512 · qwen-image-edit-2511-lightning · qwen-image-edit-2511 | L’identifiant du modèle. |
promptObligatoire | string | 2–2 000 caractères | Ce qu’il faut générer : le sujet, la caméra et la lumière. |
sizePar défaut "1K" | string | 1K · 2K | 1K pour les brouillons et les premières images, 2K pour le détail. |
aspect_ratioPar défaut "1:1" | string | 16:9 · 9:16 · 1:1 | Forme du cadre. |
image_urlFacultatif | string | URL https | Première image pour la vidéo ; image source pour les modèles de retouche. Une URL https publique ou une URL d’import. |
seedFacultatif | integer | 0–2 147 483 647 | Reproduire un résultat avec les mêmes entrées. |
quote_idFacultatif | string | qt_… | Lancer au prix d’un devis obtenu avec POST /v1/quotes, valable 10 minutes. |
max_creditsFacultatif | number | > 0 | Le maximum que cette tâche peut coûter. Au-delà, la tâche est refusée, jamais facturée. |
webhook_urlFacultatif | string | URL https | Une URL https qui reçoit les événements de la tâche. |
end_user_idFacultatif | string | 1–128 caractères | Pour les comptes développeur approuvés (accès sur demande) : votre propre identifiant utilisateur pour cette requête, affiché dans l’utilisation. |
project_idFacultatif | string | prj_… | |
shot_idFacultatif | string | sht_… | |
routing_preferenceFacultatif | string | stability · speed |
Envoyez exactement l’un des deux : quote_id ou max_credits. Cet endpoint refuse model "auto" : pour la vidéo, appelez d’abord POST /v1/auto/plan, puis envoyez le modèle choisi avec max_credits.
- Modèles
qwen-image-2512-lightningGénération · Qwen-Image-2512 · Lightning 4-stepqwen-image-edit-2511-lightningRetouche · Qwen-Image-Edit-2511 · Lightningqwen-image-2512Génération · Qwen-Image-2512qwen-image-edit-2511Retouche · Qwen-Image-Edit-2511- Débit et simultanéité
- 60 requêtes par minute et par clé, et 3 tâches simultanées par compte par défaut. Plus de clés n’augmentent pas la simultanéité.
- Pour les agents IA
- Texte brut pour les agents IA : entrées, valeurs admises, chaque prix et un exemple de requête
qwen-image-2512-lightningqwen-image-2512qwen-image-edit-2511-lightningqwen-image-edit-2511
Limites
Lues dans la même table que celle vérifiée par l’API. Chaque ligne indique qui vérifie la limite et ce qui se passe au-delà.
- AppliquéeNous la vérifions et répondons 400 avant tout devis ou toute réservation.
- FournisseurLe fournisseur la vérifie. Une tâche qu’il refuse échoue, et rien n’est facturé.
- RecommandéePersonne ne la vérifie. La respecter donne de meilleurs résultats.
| Limite | Valeur | Unité | Qui vérifie | Au-delà de la limite |
|---|---|---|---|---|
| Requête | ||||
Longueur du promptprompt | 2 à 2 000 | caractères | Appliquée | 400 invalid_request sur prompt, avant tout devis ou toute réservation. |
Taille d’imagesize | 1K, 2KPar défaut 1K | – | Appliquée | 400 invalid_request sur size. |
Format d’imageaspect_ratio | 16:9, 9:16, 1:1Par défaut 1:1 | – | Appliquée | 400 invalid_request sur aspect_ratio. |
| Images envoyées | ||||
Image sourceimage_url | Aucune | – | Appliquée | Les modèles de retouche exigent image_url et les modèles de génération le refusent : 400 invalid_request sur image_url. |
| Sortie | ||||
| Pixels de sortie | 1K16:91344×7689:16768×13441:11024×10242K16:92048×11529:161152×20481:12048×2048 | px | Appliquée | Nous demandons exactement ces tailles. |
| Côté de sortie | 256 à 2 048 | px par côté | Fournisseur | Toutes les tailles ci-dessus passent. Le fournisseur refuse les plus grandes. |
| Format de sortie | JPEG | – | Appliquée | Chaque image est un JPEG. |
| Liens | ||||
| Lien de sortie | 24 | heures | Appliquée | Ensuite, le lien répond 403. Refaites un GET sur la tâche pour obtenir un nouveau lien. Le fichier lui-même est conservé 12 mois (outputs_expire_at de la tâche donne la date), plus longtemps si le résultat est enregistré dans la Bibliothèque ou utilisé dans un projet. |
| Limite | Valeur | Unité | Qui vérifie | Au-delà de la limite |
|---|---|---|---|---|
| Requête | ||||
Longueur du promptprompt | 2 à 2 000 | caractères | Appliquée | 400 invalid_request sur prompt, avant tout devis ou toute réservation. |
Taille d’imagesize | 1K, 2KPar défaut 1K | – | Appliquée | 400 invalid_request sur size. |
Format d’imageaspect_ratio | 16:9, 9:16, 1:1Par défaut 1:1 | – | Appliquée | 400 invalid_request sur aspect_ratio. |
| Images envoyées | ||||
Image sourceimage_url | Exactement 1 | – | Appliquée | Les modèles de retouche exigent image_url et les modèles de génération le refusent : 400 invalid_request sur image_url. |
Taille d’importfile | jusqu’à 10 | Mo | Appliquée | POST /v1/uploads répond 400 invalid_request sur file. |
Formats d’importfile | JPEG, PNG, WebP | – | Appliquée | Lu dans le fichier lui-même, pas dans son nom. Tout autre format : 400 invalid_request sur file. |
| Sortie | ||||
| Pixels de sortie | 1K16:91344×7689:16768×13441:11024×10242K16:92048×11529:161152×20481:12048×2048 | px | Appliquée | Nous demandons exactement ces tailles. |
| Côté de sortie | 512 à 2 048 | px par côté | Fournisseur | Toutes les tailles ci-dessus passent. Le fournisseur refuse les plus grandes. |
| Format de sortie | JPEG | – | Appliquée | Chaque image est un JPEG. |
| Liens | ||||
| Lien d’import | 7 | jours | Appliquée | Ensuite, le lien répond 403. Importez à nouveau le fichier. |
| Lien de sortie | 24 | heures | Appliquée | Ensuite, le lien répond 403. Refaites un GET sur la tâche pour obtenir un nouveau lien. Le fichier lui-même est conservé 12 mois (outputs_expire_at de la tâche donne la date), plus longtemps si le résultat est enregistré dans la Bibliothèque ou utilisé dans un projet. |
Nous ne récupérons jamais d’images sur d’autres hôtes : pour ces liens, c’est le fournisseur qui vérifie la taille, et une tâche qu’il refuse n’est pas facturée. Les mêmes limites existent en JSON : GET /v1/models renvoie un objet limits pour chaque modèle.
Les tarifscalculés en toute transparence
Un prix par image, selon le modèle et la taille, en crédits (1 $ US = 100 crédits). La génération et la retouche ont des prix distincts.
| Modèle | 1K | 2K |
|---|---|---|
qwen-image-2512-lightningGénération | 1 cr≈ 0,01 $≈ 1 000 images pour 10 $ | 3 cr≈ 0,03 $≈ 333 images pour 10 $ |
qwen-image-edit-2511-lightningRetouche | 2 cr≈ 0,02 $≈ 500 images pour 10 $ | 4 cr≈ 0,04 $≈ 250 images pour 10 $ |
qwen-image-2512Génération | 2 cr≈ 0,02 $≈ 500 images pour 10 $ | 6 cr≈ 0,06 $≈ 166 images pour 10 $ |
qwen-image-edit-2511Retouche | 3 cr≈ 0,03 $≈ 333 images pour 10 $ | 10 cr≈ 0,10 $≈ 100 images pour 10 $ |
Webhookset idempotence
Les nouvelles tentatives ne facturent jamais deux fois, et vous n’avez pas besoin d’interroger en boucle.
- Idempotence
- Chaque POST de génération exige un Idempotency-Key (1 à 255 caractères ASCII visibles). La même clé dans les 24 heures renvoie la même tâche avec HTTP 200 : une nouvelle tentative après un délai dépassé ne crée ni ne facture jamais une seconde tâche.
- Prompts refusés
- Un prompt refusé par le contrôle préalable (422 content_rejected) ne crée rien : la même clé peut donc être réutilisée avec un nouveau prompt.
- Événements
job.queuedjob.processingjob.succeededjob.failedjob.cancelled- Signature
- X-Signature contient t, l’heure unix, et v1, un HMAC-SHA256 de t, d’un point et du corps brut, avec votre secret whsec_ comme clé. Refusez les horodatages de plus de cinq minutes et dédoublonnez sur X-Event-Id.
- Livraison
- Un 2xx en moins de 10 secondes vaut livraison. Les livraisons échouées sont retentées après 1 min, 5 min, 30 min, 2 h et 6 h. Les redirections ne sont pas suivies.
{
"id": "evt_01J9ZKB1QX",
"type": "job.succeeded",
"created_at": "2026-09-29T14:02:31Z",
"data": {
"job": {
"id": "job_01J9ZK4T8W",
"object": "job",
"kind": "image",
"status": "succeeded",
"money_status": "settled",
"requested_model": "qwen-image-2512",
"credits_charged": 2,
"outputs": [
{
"kind": "image",
"url": "https://…/job_01J9ZK4T8W.png?sig=…"
}
]
}
}
}import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received, before any JSON parsing.
export function verifyWebhook(header, rawBody, secret, toleranceSec = 300) {
let t = null;
const signatures = [];
for (const item of (header ?? "").split(",")) {
const [key, value] = item.split("=", 2);
if (key === "t") t = Number(value);
if (key === "v1") signatures.push(Buffer.from(value, "hex"));
}
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((s) => s.length === expected.length && timingSafeEqual(s, expected));
}
// verifyWebhook(req.headers["x-signature"], rawBody, process.env.WEBHOOK_SECRET)
// Answer 2xx quickly, and skip an X-Event-Id you have already handled.Les erreurset que faire
Toutes les erreurs ont la même forme : un objet error avec code, message, param et request_id. Celles que vous rencontrerez le plus souvent :
| Code | HTTP | Que faire |
|---|---|---|
invalid_request | 400 | Corrigez le champ indiqué dans param. |
unauthorized | 401 | Vérifiez la clé et l’en-tête Bearer. |
insufficient_credits | 402 | Rechargez, puis réessayez avec le même Idempotency-Key. |
forbidden_model | 403 | Ajoutez le modèle ou l’outil à la liste autorisée de la clé dans le studio, ou utilisez une autre clé. Les outils comme Améliorer ont besoin de leur propre entrée. |
quote_expired | 409 | Demandez un nouveau devis ; un devis dure 10 minutes. |
price_changed | 409 | Le prix a dépassé votre plafond. Redemandez un devis ou augmentez max_credits. |
content_rejected | 422 | Rien n’a été facturé. Modifiez le prompt ou les images. |
rate_limited | 429 | Attendez la durée de Retry-After, puis réessayez. |
upstream_unavailable | 503 | Le modèle est indisponible. Réessayez plus tard ; une tâche qui ne démarre jamais n’est pas facturée. |