Passer au contenu
Guide de l’API

Requêtes

Afficher en Markdown Mis à jour

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) :

terminal
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

terminal
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_input avec le param concerné 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=permanent ou ?storage=temporary choisit 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

Cycle de vie d’une requête
  1. queued Acceptée et facturée, en attente d’un worker
  2. running Le modèle génère le résultat
  3. États finaux:
    • succeededDevis facturé ; outputs[] contient les URL sur notre stockage
    • failedRemboursée automatiquement ; l’erreur en indique la raison
    • canceledArrê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

JSON
{
  "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"
  }
}
  • outputs est identique pour chaque modèle : une entrée par fichier généré avec type (image, video, audio, file ou 3d), une url sur notre stockage, content_type et, lorsqu'ils sont connus, file_size, width, height, duration.
  • output est 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.
  • storage indique comment les fichiers sont conservés : mode (permanent ou temporary), bytes stockés, expires_at (date de suppression d'un fichier temporaire, null pour les fichiers permanents) et expired (true une fois les fichiers supprimés).
  • cost.credits est le prix de l'appel en crédits API (cost.usd en USD), cost.charged ce qui a été débité du solde API, cost.refunded ce qui a été remboursé. Pour un modèle metered, cost.credits est le maximum bloqué au début (cost.held) ; une fois l'exécution réussie, cost.settled indique le montant correspondant à l'utilisation et le reste du maximum figure dans cost.refunded (voir Facturation selon l'utilisation).
  • Lorsqu'une requête échoue, error est { "type": …, "code": …, "message": … }.

Lire une requête

terminal
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=1 ajoute les lignes du journal de progression du modèle (les 50 dernières) sous logs.

Vous pouvez uniquement lire les requêtes de votre propre compte ; tout autre identifiant renvoie 404 request_not_found.

Lister les requêtes

terminal
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

terminal
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 obtenez 200.
  • Déjà en cours de génération : l'annulation est transmise et vous obtenez 202 avec "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à canceled renvoie simplement 200).

Supprimer les fichiers d'une requête

terminal
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ête Idempotent-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_error ou internal_error lors 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/storage avec {"mode": "temporary"}. GET https://api.doitong.com/v1/account l'affiche sous storage, avec les octets conservés et l'estimation mensuelle.
  • ?storage=permanent|temporary lors d'une exécution (l'argument storage de l'outil MCP run) 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.