API
Ordini servizi dal suo sito, dal suo negozio online o da uno script: consulti i servizi e i prezzi, effettui ordini con il compito, ne segua l'avanzamento e scarichi i risultati. È lo stesso servizio del sito, quindi anche gli ordini effettuati tramite l'API compaiono nel suo account.
Per iniziare
- Acceda e apra Saldo e chiavi API.
- Crei una chiave. Viene mostrata una sola volta: la copi e la tenga segreta, come una password. Può revocare una chiave in qualsiasi momento.
- Ricarichi il saldo. Gli ordini effettuati tramite l'API vengono pagati dal saldo, in dollari USA.
Invii la chiave con ogni richiesta:
Authorization: Bearer dlx_your_key
Indirizzo dell'API: https://dleex.com/api/v1. Richieste e risposte sono in JSON. Prezzi e importi sono espressi in centesimi di dollaro USA interi: 1500 significa 15,00 $.
Servizi
GET /services elenca ciò che si può ordinare.
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 indica quanto dura il lavoro; revisions quante volte può chiedere modifiche. addons sono gli extra che può ordinare con i pacchetti indicati in tiers: il prezzo si somma a quello del pacchetto e extraDays ai suoi tempi di consegna (se negativo, il lavoro è più rapido, ma mai meno di 1 giorno). briefQuestions sono le domande che il servizio pone sul compito, alcune con un hint; le risposte vanno in answers quando effettua un ordine. L'elenco è vuoto se il servizio non chiede nulla. linkRequired è true per un servizio che si svolge su ciò che un link apre, come un profilo o un post, oppure una registrazione da sottotitolare: un ordine di questo servizio richiede link.
files è null per un servizio che non accetta file con il brief. Altrimenti indica quali file accetta, ad esempio {"accept": ["image"], "maxFiles": 3, "maxMb": 5, "required": true, "insteadOfLink": false}: i tipi (image, audio, video), quanti file per brief o richiesta di revisione, quanto può pesare ciascun file in MB, se il brief ne richiede almeno uno e se un file può sostituire link (in tal caso linkRequired resta comunque true per gli ordini inviati senza file). Vedere File.
script è null per un servizio che non legge testi ad alta voce. Un servizio di voice-over indica il testo più lungo che ogni pacchetto legge, in caratteri, ad esempio {"maxChars": {"basic": 1000, "standard": 3000, "premium": 9000}}: i suoi ordini richiedono script, il testo da leggere parola per parola. La registrazione viene letta con una voce sintetica: ovunque la pubblichi, informi i suoi ascoltatori che la voce è sintetica (vedere i Termini).
Saldo
GET /balance
{ "balanceUsdCents": 10000, "currency": "USD" }
Effettuare un ordine
POST /orders. Il prezzo (pacchetto ed extra, meno l'eventuale sconto) viene addebitato sul saldo e il lavoro inizia subito.
| Campo | ||
|---|---|---|
service | obbligatorio | Servizio da /services |
tier | obbligatorio | basic, standard o premium |
text | obbligatorio in assenza di answers, script o awaitBrief | Il compito: cosa fare, fino a 10.000 caratteri. Con script: come leggerlo (tono, ritmo, pronuncia dei nomi) |
link | facoltativo | Un link alla pagina, al profilo o al post, oppure a una registrazione: un link diretto al file, o un link Dropbox o Yandex Disk. Obbligatorio dove linkRequired è true |
answers | facoltativo | Risposte alle briefQuestions del servizio: [{"q": "question", "a": "answer"}], fino a 8, ciascuna risposta fino a 5.000 caratteri |
script | obbligatorio dove script in /services non è null, rifiutato altrove | Il testo da leggere ad alta voce, parola per parola, fino al maxChars del pacchetto (al massimo 20.000 caratteri, un a capo conta come uno). Lasci una riga vuota tra i paragrafi |
locale | facoltativo | Lingua del risultato, en o ru. Per impostazione predefinita, la lingua del suo account |
addons | facoltativo | Id degli extra da /services offerti per questo livello, ad esempio [7] |
promoCode | facoltativo | Un codice promozionale; se non è applicabile, l'ordine non viene effettuato (vedere Errori) |
awaitBrief | facoltativo | true per inviare il brief in seguito, dopo aver caricato i file: l'ordine viene pagato e resta in attesa come awaiting_brief. In tal caso ometta text, link, answers e script. Vedere File |
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 è facoltativo e consente di ripetere la richiesta in sicurezza; ogni nuovo ordine richiede una nuova chiave. Vedere Idempotenza più avanti.
Indichi text oppure almeno una risposta, o entrambi; per un voice-over basta script. Scriva ogni domanda in q così come compare in briefQuestions, nella lingua dell'ordine, e ometta quelle a cui non ha una risposta:
{
"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 risposta è l'ordine (stato 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": []
}
File
Alcuni servizi lavorano sui file del cliente, ad esempio foto di pagine da trascrivere o una registrazione da sottotitolare: il loro files in /services non è null. I file si caricano su un ordine in attesa del brief:
- Effettui l'ordine con
"awaitBrief": truee senzatext,link,answersescript. Viene pagato subito e il suo stato èawaiting_brief; i tempi di consegna decorrono dal brief. - Per ogni file, invii
POST /orders/{id}/filescon{"name": "page-1.png", "size": 482113, "mime": "image/png"}:sizeè la dimensione esatta in byte,mimeè facoltativo. La risposta (201) contiene il file e l'indirizzo a cui caricarlo:
{
"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" }
}
- Invii con
PUTi byte del file aupload.urlcon esattamente gliheadersindicati e senza chiave API, prima diupload.expiresAt(un'ora):
curl -X PUT "$url" -H "content-type: application/octet-stream" --data-binary @page-1.png
POST /orders/{id}/files/{fileId}/complete. Un file di dimensione diversa dasize, o i cui byte non sono di un tipo presente inaccept, viene rifiutato con422ed eliminato: il nome emimenon contano. Altrimenti la risposta è il file, ora in statochecking. Dopo qualche secondo, o qualche minuto per una registrazione lunga, diventaready, oppurerejectedcon il motivo inreason, ad esempiorecording_no_soundofile_unreadable. Il campofilesdell'ordine mostra lo stato dei file.POST /orders/{id}/briefcontext,link,answersescriptcome inPOST /orders. I file pronti non ancora inviati vengono allegati automaticamente, oppure può elencare quelli da inviare infileIds. Finché uno di essi è ancorachecking, il brief viene rifiutato con409 files_not_ready: lo invii di nuovo poco dopo. La risposta (200) è l'ordine, orain_progress.
DELETE /orders/{id}/files/{fileId} ritira un file non ancora inviato. Un ordine accetta al massimo 5 file e 4 GB in totale; un file di cui è iniziato il caricamento conta finché non viene completato o ritirato e, per un giorno dall'inizio del caricamento, i file ritirati o rifiutati contano, insieme ai file dell'ordine, per un limite di 12 GB: oltre questo limite il caricamento viene rifiutato con 409 upload_quota e retryAt, il momento in cui sarà di nuovo accettato. Un ordine consegnato accetta file anche per una richiesta di revisione: li carichi allo stesso modo, poi invii fileIds con la richiesta.
Senza awaitBrief, un ordine di un servizio i cui file sono required viene rifiutato con 400 files_required, e un ordine in cui un file può sostituire il link, inviato senza link, con 400 link_required.
Nell'ordine, files elenca i suoi file con il relativo status e fileIds quelli allegati al brief. Un file pronto ha un url valido fino a expiresAt, come i file dei risultati. I file vengono conservati per 30 giorni dopo la chiusura dell'ordine.
Idempotenza
Una richiesta può andare in timeout quando l'ordine è già stato effettuato. Per ripetere POST /orders senza pagare due volte, invii con essa un header Idempotency-Key: una stringa da 1 a 255 caratteri ASCII stampabili, scelta da lei una volta per ordine, ad esempio un UUID o il suo numero d'ordine. Quando ripete la richiesta, invii la stessa chiave e lo stesso corpo.
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: ..."}'
Se con questa chiave è già stato effettuato un ordine, la risposta è quell'ordine nel suo stato attuale, con stato 201 e un header in più. Non viene addebitato nulla di nuovo:
HTTP/1.1 201 Created
Idempotent-Replayed: true
- La chiave appartiene alla richiesta con cui è stata inviata la prima volta. La stessa chiave con un corpo diverso, ad esempio altri extra o un altro codice promozionale, viene rifiutata con
422 idempotency_key_reusede non viene addebitato nulla. - Se arrivano contemporaneamente più richieste con la stessa chiave, viene effettuato un solo ordine e le altre rispondono con quello. Una richiesta che deve attendere troppo risponde
409 idempotency_key_in_progresse non addebita nulla: la ripeta poco dopo. - Una richiesta non riuscita, ad esempio con
400,402,404o un errore di extra o codice promozionale, non consuma la sua chiave: la corregga e la invii di nuovo con la stessa chiave. - Una chiave viene conservata per 24 ore. Trascorso questo tempo, la stessa chiave effettua un nuovo ordine.
- Le chiavi sono distinte per ogni account. Senza l'header, ogni richiesta effettua un nuovo ordine.
L'accettazione, i brief e le richieste di revisione non richiedono una chiave. L'accettazione si può ripetere in sicurezza: una volta completato l'ordine, una ripetizione risponde 409 order_not_delivered. Lo stesso vale per il brief: una volta accettato, una ripetizione risponde 409 brief_not_expected e l'ordine è in_progress. Una richiesta di revisione è diversa: mentre il lavoro viene rifatto, una ripetizione risponde 409 order_not_delivered, ma una volta consegnato il lavoro rifatto, una ripetizione chiede un'altra revisione. Prima di ripetere una richiesta di revisione, controlli l'ordine con GET /orders/{id} (status e revisionsLeft).
Seguire gli ordini
GET /orders/{id} restituisce un ordine, GET /orders i suoi ordini, dal più recente. L'elenco accetta status, limit (da 1 a 100, 20 per impostazione predefinita) e before (un id d'ordine, per ottenere ordini meno recenti).
Stato dell'ordine:
| Stato | Significato |
|---|---|
awaiting_brief | Effettuato con awaitBrief: in attesa di POST /orders/{id}/brief |
in_progress | Il lavoro è in corso |
quality_check | Il lavoro è terminato e viene controllato prima della consegna |
delivered | Il risultato è pronto, vedere results. Lo accetti o chieda modifiche entro autoAcceptAt |
revision | Le modifiche richieste sono in corso |
completed | Ha accettato il risultato, oppure è stato accettato automaticamente |
refunded | L'importo è tornato sul suo saldo |
Controlli ogni pochi minuti; non serve farlo più spesso. Quando l'ordine è delivered, results contiene il lavoro: kind è text (Markdown), report (un report di consegna per gli ordini social media) o files (file da scaricare, con una nota facoltativa in body). Ogni risultato ha un elenco files, vuoto per testi e report: ogni file ha name, mime, size in byte e un url valido fino a expiresAt, circa un'ora. Per ottenere link nuovi, legga di nuovo l'ordine. Il link può reindirizzare allo spazio di archiviazione dei file, quindi segua i reindirizzamenti, ad esempio curl -L -o result.png "$url", e non invii la chiave API: il link da solo apre il file.
Accettazione e revisioni
POST /orders/{id}/acceptaccetta il risultato e completa l'ordine.POST /orders/{id}/revisioncon{"text": "what to change"}chiede modifiche, finchérevisionsLeftè maggiore di zero. Se il servizio accetta file,fileIdselenca i file caricati per la richiesta; in sua assenza, vengono allegati i file pronti non ancora inviati.
Se non accetta né chiede una revisione di un ordine consegnato, l'ordine viene accettato automaticamente 3 giorni dopo la consegna, all'ora indicata in autoAcceptAt (null negli altri stati). Una nuova consegna dopo una revisione fa ripartire i 3 giorni. Può anche accettare il lavoro sul sito. Se scrive nella chat dell'ordine sul sito dopo la consegna, l'ordine non viene accettato automaticamente e autoAcceptAt resta null finché non lo accetta oppure finché non rifacciamo il lavoro o lo rimborsiamo. Dopo aver risposto al suo messaggio, possiamo anche far ripartire i 3 giorni: autoAcceptAt mostra allora il nuovo orario.
Errori
Gli errori arrivano con uno stato HTTP e un codice:
{ "code": "insufficient_balance" }
| Stato | Codice | Significato |
|---|---|---|
| 400 | validation | Un campo manca o non è valido; fields li elenca |
| 400 | link_required | Questo servizio richiede link |
| 400 | files_required | Questo servizio richiede un file: effettui l'ordine con awaitBrief e lo carichi |
| 400 | script_required | Questo servizio legge un testo ad alta voce: lo invii in script |
| 400 | script_too_long | script è più lungo di quanto legge il pacchetto; maxChars nella risposta indica il massimo accettato. Non è stato addebitato nulla |
| 400 | script_not_accepted | Il servizio non legge testi ad alta voce (il suo script in /services è null): ometta script. Non è stato addebitato nulla |
| 400 | files_not_accepted, file_too_large | Il servizio non accetta file, oppure il file supera il suo maxMb |
| 400 | invalid_idempotency_key | Idempotency-Key è vuoto, supera i 255 caratteri o non è in ASCII stampabile |
| 401 | invalid_api_key | Chiave assente, errata o revocata. Le chiavi vengono revocate anche quando l'email non confermata dell'account viene confermata accedendo con Google o impostando una nuova password |
| 402 | insufficient_balance | Saldo insufficiente; non è stato addebitato nulla |
| 404 | package_not_found, order_not_found, file_not_found | Servizio, pacchetto, ordine o file inesistente |
| 409 | order_not_delivered, no_revisions_left | L'ordine non è in uno stato che consente questa operazione |
| 409 | brief_not_expected | L'ordine non è in attesa del brief: è stato effettuato senza awaitBrief, oppure il brief è già stato inviato |
| 409 | uploads_closed | I file sono accettati solo mentre l'ordine è in attesa del brief o è consegnato |
| 409 | files_limit | Più file di quanti il servizio ne accetti per brief o richiesta, oppure oltre 5 file o 4 GB per l'ordine |
| 409 | upload_quota | Con questo file, i file dell'ordine (compresi quelli inviati e i caricamenti non completati) e quelli iniziati nell'ultimo giorno e poi ritirati o rifiutati superano 12 GB: riprovi dopo retryAt |
| 409 | files_not_ready, file_rejected | Un file da inviare è ancora in fase di controllo, oppure è stato rifiutato |
| 409 | upload_incomplete | Non è stato ancora caricato nulla al link: completi il PUT, poi completi di nuovo il caricamento |
| 409 | file_in_use, file_busy | Il file è stato allegato al brief o a una richiesta e resta nell'ordine, oppure è in fase di spostamento per il controllo: riprovi tra un attimo |
| 409 | addon_unavailable | Un extra non è offerto per questo servizio e livello |
| 409 | promo_not_found, promo_inactive, promo_used_up, promo_already_used, promo_first_order_only, promo_min_order | Il codice promozionale non esiste, non è attivo al momento, è esaurito, è già stato usato da lei, vale solo per un primo ordine oppure richiede un ordine di importo maggiore. Non è stato addebitato nulla |
| 409 | idempotency_key_in_progress | Una richiesta con questa Idempotency-Key è ancora in elaborazione; la ripeta poco dopo |
| 410 | upload_expired, file_removed | Il link di caricamento è scaduto prima che venisse caricato qualcosa, oppure ha ritirato il file: avvii un nuovo caricamento |
| 415 | file_type_not_accepted | Il mime indicato non è di un tipo accettato dal servizio |
| 422 | idempotency_key_reused | Questa Idempotency-Key è già stata usata con una richiesta diversa |
| 422 | upload_size_mismatch, file_type_not_accepted | Il file caricato non ha la dimensione indicata in size, oppure i suoi byte non sono di un tipo accettato dal servizio; è stato eliminato |
| 422 | file_unreadable, recording_no_sound, check_failed | Completamento di un file rifiutato dal controllo: non si apre, la registrazione è senza audio oppure non è stato possibile controllarlo. Carichi di nuovo il file o un altro |
| 429 | rate_limited | Oltre 120 richieste al minuto con una stessa chiave; attenda i secondi indicati in Retry-After |
Rimborsi
Se rimborsiamo un ordine, l'importo torna sul saldo e l'ordine diventa refunded.