Requêtes
Une requête correspond à un appel d'un modèle. Elle possède un identifiant (req_…), un statut, 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 chaque modèle.
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 tags, 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 d'une ligne précédente : chaque variante d'un modèle (pro, fast, image-to-video, …). |
mode |
exact (le prix est calculé à partir de l'entrée), measured (à partir de la durée 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, par défaut 50) 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 des entrées et sorties, 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 la forme d'un 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 invalide renvoie
422 invalid_inputavec leparamconcerné et ne coûte rien. ?wait=N(jusqu'à 20 secondes) maintient l'appel jusqu'à la fin de la requête ou l'expiration du délai.?webhook_url=https://…envoie un POST signé à cette URL lorsque la requête se termine (voir Webhooks).?storage=permanentou?storage=temporarychoisit la durée de conservation des fichiers de sortie ; sans ce paramètre, le réglage du compte s'applique (voir Emplacement des fichiers).
La réponse est 202 Accepted tant que la requête est en cours, 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.
Statuts
-
queuedAcceptée et facturée, en attente d’un worker -
runningLe modèle génère le résultat -
États finaux:
succeededDevis facturé ; outputs[] contient les URL sur notre stockagefailedRemboursée automatiquement ; l’erreur en indique la raisoncanceledArrêtée avant l’obtention d’un résultat ; remboursée
| Statut | Signification | Final |
|---|---|---|
queued |
Acceptée et facturée, en attente d'un worker. queue_position peut indiquer la position dans la file. |
non |
running |
Le modèle est en cours de génération. | non |
succeeded |
Terminée. outputs répertorie les fichiers. |
oui |
failed |
Le modèle ou une limite l'a interrompue. 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 chaque modèle : une entrée par fichier généré avectype(image,video,audio,fileou3d), uneurlsur 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,cost.refundedce qui a été remboursé. Pour un modèlemetered,cost.creditsest le maximum bloqué 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 interrogation longue : l'appel renvoie dès que la requête est finale, ou après N secondes avec l'état actuel. Boucler de cette façon est le moyen le 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.
Lister 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 (par défaut 20), status et model filtrent. La réponse est
{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" } ; transmettez cursor=<next_cursor> pour
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 : le statut devient
canceled, les crédits API sont remboursés et vous obtenez200. - Déjà en cours de génération : l'annulation est transmise et vous obtenez
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 arrête leur facturation 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 ne possède pas encore de fichiers : 409 request_active. Nécessite models:run.
Idempotence : réessayer sans payer deux fois
Les réseaux échouent. Pour réessayer une exécution en toute sécurité, envoyez un en-tête Idempotency-Key (n'importe quelle 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 récupérez 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 qui a é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é, le nouvel essai 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 sont hébergées sur
nos propres serveurs et que vous pouvez créer un lien direct 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 et par mois, facturés quotidiennement sur le solde API |
temporary |
7 jours, puis suppression | Gratuit |
- Le réglage du compte s'applique aux nouvelles requêtes : le bouton « Conserver les fichiers indéfiniment » 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) le remplace 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 e-mail : effectuez un rechargement 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, à durée de vie courte :
téléchargez-la rapidement.