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

  1. Acceda e apra Saldo e chiavi API.
  2. Crei una chiave. Viene mostrata una sola volta: la copi e la tenga segreta, come una password. Può revocare una chiave in qualsiasi momento.
  3. 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
serviceobbligatorioServizio da /services
tierobbligatoriobasic, standard o premium
textobbligatorio in assenza di answers, script o awaitBriefIl compito: cosa fare, fino a 10.000 caratteri. Con script: come leggerlo (tono, ritmo, pronuncia dei nomi)
linkfacoltativoUn 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
answersfacoltativoRisposte alle briefQuestions del servizio: [{"q": "question", "a": "answer"}], fino a 8, ciascuna risposta fino a 5.000 caratteri
scriptobbligatorio dove script in /services non è null, rifiutato altroveIl 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
localefacoltativoLingua del risultato, en o ru. Per impostazione predefinita, la lingua del suo account
addonsfacoltativoId degli extra da /services offerti per questo livello, ad esempio [7]
promoCodefacoltativoUn codice promozionale; se non è applicabile, l'ordine non viene effettuato (vedere Errori)
awaitBrieffacoltativotrue 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:

  1. Effettui l'ordine con "awaitBrief": true e senza text, link, answers e script. Viene pagato subito e il suo stato è awaiting_brief; i tempi di consegna decorrono dal brief.
  2. Per ogni file, invii POST /orders/{id}/files con {"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" }
}
  1. Invii con PUT i byte del file a upload.url con esattamente gli headers indicati e senza chiave API, prima di upload.expiresAt (un'ora):
curl -X PUT "$url" -H "content-type: application/octet-stream" --data-binary @page-1.png
  1. POST /orders/{id}/files/{fileId}/complete. Un file di dimensione diversa da size, o i cui byte non sono di un tipo presente in accept, viene rifiutato con 422 ed eliminato: il nome e mime non contano. Altrimenti la risposta è il file, ora in stato checking. Dopo qualche secondo, o qualche minuto per una registrazione lunga, diventa ready, oppure rejected con il motivo in reason, ad esempio recording_no_sound o file_unreadable. Il campo files dell'ordine mostra lo stato dei file.
  2. POST /orders/{id}/brief con text, link, answers e script come in POST /orders. I file pronti non ancora inviati vengono allegati automaticamente, oppure può elencare quelli da inviare in fileIds. Finché uno di essi è ancora checking, il brief viene rifiutato con 409 files_not_ready: lo invii di nuovo poco dopo. La risposta (200) è l'ordine, ora in_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

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:

StatoSignificato
awaiting_briefEffettuato con awaitBrief: in attesa di POST /orders/{id}/brief
in_progressIl lavoro è in corso
quality_checkIl lavoro è terminato e viene controllato prima della consegna
deliveredIl risultato è pronto, vedere results. Lo accetti o chieda modifiche entro autoAcceptAt
revisionLe modifiche richieste sono in corso
completedHa accettato il risultato, oppure è stato accettato automaticamente
refundedL'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

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" }
StatoCodiceSignificato
400validationUn campo manca o non è valido; fields li elenca
400link_requiredQuesto servizio richiede link
400files_requiredQuesto servizio richiede un file: effettui l'ordine con awaitBrief e lo carichi
400script_requiredQuesto servizio legge un testo ad alta voce: lo invii in script
400script_too_longscript è più lungo di quanto legge il pacchetto; maxChars nella risposta indica il massimo accettato. Non è stato addebitato nulla
400script_not_acceptedIl servizio non legge testi ad alta voce (il suo script in /services è null): ometta script. Non è stato addebitato nulla
400files_not_accepted, file_too_largeIl servizio non accetta file, oppure il file supera il suo maxMb
400invalid_idempotency_keyIdempotency-Key è vuoto, supera i 255 caratteri o non è in ASCII stampabile
401invalid_api_keyChiave 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
402insufficient_balanceSaldo insufficiente; non è stato addebitato nulla
404package_not_found, order_not_found, file_not_foundServizio, pacchetto, ordine o file inesistente
409order_not_delivered, no_revisions_leftL'ordine non è in uno stato che consente questa operazione
409brief_not_expectedL'ordine non è in attesa del brief: è stato effettuato senza awaitBrief, oppure il brief è già stato inviato
409uploads_closedI file sono accettati solo mentre l'ordine è in attesa del brief o è consegnato
409files_limitPiù file di quanti il servizio ne accetti per brief o richiesta, oppure oltre 5 file o 4 GB per l'ordine
409upload_quotaCon 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
409files_not_ready, file_rejectedUn file da inviare è ancora in fase di controllo, oppure è stato rifiutato
409upload_incompleteNon è stato ancora caricato nulla al link: completi il PUT, poi completi di nuovo il caricamento
409file_in_use, file_busyIl 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
409addon_unavailableUn extra non è offerto per questo servizio e livello
409promo_not_found, promo_inactive, promo_used_up, promo_already_used, promo_first_order_only, promo_min_orderIl 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
409idempotency_key_in_progressUna richiesta con questa Idempotency-Key è ancora in elaborazione; la ripeta poco dopo
410upload_expired, file_removedIl link di caricamento è scaduto prima che venisse caricato qualcosa, oppure ha ritirato il file: avvii un nuovo caricamento
415file_type_not_acceptedIl mime indicato non è di un tipo accettato dal servizio
422idempotency_key_reusedQuesta Idempotency-Key è già stata usata con una richiesta diversa
422upload_size_mismatch, file_type_not_acceptedIl file caricato non ha la dimensione indicata in size, oppure i suoi byte non sono di un tipo accettato dal servizio; è stato eliminato
422file_unreadable, recording_no_sound, check_failedCompletamento 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
429rate_limitedOltre 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.