Requêtes
Une requête correspond à un appel à un modèle. Elle possède un identifiant (req_…), un état, son coût en crédits API (1000 = 1 USD) et, lorsqu’elle réussit, les fichiers générés. Le même objet est renvoyé par chaque point de terminaison ci-dessous, pour tous les modèles.
Trouver un modèle
Le catalogue des 1 496 modèles est un JSON public (aucune clé requise) :
curl "https://api.doitong.com/v1/models?category=text-to-video&lab=Google&limit=20"
| Paramètre de requête | Signification |
|---|---|
q |
Les mots qui doivent tous apparaître dans le nom, l’identifiant, le fabricant ou les balises, par exemple kling 3. |
category |
Un identifiant de catégorie, par exemple text-to-video ou upscale. GET https://api.doitong.com/v1/categories répertorie les 21 catégories avec leur nombre d’éléments. |
lab |
Le fabricant du modèle, par nom ou identifiant, par exemple Google ou black-forest-labs. |
family |
Un identifiant family provenant d’une ligne précédente : chaque variante d’un même modèle (pro, fast, image-to-video, …). |
mode |
exact (le prix est calculé à partir de l’entrée), measured (à partir de la longueur ou de la taille des fichiers d’entrée), estimate (un prix estimé par exécution) ou metered (facturé selon l’utilisation réelle, jusqu’à un maximum par exécution). |
limit, cursor |
Taille de page (de 1 à 100, 50 par défaut) et next_cursor de la page précédente. |
Chaque ligne contient id, name, lab, category, family, summary, tags, output_kind, docs_url et un objet price (voir Tarification). GET https://api.doitong.com/v1/models/{model_id} ajoute le schéma JSON complet de l’entrée et de la sortie, les noms canoniques des paramètres, les règles de tarification et un exemple d’entrée. Une category ou un mode inconnu renvoie 400 invalid_parameter.
Exécuter un modèle
curl -X POST "https://api.doitong.com/v1/run/{model_id}?wait=20" \
-H "Authorization: Bearer $DOITONG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1842-cover" \
-d '{"prompt": "..."}'
- Le corps contient l’entrée du modèle, sous forme d’objet JSON. Chaque page de modèle répertorie ses paramètres.
- L’entrée est vérifiée avant toute facturation. Une entrée non valide renvoie
422 invalid_inputavec leparamfautif, et ne coûte rien. ?wait=N(jusqu’à 20 secondes) maintient l’appel jusqu’à la fin de la requête ou jusqu’à l’expiration du délai.?webhook_url=https://…envoie une requête POST signée à cette URL lorsque la requête se termine (voir Webhooks).?storage=permanentou?storage=temporarydétermine combien de temps les fichiers de sortie sont conservés ; sans ce paramètre, le réglage du compte s’applique (voir Emplacement des fichiers).
La réponse est 202 Accepted pendant le traitement de la requête, et 200 OK lorsqu’elle s’est terminée pendant l’attente (ou lorsqu’il s’agit d’une nouvelle lecture, voir ci-dessous). Les en-têtes Location et Doitong-Request-Id contiennent l’URL et l’identifiant de la requête.
États
-
queuedAcceptée et débitée, en attente d’un processus -
runningLe modèle génère le résultat -
États finaux:
succeededLe montant indiqué a été débité; outputs[] contient les URL dans notre stockagefailedRemboursement automatique; l’erreur en indique la raisoncanceledArrêtée avant l’obtention d’un résultat; remboursée
| État | Signification | Final |
|---|---|---|
queued |
Acceptée et facturée, en attente d’un processus. queue_position peut indiquer sa position dans la file. |
non |
running |
Le modèle génère le résultat. | non |
succeeded |
Terminée. outputs répertorie les fichiers. |
oui |
failed |
Le modèle ou une limite a interrompu la requête. error en indique la raison. Les crédits API sont remboursés. |
oui |
canceled |
Annulée avant de produire un résultat. Les crédits API sont remboursés. | oui |
Une requête qui dépasse sa limite de temps échoue avec le code timeout et est remboursée : 15 minutes pour les images, 60 minutes pour la vidéo, 30 minutes pour l’audio et tout le reste.
L’objet requête
{
"id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
"object": "request",
"model": "flux/schnell",
"status": "succeeded",
"created_at": "2026-10-20T12:00:00Z",
"started_at": "2026-10-20T12:00:01Z",
"completed_at": "2026-10-20T12:00:02Z",
"queue_position": null,
"cost": { "credits": 3, "usd": "0.003", "charged": 3, "refunded": 0 },
"input": { "prompt": "..." },
"output": { "images": [ { "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "width": 1024, "height": 768 } ] },
"outputs": [
{ "type": "image", "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "content_type": "image/jpeg",
"width": 1024, "height": 768, "file_size": 183920, "stored": true }
],
"error": null,
"metrics": { "inference_seconds": 1.2 },
"storage": { "mode": "permanent", "bytes": 183920, "expires_at": null, "expired": false },
"urls": {
"self": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
"cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
}
}
outputsest identique pour tous les modèles : une entrée par fichier généré avectype(image,video,audio,fileou3d), uneurldans notre stockage,content_typeet, lorsqu’ils sont connus,file_size,width,height,duration.outputest l’objet de résultat propre au modèle (ses champs sont répertoriés sur chaque page de modèle), avec les mêmes URL.storageindique comment les fichiers sont conservés :mode(permanentoutemporary),bytesstockés,expires_at(date de suppression d’un fichier temporaire,nullpour les fichiers permanents) etexpired(trueune fois les fichiers supprimés).cost.creditsest le prix de l’appel en crédits API (cost.usden USD),cost.chargedce qui a été débité du solde API, etcost.refundedce qui a été remboursé. Pour un modèlemetered,cost.creditsest le maximum retenu au début (cost.held) ; une fois l’exécution réussie,cost.settledindique le montant correspondant à l’utilisation et le reste du maximum figure danscost.refunded(voir Facturation selon l’utilisation).- Lorsqu’une requête échoue,
errorest{ "type": …, "code": …, "message": … }.
Lire une requête
curl "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t?wait=20" \
-H "Authorization: Bearer $DOITONG_API_KEY"
?wait=N(jusqu’à 20 secondes) effectue une attente longue : l’appel renvoie la réponse dès que la requête est finale, ou après N secondes avec son état actuel. Répéter cet appel est la façon la plus simple d’attendre un résultat.?logs=1ajoute les lignes du journal de progression du modèle (les 50 dernières) souslogs.
Vous pouvez uniquement lire les requêtes de votre propre compte ; tout autre identifiant renvoie 404 request_not_found.
Répertorier les requêtes
curl "https://api.doitong.com/v1/requests?limit=20&status=succeeded&model=flux/schnell" \
-H "Authorization: Bearer $DOITONG_API_KEY"
De la plus récente à la plus ancienne. limit va de 1 à 100 (20 par défaut) ; status et model servent de filtres. La réponse est { "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" } ; transmettez cursor=<next_cursor> pour obtenir la page suivante.
Annuler une requête
curl -X POST "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel" \
-H "Authorization: Bearer $DOITONG_API_KEY"
- Annulée avant le démarrage du modèle : l’état devient
canceled, les crédits API sont remboursés et vous recevez200. - Déjà en cours de génération : l’annulation est transmise et vous recevez
202avec"cancel_requested": true. Si le modèle termine malgré tout, la requête réussit normalement et est facturée. - Déjà finale :
409 not_cancelable(une requête déjàcanceledrenvoie simplement200).
Supprimer les fichiers d’une requête
curl -X DELETE "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/files" \
-H "Authorization: Bearer $DOITONG_API_KEY"
Supprime immédiatement nos copies des fichiers de sortie de la requête et met fin à leurs frais de stockage. La réponse est l’objet requête avec storage.expired: true ; ses URL restent dans l’enregistrement, mais ne fonctionnent plus. Un nouvel appel ne change rien (200). Une requête encore queued ou running n’a pas encore de fichiers : 409 request_active. Nécessite models:run.
Idempotence : réessayer sans payer deux fois
Les réseaux peuvent échouer. Pour réessayer une exécution en toute sécurité, envoyez un en-tête Idempotency-Key (toute chaîne de 255 caractères maximum, unique par opération, par exemple votre propre identifiant de commande) :
- Même clé et même corps qu’auparavant : vous recevez la requête d’origine (
200, en-têteIdempotent-Replayed: true) et rien n’est facturé à nouveau. - Même clé et même corps après une exécution ayant échoué avant d’atteindre le modèle (
upstream_errorouinternal_errorlors de la soumission,insufficient_credits,budget_exceeded,too_many_inflight) : rien n’a été produit et rien n’est facturé ; la nouvelle tentative exécute donc à nouveau le modèle au lieu de renvoyer l’échec. - Même clé avec un corps différent :
409 idempotency_mismatch. - Les clés sont associées à la clé API qui les a envoyées.
Emplacement des fichiers
Chaque fichier de sortie est copié dans notre stockage avant que la requête soit marquée succeeded, de sorte que les URL de outputs se trouvent sur nos propres hôtes et que vous pouvez créer directement des liens vers elles. Vous choisissez leur durée de conservation :
| Mode | Durée | Prix |
|---|---|---|
permanent (par défaut) |
Jusqu’à leur suppression | 100 crédits API (0,10 $) par Go par mois, facturés quotidiennement sur le solde API |
temporary |
7 jours, puis supprimés | Gratuit |
- Le réglage du compte s’applique aux nouvelles requêtes : le commutateur « Conserver les fichiers pour toujours » du tableau de bord, ou
PATCH https://api.doitong.com/v1/account/storageavec{"mode": "temporary"}.GET https://api.doitong.com/v1/accountl’affiche sousstorage, avec les octets conservés et l’estimation mensuelle. ?storage=permanent|temporarylors d’une exécution (l’argumentstoragede l’outil MCPrun) remplace ce réglage pour cette exécution.- Modifier le réglage ne touche jamais aux fichiers déjà présents ; supprimez-les avec
DELETE /requests/{id}/files. - Lorsque le solde API ne peut pas payer le stockage, rien n’est facturé et vous recevez un courriel : effectuez une recharge dans les 30 jours, sinon les fichiers conservés deviennent temporaires et sont supprimés 7 jours plus tard.
Dans le rare cas où notre copie échoue, l’entrée contient "stored": false et l’URL est celle d’origine, à courte durée de vie : téléchargez-la rapidement.