API

Đặt dịch vụ ngay từ website, cửa hàng hoặc script của bạn: xem danh sách dịch vụ và giá, đặt đơn hàng kèm nhiệm vụ, theo dõi và nhận kết quả. Đây chính là dịch vụ như trên website, nên các đơn hàng đặt qua API cũng hiển thị trong tài khoản của bạn.

Bắt đầu

  1. Đăng nhập và mở Số dư và khóa API.
  2. Tạo một khóa. Khóa chỉ hiển thị một lần: hãy sao chép và giữ bí mật như mật khẩu. Bạn có thể thu hồi khóa bất cứ lúc nào.
  3. Nạp tiền vào số dư. Các đơn hàng đặt qua API được thanh toán từ số dư, bằng đô la Mỹ.

Gửi khóa kèm theo mỗi yêu cầu:

Authorization: Bearer dlx_your_key

Địa chỉ API: https://dleex.com/api/v1. Yêu cầu và phản hồi đều ở định dạng JSON. Giá và số tiền được tính bằng số nguyên cent Mỹ: 1500 nghĩa là $15.00.

Dịch vụ

GET /services trả về danh sách những gì có thể đặt.

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 là thời gian thực hiện công việc; revisions là số lần bạn có thể yêu cầu chỉnh sửa. addons là các tùy chọn thêm có thể đặt cùng những gói trong tiers: giá của tùy chọn được cộng vào giá gói, còn extraDays được cộng vào thời hạn của gói (số âm: nhanh hơn, nhưng không bao giờ dưới 1 ngày). briefQuestions là những câu hỏi dịch vụ đặt ra về nhiệm vụ, một số có kèm hint; hãy trả lời chúng trong answers khi đặt đơn hàng. Danh sách sẽ trống nếu dịch vụ không hỏi gì. linkRequired là true đối với dịch vụ được thực hiện dựa trên nội dung mà một liên kết mở ra, chẳng hạn hồ sơ hoặc bài đăng, hay bản ghi âm/ghi hình cần làm phụ đề: đơn hàng của dịch vụ đó cần có link.

files là null đối với dịch vụ không nhận tệp kèm bản yêu cầu. Nếu không, trường này cho biết dịch vụ nhận những tệp nào, ví dụ {"accept": ["image"], "maxFiles": 3, "maxMb": 5, "required": true, "insteadOfLink": false}: các loại tệp (image, audio, video), số tệp tối đa kèm một bản yêu cầu hoặc một yêu cầu chỉnh sửa, dung lượng tối đa của mỗi tệp tính bằng MB, bản yêu cầu có bắt buộc phải có ít nhất một tệp hay không, và tệp có thể thay thế cho link hay không (khi đó linkRequired vẫn là true đối với các đơn hàng gửi không kèm tệp). Xem mục Tệp.

script là null đối với dịch vụ không đọc văn bản thành tiếng. Dịch vụ lồng tiếng có độ dài văn bản tối đa mà mỗi gói đọc, tính bằng ký tự, ví dụ {"maxChars": {"basic": 1000, "standard": 3000, "premium": 9000}}: đơn hàng của dịch vụ này cần có script, tức văn bản cần đọc nguyên văn từng chữ. Bản ghi được đọc bằng giọng tổng hợp: dù bạn đăng ở đâu, hãy cho người nghe biết đó là giọng tổng hợp (xem Điều khoản).

Số dư

GET /balance

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

Đặt đơn hàng

POST /orders. Giá (gói và các tùy chọn thêm, trừ đi khoản giảm giá nếu có) được trừ vào số dư và công việc bắt đầu ngay lập tức.

Trường
servicebắt buộcDịch vụ từ /services
tierbắt buộcbasic, standard hoặc premium
textbắt buộc nếu không có answers, script hoặc awaitBriefNhiệm vụ: cần làm gì, tối đa 10.000 ký tự. Khi có script: cách đọc (giọng điệu, tốc độ, cách phát âm tên riêng)
linktùy chọnLiên kết đến trang, hồ sơ hoặc bài đăng, hoặc đến một bản ghi: liên kết trực tiếp đến tệp, hoặc liên kết Dropbox hay Yandex Disk. Bắt buộc khi linkRequired là true
answerstùy chọnCâu trả lời cho briefQuestions của dịch vụ: [{"q": "question", "a": "answer"}], tối đa 8 câu, mỗi câu trả lời tối đa 5.000 ký tự
scriptbắt buộc khi script trong /services không phải null, bị từ chối trong các trường hợp khácVăn bản cần đọc thành tiếng, nguyên văn từng chữ, tối đa bằng maxChars của gói (không quá 20.000 ký tự, mỗi dấu xuống dòng tính là một ký tự). Để một dòng trống giữa các đoạn
localetùy chọnNgôn ngữ của kết quả, en hoặc ru. Mặc định là ngôn ngữ tài khoản của bạn
addonstùy chọnId của các tùy chọn thêm từ /services được cung cấp cho gói này, ví dụ [7]
promoCodetùy chọnMã khuyến mãi; nếu mã không áp dụng được, đơn hàng sẽ không được đặt (xem mục Lỗi)
awaitBrieftùy chọntrue để gửi bản yêu cầu sau, khi đã tải tệp lên: đơn hàng được thanh toán và chờ ở trạng thái awaiting_brief. Khi đó, bỏ qua text, link, answers và script. Xem mục Tệp
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 không bắt buộc và cho phép bạn lặp lại yêu cầu một cách an toàn; mỗi đơn hàng mới cần một khóa mới. Xem mục Tính lũy đẳng bên dưới.

Hãy cung cấp text hoặc ít nhất một câu trả lời, hoặc cả hai; với dịch vụ lồng tiếng, chỉ cần script là đủ. Ghi mỗi câu hỏi trong q đúng như trong briefQuestions, bằng ngôn ngữ của đơn hàng, và bỏ qua những câu bạn không có câu trả lời:

{
  "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" }
  ]
}

Phản hồi là đơn hàng (mã trạng thái 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": []
}

Tệp

Một số dịch vụ làm việc dựa trên tệp của khách hàng, chẳng hạn ảnh chụp các trang cần đánh máy lại hoặc bản ghi cần làm phụ đề: files của các dịch vụ này trong /services không phải null. Tệp được tải lên cho một đơn hàng đang chờ bản yêu cầu:

  1. Đặt đơn hàng với "awaitBrief": true và không kèm text, link, answers và script. Đơn hàng được thanh toán ngay và có trạng thái awaiting_brief; thời hạn bắt đầu tính từ khi có bản yêu cầu.
  2. Với mỗi tệp, gọi POST /orders/{id}/files với {"name": "page-1.png", "size": 482113, "mime": "image/png"}: size là kích thước chính xác tính bằng byte, mime không bắt buộc. Phản hồi (201) là tệp và nơi để tải tệp lên:
{
  "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. Gửi PUT nội dung tệp đến upload.url với đúng các headers đã cho và không kèm khóa API, trước thời điểm upload.expiresAt (một giờ):
curl -X PUT "$url" -H "content-type: application/octet-stream" --data-binary @page-1.png
  1. Gọi POST /orders/{id}/files/{fileId}/complete. Tệp có kích thước khác với size, hoặc có nội dung không thuộc loại nào trong accept, sẽ bị từ chối với 422 và bị xóa: tên tệp và mime không được tính đến. Nếu không, phản hồi là tệp, lúc này ở trạng thái checking. Sau vài giây, hoặc vài phút với bản ghi dài, tệp chuyển sang ready, hoặc rejected kèm lý do trong reason, ví dụ recording_no_sound hoặc file_unreadable. Trường files của đơn hàng cho biết tình trạng của các tệp.
  2. Gọi POST /orders/{id}/brief với text, link, answers và script như trong POST /orders. Các tệp đã sẵn sàng nhưng chưa được gửi sẽ đi kèm, hoặc bạn liệt kê các tệp cần gửi trong fileIds. Khi còn một tệp đang ở trạng thái checking, bản yêu cầu bị từ chối với 409 files_not_ready: hãy gửi lại sau ít phút. Phản hồi (200) là đơn hàng, lúc này ở trạng thái in_progress.

DELETE /orders/{id}/files/{fileId} rút lại một tệp chưa được gửi. Một đơn hàng nhận tối đa 5 tệp và tổng cộng 4 GB; tệp đã bắt đầu tải lên được tính cho đến khi hoàn tất hoặc bị rút lại, và trong một ngày kể từ lúc bắt đầu tải lên, các tệp đã rút lại hoặc bị từ chối được tính vào giới hạn 12 GB cùng với các tệp của đơn hàng: vượt quá mức đó, việc tải lên bị từ chối với 409 upload_quota và retryAt, thời điểm có thể tải lên lại. Đơn hàng đã bàn giao cũng nhận tệp cho yêu cầu chỉnh sửa: tải tệp lên theo cách tương tự, rồi gửi fileIds kèm yêu cầu.

Nếu không có awaitBrief, đơn hàng của dịch vụ có tệp là required sẽ bị từ chối với 400 files_required, còn đơn hàng của dịch vụ cho phép tệp thay thế liên kết mà gửi không kèm liên kết sẽ bị từ chối với 400 link_required.

Trong đơn hàng, files liệt kê các tệp của bạn cùng status của chúng, còn fileIds là các tệp đã đi kèm bản yêu cầu. Tệp đã sẵn sàng có url dùng được đến expiresAt, giống như tệp kết quả. Tệp được lưu trong 30 ngày sau khi đơn hàng đóng.

Tính lũy đẳng

Một yêu cầu có thể hết thời gian chờ sau khi đơn hàng đã được đặt. Để lặp lại POST /orders mà không phải trả tiền hai lần, hãy gửi kèm header Idempotency-Key: một chuỗi từ 1 đến 255 ký tự ASCII in được mà bạn chọn một lần cho mỗi đơn hàng, chẳng hạn UUID hoặc mã đơn hàng của riêng bạn. Khi lặp lại yêu cầu, hãy gửi cùng khóa và cùng nội dung.

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: ..."}'

Nếu đã có đơn hàng được đặt với khóa này, phản hồi là đơn hàng đó ở trạng thái hiện tại, với mã trạng thái 201 và thêm một header. Không có khoản nào bị trừ thêm:

HTTP/1.1 201 Created
Idempotent-Replayed: true

Việc chấp nhận kết quả, gửi bản yêu cầu và yêu cầu chỉnh sửa không dùng khóa. Chấp nhận kết quả có thể lặp lại an toàn: khi đơn hàng đã hoàn tất, yêu cầu lặp lại sẽ phản hồi 409 order_not_delivered. Bản yêu cầu cũng vậy: khi đã gửi thành công, yêu cầu lặp lại sẽ phản hồi 409 brief_not_expected và đơn hàng ở trạng thái in_progress. Yêu cầu chỉnh sửa thì khác: trong khi công việc đang được làm lại, yêu cầu lặp lại sẽ phản hồi 409 order_not_delivered, nhưng khi bản làm lại đã được bàn giao, yêu cầu lặp lại sẽ yêu cầu thêm một lần chỉnh sửa nữa. Trước khi lặp lại yêu cầu chỉnh sửa, hãy kiểm tra đơn hàng bằng GET /orders/{id} (status và revisionsLeft).

Theo dõi đơn hàng

GET /orders/{id} trả về một đơn hàng, GET /orders trả về các đơn hàng của bạn, mới nhất trước. Danh sách nhận status, limit (từ 1 đến 100, mặc định 20) và before (id đơn hàng, để lấy các đơn hàng cũ hơn).

Trạng thái đơn hàng:

Trạng tháiÝ nghĩa
awaiting_briefĐặt với awaitBrief: đang chờ POST /orders/{id}/brief
in_progressCông việc đang được thực hiện
quality_checkCông việc đã xong và đang được kiểm tra trước khi bàn giao
deliveredKết quả đã sẵn sàng, xem results. Hãy chấp nhận kết quả hoặc yêu cầu chỉnh sửa trước autoAcceptAt
revisionCác chỉnh sửa bạn yêu cầu đang được thực hiện
completedBạn đã chấp nhận kết quả, hoặc kết quả đã được chấp nhận tự động
refundedTiền đã được hoàn về số dư của bạn

Hãy kiểm tra vài phút một lần; không cần kiểm tra thường xuyên hơn. Khi đơn hàng ở trạng thái delivered, results chứa kết quả công việc: kind là text (Markdown), report (báo cáo bàn giao cho các đơn hàng mạng xã hội) hoặc files (tệp để tải xuống, có thể kèm ghi chú trong body). Mỗi kết quả có danh sách files, trống đối với văn bản và báo cáo: mỗi tệp có name, mime, size tính bằng byte và url dùng được đến expiresAt, khoảng một giờ. Hãy đọc lại đơn hàng để nhận liên kết mới. Liên kết có thể chuyển hướng đến kho lưu trữ tệp, vì vậy hãy theo các chuyển hướng, ví dụ curl -L -o result.png "$url", và không gửi khóa API kèm theo: chỉ riêng liên kết đã mở được tệp.

Chấp nhận kết quả và chỉnh sửa

Nếu bạn không chấp nhận cũng không yêu cầu chỉnh sửa một đơn hàng đã bàn giao, đơn hàng sẽ được chấp nhận tự động 3 ngày sau khi bàn giao, vào thời điểm ghi trong autoAcceptAt (null ở các trạng thái khác). Lần bàn giao mới sau khi chỉnh sửa sẽ tính lại 3 ngày từ đầu. Bạn cũng có thể chấp nhận kết quả trên website. Nếu bạn nhắn tin trong phần trò chuyện của đơn hàng trên website sau khi bàn giao, đơn hàng sẽ không được chấp nhận tự động và autoAcceptAt là null cho đến khi bạn chấp nhận kết quả hoặc chúng tôi làm lại hay hoàn tiền. Sau khi trả lời tin nhắn của bạn, chúng tôi cũng có thể tính lại 3 ngày từ đầu: khi đó autoAcceptAt sẽ hiển thị thời điểm mới.

Lỗi

Lỗi được trả về kèm mã trạng thái HTTP và mã lỗi:

{ "code": "insufficient_balance" }
Trạng tháiMãÝ nghĩa
400validationMột trường bị thiếu hoặc sai; fields liệt kê các trường đó
400link_requiredDịch vụ này cần link
400files_requiredDịch vụ này cần tệp: hãy đặt đơn hàng với awaitBrief và tải tệp lên
400script_requiredDịch vụ này đọc văn bản thành tiếng: hãy gửi văn bản trong script
400script_too_longscript dài hơn mức gói đọc; maxChars trong phản hồi là độ dài tối đa được nhận. Không có khoản nào bị trừ
400script_not_acceptedDịch vụ không đọc văn bản thành tiếng (script của dịch vụ trong /services là null): hãy bỏ script. Không có khoản nào bị trừ
400files_not_accepted, file_too_largeDịch vụ không nhận tệp, hoặc tệp lớn hơn maxMb của dịch vụ
400invalid_idempotency_keyIdempotency-Key trống, dài hơn 255 ký tự hoặc không phải ASCII in được
401invalid_api_keyKhông có khóa, khóa sai hoặc khóa đã bị thu hồi. Khóa cũng bị thu hồi khi email chưa xác nhận của tài khoản được xác nhận bằng cách đăng nhập với Google hoặc đặt mật khẩu mới
402insufficient_balanceSố dư không đủ; không có khoản nào bị trừ
404package_not_found, order_not_found, file_not_foundKhông tồn tại dịch vụ, gói, đơn hàng hoặc tệp như vậy
409order_not_delivered, no_revisions_leftĐơn hàng không ở trạng thái cho phép thao tác này
409brief_not_expectedĐơn hàng không chờ bản yêu cầu: đơn được đặt không kèm awaitBrief, hoặc bản yêu cầu đã được gửi
409uploads_closedChỉ nhận tệp khi đơn hàng đang chờ bản yêu cầu hoặc đã được bàn giao
409files_limitNhiều tệp hơn số dịch vụ nhận kèm một bản yêu cầu hoặc một yêu cầu, hoặc vượt quá 5 tệp hay 4 GB cho đơn hàng
409upload_quotaTính cả tệp này, các tệp của đơn hàng (kể cả tệp đã gửi và các lượt tải lên chưa hoàn tất) cùng các tệp bắt đầu tải lên trong ngày qua rồi bị rút lại hoặc bị từ chối vượt quá 12 GB: hãy thử lại sau retryAt
409files_not_ready, file_rejectedMột tệp cần gửi vẫn đang được kiểm tra, hoặc đã bị từ chối
409upload_incompleteChưa có gì được tải lên liên kết: hãy hoàn tất PUT, rồi hoàn tất lượt tải lên lần nữa
409file_in_use, file_busyTệp đã đi kèm bản yêu cầu hoặc một yêu cầu và được giữ lại cùng đơn hàng, hoặc đang được di chuyển trong quá trình kiểm tra: hãy thử lại sau giây lát
409addon_unavailableTùy chọn thêm không được cung cấp cho dịch vụ và gói này
409promo_not_found, promo_inactive, promo_used_up, promo_already_used, promo_first_order_only, promo_min_orderMã khuyến mãi không tồn tại, hiện không hoạt động, đã hết lượt, bạn đã dùng rồi, chỉ dành cho đơn hàng đầu tiên, hoặc cần đơn hàng có giá trị lớn hơn. Không có khoản nào bị trừ
409idempotency_key_in_progressMột yêu cầu với Idempotency-Key này vẫn đang được xử lý; hãy lặp lại sau giây lát
410upload_expired, file_removedLiên kết tải lên đã hết hạn trước khi có gì được tải lên, hoặc bạn đã rút lại tệp: hãy bắt đầu một lượt tải lên mới
415file_type_not_acceptedmime đã cho không thuộc loại mà dịch vụ nhận
422idempotency_key_reusedIdempotency-Key này đã được dùng cho một yêu cầu khác
422upload_size_mismatch, file_type_not_acceptedTệp đã tải lên không có kích thước bằng size, hoặc nội dung của tệp không thuộc loại mà dịch vụ nhận; tệp đã bị xóa
422file_unreadable, recording_no_sound, check_failedHoàn tất một tệp mà quá trình kiểm tra đã từ chối: tệp không mở được, bản ghi không có âm thanh, hoặc không thể kiểm tra tệp. Hãy tải lại tệp đó hoặc một tệp khác
429rate_limitedVượt quá 120 yêu cầu mỗi phút với một khóa; hãy chờ số giây ghi trong Retry-After

Hoàn tiền

Nếu chúng tôi hoàn tiền một đơn hàng, tiền sẽ được trả về số dư và đơn hàng chuyển sang trạng thái refunded.