API
Commandez des services depuis votre propre site, boutique ou script : listez les services et leurs prix, passez des commandes avec la tâche à réaliser, suivez-les et récupérez les résultats. C’est le même service que sur le site : les commandes passées via l’API apparaissent aussi dans votre compte.
Premiers pas
- Connectez-vous et ouvrez Solde et clés API.
- Créez une clé. Elle n’est affichée qu’une seule fois : copiez-la et gardez-la secrète, comme un mot de passe. Vous pouvez révoquer une clé à tout moment.
- Rechargez votre solde. Les commandes passées via l’API sont payées à partir de celui-ci, en dollars américains.
Envoyez la clé avec chaque requête :
Authorization: Bearer dlx_your_key
Adresse de l’API : https://dleex.com/api/v1. Les requêtes et les réponses sont au format JSON. Les prix et les montants sont exprimés en cents américains entiers : 1500 signifie 15,00 $.
Services
GET /services liste ce qui peut être commandé.
curl https://dleex.com/api/v1/services -H "Authorization: Bearer dlx_your_key"
[
{
"service": "seo-article",
"category": "seo",
"title": { "en": "SEO article", "ru": "SEO-статья" },
"linkRequired": false,
"files": null,
"script": null,
"briefQuestions": [
{ "q": { "en": "What is the article about?", "ru": "О чём статья?" }, "hint": { "en": "The topic, or a link to the page.", "ru": "..." } },
{ "q": { "en": "Who will read it?", "ru": "..." } }
],
"packages": [
{ "tier": "basic", "title": { "en": "...", "ru": "..." }, "priceUsdCents": 1500, "days": 2, "revisions": 1 },
{ "tier": "standard", "...": "..." },
{ "tier": "premium", "...": "..." }
],
"addons": [
{
"id": 7,
"title": { "en": "Express delivery", "ru": "Срочное выполнение" },
"description": null,
"priceUsdCents": 1000,
"extraDays": -1,
"tiers": ["standard", "premium"]
}
]
}
]
days indique la durée du travail ; revisions indique combien de fois vous pouvez demander des retouches. addons sont les options que vous pouvez commander avec les formules listées dans tiers : leur prix s’ajoute à celui de la formule, et extraDays à son délai (valeur négative : plus rapide, jamais moins d’un jour). briefQuestions sont les questions que le service pose sur la tâche, certaines accompagnées d’un hint ; répondez-y dans answers lorsque vous passez une commande. La liste est vide quand un service ne pose aucune question. linkRequired vaut true pour un service réalisé à partir de ce qu’ouvre un lien, comme un profil ou une publication, ou un enregistrement à sous-titrer : une commande de ce service nécessite link.
files vaut null pour un service qui n’accepte aucun fichier avec le brief. Sinon, il indique lesquels il accepte, par exemple {"accept": ["image"], "maxFiles": 3, "maxMb": 5, "required": true, "insteadOfLink": false} : les types (image, audio, video), le nombre de fichiers par brief ou par demande de retouches, la taille maximale de chaque fichier en Mo, si le brief en exige au moins un, et si un fichier peut remplacer link (linkRequired reste alors true pour les commandes envoyées sans fichier). Voir Fichiers.
script vaut null pour un service qui ne lit aucun texte à voix haute. Un service de voix off indique le texte le plus long que lit chaque formule, en caractères, par exemple {"maxChars": {"basic": 1000, "standard": 3000, "premium": 9000}} : ses commandes nécessitent script, le texte à lire mot pour mot. L’enregistrement est lu par une voix de synthèse : où que vous le publiiez, indiquez à vos auditeurs que la voix est synthétique (voir les Conditions d’utilisation).
Solde
GET /balance
{ "balanceUsdCents": 10000, "currency": "USD" }
Passer une commande
POST /orders. Le prix (la formule et les options, moins une éventuelle remise) est débité du solde et le travail commence aussitôt.
| Champ | ||
|---|---|---|
service | obligatoire | Service issu de /services |
tier | obligatoire | basic, standard ou premium |
text | obligatoire sans answers, script ni awaitBrief | La tâche : ce qu’il faut faire, jusqu’à 10 000 caractères. Avec script : comment le lire (ton, rythme, prononciation des noms) |
link | facultatif | Un lien vers la page, le profil ou la publication, ou vers un enregistrement : un lien direct vers le fichier, ou un lien Dropbox ou Yandex Disk. Obligatoire lorsque linkRequired vaut true |
answers | facultatif | Réponses aux briefQuestions du service : [{"q": "question", "a": "answer"}], jusqu’à 8, chaque réponse jusqu’à 5 000 caractères |
script | obligatoire lorsque script dans /services ne vaut pas null, refusé ailleurs | Le texte à lire à voix haute, mot pour mot, dans la limite du maxChars de la formule (20 000 caractères au maximum, un saut de ligne comptant pour un). Laissez une ligne vide entre les paragraphes |
locale | facultatif | Langue du résultat, en ou ru. Par défaut, la langue de votre compte |
addons | facultatif | Identifiants des options de /services proposées pour cette formule, par exemple [7] |
promoCode | facultatif | Un code promo ; s’il ne s’applique pas, la commande n’est pas passée (voir Erreurs) |
awaitBrief | facultatif | true pour envoyer le brief plus tard, après avoir téléversé les fichiers : la commande est payée et attend avec le statut awaiting_brief. Omettez alors text, link, answers et script. Voir Fichiers |
curl https://dleex.com/api/v1/orders -H "Authorization: Bearer dlx_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: <your-order-id>" \
-d '{"service":"seo-article","tier":"basic","text":"An article about trail running shoes, 5 keywords: ..."}'
Idempotency-Key est facultatif et permet de répéter la requête en toute sécurité ; chaque nouvelle commande nécessite une nouvelle clé. Voir Idempotence ci-dessous.
Indiquez soit text, soit au moins une réponse, soit les deux ; pour une voix off, script suffit. Écrivez chaque question dans q telle qu’elle figure dans briefQuestions, dans la langue de la commande, et omettez celles auxquelles vous n’avez pas de réponse :
{
"service": "seo-article",
"tier": "basic",
"answers": [
{ "q": "What is the article about?", "a": "Choosing trail running shoes" },
{ "q": "Who will read it?", "a": "Runners moving from road to trail" }
]
}
La réponse est la commande (statut 201) :
{
"id": 1042,
"status": "in_progress",
"service": "seo-article",
"tier": "basic",
"priceUsdCents": 1500,
"addons": [],
"discountUsdCents": 0,
"promoCode": null,
"locale": "en",
"text": "An article about trail running shoes...",
"link": null,
"answers": [],
"script": null,
"fileIds": [],
"files": [],
"revisionsLeft": 1,
"createdAt": "2026-10-16T11:00:00.000Z",
"dueAt": "2026-10-18T11:00:00.000Z",
"deliveredAt": null,
"autoAcceptAt": null,
"completedAt": null,
"results": []
}
Fichiers
Certains services travaillent à partir des fichiers du client, comme des photos de pages à retranscrire ou un enregistrement à sous-titrer : leur files dans /services ne vaut pas null. Les fichiers sont téléversés sur une commande qui attend son brief :
- Passez la commande avec
"awaitBrief": trueet sanstext,link,answersniscript. Elle est payée aussitôt et son statut estawaiting_brief; le délai commence à courir avec le brief. - Pour chaque fichier, envoyez
POST /orders/{id}/filesavec{"name": "page-1.png", "size": 482113, "mime": "image/png"}:sizeest la taille exacte en octets,mimeest facultatif. La réponse (201) contient le fichier et l’adresse où le téléverser :
{
"file": { "id": 77, "name": "page-1.png", "mime": "application/octet-stream", "size": 482113, "status": "pending", "used": false, "uploadExpiresAt": "2026-10-16T12:00:00.000Z", "createdAt": "2026-10-16T11:00:00.000Z" },
"upload": { "url": "https://...", "headers": { "content-type": "application/octet-stream" }, "expiresAt": "2026-10-16T12:00:00.000Z" }
}
- Envoyez les octets du fichier par
PUTàupload.urlavec exactement lesheadersindiqués et sans clé API, avantupload.expiresAt(une heure) :
curl -X PUT "$url" -H "content-type: application/octet-stream" --data-binary @page-1.png
POST /orders/{id}/files/{fileId}/complete. Un fichier dont la taille diffère desize, ou dont les octets ne correspondent à aucun type deaccept, est refusé avec422et supprimé : le nom etmimene comptent pas. Sinon, la réponse est le fichier, désormaischecking. Après quelques secondes, ou quelques minutes pour un long enregistrement, il passe àready, ou àrejectedavec le motif dansreason, par exemplerecording_no_soundoufile_unreadable. Le champfilesde la commande indique leur état.POST /orders/{id}/briefavectext,link,answersetscriptcomme pourPOST /orders. Les fichiers prêts pas encore envoyés l’accompagnent, ou listez ceux à envoyer dansfileIds. Tant que l’un d’eux est encorechecking, le brief est refusé avec409 files_not_ready: renvoyez-le un peu plus tard. La réponse (200) est la commande, désormaisin_progress.
DELETE /orders/{id}/files/{fileId} retire un fichier pas encore envoyé. Une commande accepte au maximum 5 fichiers et 4 Go au total ; un fichier dont le téléversement a commencé compte jusqu’à ce qu’il soit finalisé ou retiré, et pendant une journée à compter du début de leur téléversement, les fichiers retirés ou refusés comptent dans une limite de 12 Go avec les fichiers de la commande : au-delà, un téléversement est refusé avec 409 upload_quota et retryAt, l’heure à laquelle il sera de nouveau accepté. Une commande livrée accepte aussi des fichiers pour une demande de retouches : téléversez-les de la même façon, puis envoyez fileIds avec la demande.
Sans awaitBrief, une commande d’un service dont les fichiers sont required est refusée avec 400 files_required, et celle d’un service où un fichier peut remplacer le lien, envoyée sans lien, avec 400 link_required.
Dans la commande, files liste vos fichiers avec leur status, et fileIds ceux qui ont accompagné le brief. Un fichier prêt possède une url valable jusqu’à expiresAt, comme les fichiers de résultat. Les fichiers sont conservés 30 jours après la clôture de la commande.
Idempotence
Une requête peut expirer alors que la commande a déjà été passée. Pour répéter POST /orders sans payer deux fois, envoyez avec elle un en-tête Idempotency-Key : une chaîne de 1 à 255 caractères ASCII imprimables que vous choisissez une fois par commande, comme un UUID ou votre propre numéro de commande. Envoyez la même clé et le même corps lorsque vous répétez la requête.
curl -i https://dleex.com/api/v1/orders -H "Authorization: Bearer dlx_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: shop-order-981" \
-d '{"service":"seo-article","tier":"basic","text":"An article about trail running shoes, 5 keywords: ..."}'
Si une commande a déjà été passée avec cette clé, la réponse est cette commande dans son état actuel, avec le statut 201 et un en-tête supplémentaire. Rien n’est débité une seconde fois :
HTTP/1.1 201 Created
Idempotent-Replayed: true
- La clé appartient à la requête avec laquelle elle a été envoyée la première fois. La même clé avec un corps différent, par exemple d’autres options ou un autre code promo, est refusée avec
422 idempotency_key_reused, et rien n’est débité. - Si plusieurs requêtes avec la même clé arrivent en même temps, une seule commande est passée et les autres renvoient celle-ci. Une requête qui doit attendre trop longtemps renvoie
409 idempotency_key_in_progresset ne débite rien : répétez-la un instant plus tard. - Une requête qui a échoué, par exemple avec
400,402,404ou une erreur d’option ou de code promo, ne consomme pas sa clé : corrigez-la et renvoyez-la avec la même clé. - Une clé est conservée 24 heures. Passé ce délai, la même clé passe une nouvelle commande.
- Les clés sont propres à chaque compte. Sans l’en-tête, chaque requête passe une nouvelle commande.
La validation, les briefs et les demandes de retouches ne prennent pas de clé. La validation peut être répétée sans risque : une fois la commande terminée, une répétition renvoie 409 order_not_delivered. De même pour un brief : une fois qu’il est passé, une répétition renvoie 409 brief_not_expected et la commande est in_progress. Une demande de retouches est différente : pendant que le travail est repris, une répétition renvoie 409 order_not_delivered, mais une fois la nouvelle version livrée, une répétition demande une retouche supplémentaire. Avant de répéter une demande de retouches, vérifiez la commande avec GET /orders/{id} (status et revisionsLeft).
Suivi des commandes
GET /orders/{id} renvoie une commande, GET /orders vos commandes, des plus récentes aux plus anciennes. La liste accepte status, limit (de 1 à 100, 20 par défaut) et before (un identifiant de commande, pour obtenir des commandes plus anciennes).
Statut de la commande :
| Statut | Signification |
|---|---|
awaiting_brief | Passée avec awaitBrief : en attente de POST /orders/{id}/brief |
in_progress | Le travail est en cours |
quality_check | Le travail est terminé et vérifié avant la livraison |
delivered | Le résultat est prêt, voir results. Validez-le ou demandez des retouches avant autoAcceptAt |
revision | Les retouches demandées sont en cours |
completed | Vous avez validé le résultat, ou il a été validé automatiquement |
refunded | L’argent a été restitué sur votre solde |
Vérifiez toutes les quelques minutes ; inutile d’interroger plus souvent. Lorsque la commande est delivered, results contient le travail : kind vaut text (Markdown), report (un rapport de livraison pour les commandes réseaux sociaux) ou files (des fichiers à télécharger, avec une note facultative dans body). Chaque résultat comporte une liste files, vide pour les textes et les rapports : chaque fichier a un name, un mime, une size en octets et une url valable jusqu’à expiresAt, environ une heure. Relisez la commande pour obtenir de nouveaux liens. Le lien peut rediriger vers le stockage des fichiers : suivez donc les redirections, par exemple curl -L -o result.png "$url", et n’envoyez pas de clé API avec : le lien suffit à ouvrir le fichier.
Validation et retouches
POST /orders/{id}/acceptvalide le résultat et termine la commande.POST /orders/{id}/revisionavec{"text": "what to change"}demande des retouches, tant querevisionsLeftest supérieur à zéro. Lorsque le service accepte des fichiers,fileIdsliste les fichiers téléversés pour la demande ; sans lui, les fichiers prêts pas encore envoyés l’accompagnent.
Si vous ne validez pas une commande livrée et ne demandez pas de retouches, elle est validée automatiquement 3 jours après la livraison, à l’heure indiquée dans autoAcceptAt (null dans les autres états). Une nouvelle livraison après des retouches relance les 3 jours. Vous pouvez aussi valider le travail sur le site. Si vous écrivez dans le chat de la commande sur le site après la livraison, la commande n’est pas validée automatiquement et autoAcceptAt vaut null jusqu’à ce que vous la validiez ou que nous reprenions le travail ou le remboursions. Après avoir répondu à votre message, nous pouvons aussi relancer les 3 jours : autoAcceptAt indique alors la nouvelle heure.
Erreurs
Les erreurs sont accompagnées d’un statut HTTP et d’un code :
{ "code": "insufficient_balance" }
| Statut | Code | Signification |
|---|---|---|
| 400 | validation | Un champ est manquant ou incorrect ; fields les liste |
| 400 | link_required | Ce service nécessite link |
| 400 | files_required | Ce service nécessite un fichier : passez la commande avec awaitBrief et téléversez-le |
| 400 | script_required | Ce service lit un texte à voix haute : envoyez-le dans script |
| 400 | script_too_long | script est plus long que ce que lit la formule ; maxChars dans la réponse indique le maximum accepté. Rien n’a été débité |
| 400 | script_not_accepted | Le service ne lit aucun texte à voix haute (son script dans /services vaut null) : omettez script. Rien n’a été débité |
| 400 | files_not_accepted, file_too_large | Le service n’accepte aucun fichier, ou le fichier dépasse son maxMb |
| 400 | invalid_idempotency_key | Idempotency-Key est vide, dépasse 255 caractères ou n’est pas en ASCII imprimable |
| 401 | invalid_api_key | Clé absente, incorrecte ou révoquée. Les clés sont aussi révoquées lorsque l’e-mail non confirmé du compte est confirmé par une connexion avec Google ou par la définition d’un nouveau mot de passe |
| 402 | insufficient_balance | Solde insuffisant ; rien n’a été débité |
| 404 | package_not_found, order_not_found, file_not_found | Service, formule, commande ou fichier introuvable |
| 409 | order_not_delivered, no_revisions_left | La commande n’est pas dans un état qui le permet |
| 409 | brief_not_expected | La commande n’attend pas son brief : elle a été passée sans awaitBrief, ou son brief a déjà été envoyé |
| 409 | uploads_closed | Les fichiers ne sont acceptés que lorsque la commande attend son brief ou est livrée |
| 409 | files_limit | Plus de fichiers que le service n’en accepte par brief ou par demande, ou plus de 5 fichiers ou 4 Go pour la commande |
| 409 | upload_quota | Avec celui-ci, les fichiers de la commande (y compris ceux envoyés et les téléversements inachevés) et ceux commencés au cours de la dernière journée puis retirés ou refusés dépassent 12 Go : réessayez après retryAt |
| 409 | files_not_ready, file_rejected | Un fichier à envoyer est encore en cours de vérification, ou a été rejeté |
| 409 | upload_incomplete | Rien n’a encore été téléversé sur le lien : terminez le PUT, puis finalisez à nouveau le téléversement |
| 409 | file_in_use, file_busy | Le fichier a accompagné le brief ou une demande et reste lié à la commande, ou il est en cours de déplacement par sa vérification : réessayez dans un instant |
| 409 | addon_unavailable | Une option n’est pas proposée pour ce service et cette formule |
| 409 | promo_not_found, promo_inactive, promo_used_up, promo_already_used, promo_first_order_only, promo_min_order | Le code promo n’existe pas, n’est pas actif actuellement, est épuisé, a déjà été utilisé par vous, est réservé à une première commande ou exige une commande plus importante. Rien n’a été débité |
| 409 | idempotency_key_in_progress | Une requête avec cette Idempotency-Key est encore en cours de traitement ; répétez-la un instant plus tard |
| 410 | upload_expired, file_removed | Le lien de téléversement a expiré avant que quoi que ce soit ait été téléversé, ou vous avez retiré le fichier : lancez un nouveau téléversement |
| 415 | file_type_not_accepted | Le mime indiqué ne correspond à aucun type accepté par le service |
| 422 | idempotency_key_reused | Cette Idempotency-Key a déjà été utilisée avec une autre requête |
| 422 | upload_size_mismatch, file_type_not_accepted | Le fichier téléversé n’a pas la taille indiquée dans size, ou ses octets ne correspondent à aucun type accepté par le service ; il a été supprimé |
| 422 | file_unreadable, recording_no_sound, check_failed | Finalisation d’un fichier rejeté par la vérification : il ne s’ouvre pas, l’enregistrement n’a pas de son, ou il n’a pas pu être vérifié. Téléversez à nouveau le fichier ou un autre |
| 429 | rate_limited | Plus de 120 requêtes par minute avec une même clé ; attendez le nombre de secondes indiqué dans Retry-After |
Remboursements
Si nous remboursons une commande, l’argent est restitué sur le solde et la commande passe à refunded.