API

Заказывайте услуги со своего сайта, из магазина или скрипта: получайте список услуг и цен, создавайте заказы с заданием, следите за ними и забирайте результат. Это тот же сервис, что и на сайте, поэтому заказы через API видны и в личном кабинете.

С чего начать

  1. Войдите и откройте Баланс и API-ключи.
  2. Создайте ключ. Он показывается один раз: скопируйте его и храните в секрете, как пароль. Ключ можно отозвать в любой момент.
  3. Пополните баланс. Заказы через API оплачиваются с него, в долларах США.

Передавайте ключ в каждом запросе:

Authorization: Bearer dlx_ваш_ключ

Адрес API: https://dleex.com/api/v1. Запросы и ответы в JSON. Цены и суммы указаны в центах США целым числом: 1500 значит $15,00.

Услуги

GET /services возвращает список того, что можно заказать.

curl https://dleex.com/api/v1/services -H "Authorization: Bearer dlx_ваш_ключ"
[
  {
    "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": "...", "ru": "Тема или ссылка на страницу." } },
      { "q": { "en": "...", "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 — срок выполнения в днях, revisions — сколько раз можно попросить доработку. addons — дополнительные опции, которые можно заказать вместе с пакетами из tiers: их цена прибавляется к цене пакета, а extraDays — к сроку (отрицательное число ускоряет работу, но срок не бывает меньше 1 дня). briefQuestions — что услуга спрашивает о задаче, у некоторых вопросов есть подсказка hint; ответы на них передаются в answers при создании заказа. Если услуга ни о чём не спрашивает, список пустой. linkRequired равно true у услуг, которые выполняются по ссылке, например на профиль или пост либо на запись для субтитров: заказу такой услуги нужна ссылка link.

files равно null у услуг, которые не принимают файлы с брифом. Иначе там сказано, какие файлы принимаются, например {"accept": ["image"], "maxFiles": 3, "maxMb": 5, "required": true, "insteadOfLink": false}: типы (image, audio, video), сколько файлов можно отправить с одним брифом или запросом на доработку, сколько мегабайт может весить каждый, обязателен ли хотя бы один файл и может ли файл заменить ссылку link (тогда linkRequired всё равно true для заказов без файлов). См. раздел «Файлы».

script равно null у услуг, которые не читают текст вслух. У услуги озвучки там указан самый длинный текст, который читает каждый пакет, в символах, например {"maxChars": {"basic": 1000, "standard": 3000, "premium": 9000}}: заказам такой услуги нужен script — текст, который прочитают слово в слово. Запись читает синтезированный голос: везде, где публикуете её, сообщайте слушателям, что голос синтезированный (см. Условия использования).

Баланс

GET /balance

{ "balanceUsdCents": 10000, "currency": "USD" }

Создание заказа

POST /orders. Стоимость (пакет и опции за вычетом скидки) списывается с баланса, работа начинается сразу.

Поле
serviceобязательноУслуга из /services
tierобязательноbasic, standard или premium
textобязательно без answers, script и awaitBriefЗадание: что нужно сделать, до 10 000 символов. Вместе со script — как читать текст (тон, темп, как произносить имена)
linkпо ситуацииСсылка на страницу, профиль или пост либо на запись: прямая ссылка на файл или ссылка Dropbox или Яндекс Диска. Обязательна, если у услуги linkRequired равно true
answersнетОтветы на briefQuestions услуги: [{"q": "вопрос", "a": "ответ"}], до 8 штук, каждый ответ до 5 000 символов
scriptобязательно, если у услуги в /services script не null; другие услуги его не принимаютТекст, который нужно прочитать вслух слово в слово, не длиннее maxChars пакета (и не больше 20 000 символов; перенос строки считается одним символом). Абзацы разделяйте пустой строкой
localeнетЯзык результата, en или ru. По умолчанию язык аккаунта
addonsнетНомера опций из /services, доступных для этого пакета, например [7]
promoCodeнетПромокод; если он не подходит, заказ не создаётся (см. «Ошибки»)
awaitBriefнетtrue, чтобы отправить бриф позже, после загрузки файлов: заказ оплачивается и ждёт в статусе awaiting_brief. text, link, answers и script тогда не передаются. См. раздел «Файлы»
curl https://dleex.com/api/v1/orders -H "Authorization: Bearer dlx_ваш_ключ" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: <ваш-номер-заказа>" \
  -d '{"service":"seo-article","tier":"basic","text":"Статья о кроссовках для трейлраннинга, 5 ключевых слов: ..."}'

Idempotency-Key необязателен и позволяет безопасно повторить запрос; для каждого нового заказа нужен новый ключ. См. раздел «Идемпотентность» ниже.

Нужен text, хотя бы один ответ или и то и другое; для озвучки достаточно script. Вопрос в q пишите так, как он указан в briefQuestions, на языке заказа; вопросы без ответа можно не передавать:

{
  "service": "seo-article",
  "tier": "basic",
  "locale": "ru",
  "answers": [
    { "q": "О чём статья?", "a": "Как выбрать кроссовки для трейлраннинга" },
    { "q": "Кто будет читать статью?", "a": "Бегуны, которые переходят с асфальта на тропы" }
  ]
}

В ответ приходит заказ (статус 201):

{
  "id": 1042,
  "status": "in_progress",
  "service": "seo-article",
  "tier": "basic",
  "priceUsdCents": 1500,
  "addons": [],
  "discountUsdCents": 0,
  "promoCode": null,
  "locale": "ru",
  "text": "Статья о кроссовках для трейлраннинга...",
  "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": []
}

Файлы

Некоторые услуги выполняются по файлам клиента, например по фотографиям страниц для набора текста или по записи для субтитров: у них files в /services не null. Файлы загружаются в заказ, который ждёт бриф:

  1. Создайте заказ с "awaitBrief": true и без text, link, answers и script. Он сразу оплачивается и получает статус awaiting_brief; срок пойдёт после брифа.
  2. Для каждого файла отправьте POST /orders/{id}/files с {"name": "page-1.png", "size": 482113, "mime": "image/png"}: size — точный размер в байтах, mime необязателен. В ответ (201) приходит файл и адрес для загрузки:
{
  "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. Отправьте содержимое файла запросом PUT на upload.url ровно с указанными headers и без API-ключа, до upload.expiresAt (в течение часа):
curl -X PUT "$url" -H "content-type: application/octet-stream" --data-binary @page-1.png
  1. Отправьте POST /orders/{id}/files/{fileId}/complete. Файл другого размера, чем size, или файл, содержимое которого не относится к типам из accept, отклоняется с ошибкой 422 и удаляется: имя и mime не учитываются. Иначе в ответ приходит файл в статусе checking. Через несколько секунд, а для длинной записи через несколько минут, он становится ready или rejected с причиной в reason, например recording_no_sound или file_unreadable. Как идёт проверка, видно в files заказа.
  2. Отправьте POST /orders/{id}/brief с text, link, answers и script, как в POST /orders. С брифом уходят готовые файлы, которые ещё не отправлены, либо те, что перечислены в fileIds. Пока один из них ещё checking, бриф отклоняется с ошибкой 409 files_not_ready: отправьте его чуть позже. В ответ (200) приходит заказ, теперь in_progress.

DELETE /orders/{id}/files/{fileId} убирает файл, который ещё не отправлен. В одном заказе не больше 5 файлов и 4 ГБ всего; файл, загрузку которого начали, считается, пока его не завершат или не уберут, а убранные и отклонённые файлы сутки с начала их загрузки считаются вместе с файлами заказа в предел 12 ГБ: сверх него загрузка получает отказ 409 upload_quota с retryAt, временем, когда её снова примут. Сданный заказ принимает файлы и для запроса на доработку: загрузите их так же и передайте fileIds в запросе.

Без awaitBrief заказ услуги, у которой файлы required, отклоняется с ошибкой 400 files_required, а заказ услуги, где файл может заменить ссылку, без ссылки — с ошибкой 400 link_required.

В заказе files перечисляет ваши файлы с их status, а fileIds — файлы, ушедшие с брифом. У готового файла есть ссылка url, которая работает до expiresAt, как у файлов результата. Файлы хранятся 30 дней после закрытия заказа.

Идемпотентность

Запрос может оборваться по тайм-ауту, когда заказ уже создан. Чтобы повторить POST /orders и не заплатить дважды, передавайте в нём заголовок Idempotency-Key: строку из 1–255 печатных символов ASCII, которую вы выбираете один раз для каждого заказа, например UUID или номер заказа в вашей системе. При повторе отправляйте тот же ключ и то же тело запроса.

curl -i https://dleex.com/api/v1/orders -H "Authorization: Bearer dlx_ваш_ключ" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: shop-order-981" \
  -d '{"service":"seo-article","tier":"basic","text":"Статья о кроссовках для трейлраннинга, 5 ключевых слов: ..."}'

Если заказ с этим ключом уже создан, в ответ придёт он же в текущем состоянии, со статусом 201 и дополнительным заголовком. Повторно деньги не списываются:

HTTP/1.1 201 Created
Idempotent-Replayed: true

Приёмка, бриф и доработка ключ не принимают. Приёмку можно безопасно повторить: когда заказ завершён, повтор ответит 409 order_not_delivered. Бриф тоже: если он уже принят, повтор ответит 409 brief_not_expected, а заказ будет в статусе in_progress. С доработкой иначе: пока работу переделывают, повтор ответит 409 order_not_delivered, но после сдачи переделанной работы повтор попросит ещё одну доработку. Поэтому перед повтором запроса на доработку проверьте заказ через GET /orders/{id} (status и revisionsLeft).

Статус заказов

GET /orders/{id} возвращает один заказ, GET /orders — ваши заказы, новые первыми. Список принимает status, limit (от 1 до 100, по умолчанию 20) и before (номер заказа, чтобы получить более старые).

Статусы:

СтатусЧто значит
awaiting_briefЗаказ создан с awaitBrief и ждёт POST /orders/{id}/brief
in_progressРабота выполняется
quality_checkРабота готова и проходит проверку перед сдачей
deliveredРезультат готов, смотрите results. Примите его или попросите доработку до autoAcceptAt
revisionВносятся правки, которые вы попросили
completedВы приняли работу, или она была принята автоматически
refundedДеньги вернулись на баланс

Проверяйте раз в несколько минут, чаще не нужно. Когда заказ в статусе delivered, в results лежит работа: kind равен text (текст в Markdown), report (отчёт о выполнении для заказов в соцсетях) или files (файлы для скачивания, в body может быть пояснение). У каждого результата есть список files, пустой для текста и отчёта: у файла есть name, mime, size в байтах и ссылка url, которая работает до expiresAt, около часа. За новыми ссылками запросите заказ ещё раз. Ссылка может перенаправить в хранилище файлов, поэтому следуйте перенаправлениям, например curl -L -o result.png "$url", и не отправляйте с ней API-ключ: файл открывает сама ссылка.

Приёмка и доработки

Если работу не принять и не отправить на доработку, через 3 дня после сдачи она будет принята автоматически; время указано в autoAcceptAt (в других статусах там null). Каждая новая сдача после доработки начинает отсчёт 3 дней заново. Принять работу можно и на сайте. Если после сдачи вы напишете в чат заказа на сайте, заказ не будет принят автоматически и в autoAcceptAt будет null, пока вы не примете работу или мы не переделаем её или не вернём оплату. Ответив на ваше сообщение, мы можем также начать отсчёт 3 дней заново: тогда в autoAcceptAt появится новое время.

Ошибки

Ошибка приходит с HTTP-статусом и кодом:

{ "code": "insufficient_balance" }
СтатусКодЧто значит
400validationПоле не заполнено или заполнено неверно; список полей в fields
400link_requiredДля этой услуги нужна ссылка link
400files_requiredДля этой услуги нужен файл: создайте заказ с awaitBrief и загрузите его
400script_requiredЭта услуга читает текст вслух: передайте его в script
400script_too_longscript длиннее, чем читает пакет; maxChars в ответе — самая большая длина, которую он принимает. Деньги не списаны
400script_not_acceptedУслуга не читает текст вслух (её script в /services равно null): не передавайте script. Деньги не списаны
400files_not_accepted, file_too_largeУслуга не принимает файлы, или файл больше её maxMb
400invalid_idempotency_keyIdempotency-Key пустой, длиннее 255 символов или содержит что-то кроме печатных символов ASCII
401invalid_api_keyКлюча нет, он неверный или отозван. Ключи отзываются и тогда, когда неподтверждённый email аккаунта подтверждают входом через Google или установкой нового пароля
402insufficient_balanceНа балансе не хватает денег; ничего не списано
404package_not_found, order_not_found, file_not_foundНет такой услуги, пакета, заказа или файла
409order_not_delivered, no_revisions_leftЗаказ сейчас не в том статусе
409brief_not_expectedЗаказ не ждёт бриф: он создан без awaitBrief или бриф уже отправлен
409uploads_closedФайлы принимаются, только пока заказ ждёт бриф или сдан
409files_limitБольше файлов, чем услуга принимает с одним брифом или запросом, или больше 5 файлов или 4 ГБ на заказ
409upload_quotaВместе с этим файлом файлы заказа (и отправленные, и незавершённые загрузки) и убранные или отклонённые файлы, загрузку которых начали за последние сутки, больше 12 ГБ: повторите после retryAt
409files_not_ready, file_rejectedФайл для отправки ещё проверяется или отклонён
409upload_incompleteПо ссылке ещё ничего не загружено: закончите PUT и снова завершите загрузку
409file_in_use, file_busyФайл ушёл с брифом или запросом и остаётся в заказе, или его как раз переносит проверка: повторите чуть позже
409addon_unavailableОпция недоступна для этой услуги и пакета
409promo_not_found, promo_inactive, promo_used_up, promo_already_used, promo_first_order_only, promo_min_orderПромокода нет, он сейчас не действует, закончился, уже использован вами, подходит только для первого заказа или нужен заказ на большую сумму. Ничего не списано
409idempotency_key_in_progressЗапрос с этим Idempotency-Key ещё выполняется; повторите его чуть позже
410upload_expired, file_removedСсылка для загрузки истекла раньше, чем файл был загружен, или вы убрали файл: начните загрузку заново
415file_type_not_acceptedУказанный mime не относится к типам, которые принимает услуга
422idempotency_key_reusedЭтот Idempotency-Key уже использован с другим запросом
422upload_size_mismatch, file_type_not_acceptedЗагруженный файл не совпадает по размеру с size или по содержимому не относится к типам, которые принимает услуга; он удалён
422file_unreadable, recording_no_sound, check_failedЗавершение загрузки файла, который не прошёл проверку: он не открывается, в записи нет звука или его не удалось проверить. Загрузите файл ещё раз или другой
429rate_limitedБольше 120 запросов в минуту с одного ключа; подождите столько секунд, сколько указано в Retry-After

Возвраты

Если мы оформляем возврат по заказу, деньги возвращаются на баланс, а заказ получает статус refunded.