Accéder 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 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 provenant 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 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 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 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_input avec le param concerné et ne coûte rien.
  • ?wait=N (jusqu’à 20 secondes) maintient l’appel ouvert 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 détermine 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 processus
  2. running Le modèle génère le résultat
  3. États finaux:
    • succeededDevis facturé ; outputs[] contient des 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 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 l’a arrêtée. 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 les vidéos, 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 tous les modèles : 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’elles sont connues, 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 le montant débité du solde API, et cost.refunded le montant remboursé. Pour un modèle metered, cost.credits correspond au 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 vaut { "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 attente longue : l’appel renvoie dès que la requête est finale, ou après N secondes avec l’état actuel. Répéter cet appel 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.

Répertorier 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 (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

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 recevez 200.
  • Déjà en cours de génération : l’annulation est transmise et vous recevez 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 n’a pas encore de fichiers : 409 request_active. Nécessite models:run.

Idempotence : réessayer sans payer deux fois

Les réseaux peuvent tomber en panne. 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 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 ayant é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é ; 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 limité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 ; les URL de outputs se trouvent donc sur nos propres hôtes et vous pouvez les utiliser directement. 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) 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 e-mail : rechargez votre solde 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 limitée : téléchargez-la rapidement.