API
Haga pedidos de servicios desde su propio sitio web, tienda o script: consulte los servicios y sus precios, haga pedidos con la tarea, sígalos y obtenga los resultados. Es el mismo servicio que en el sitio, así que los pedidos hechos a través de la API también aparecen en su cuenta.
Primeros pasos
- Inicie sesión y abra Saldo y claves de API.
- Cree una clave. Se muestra una sola vez: cópiela y manténgala en secreto, como una contraseña. Puede revocar una clave en cualquier momento.
- Recargue el saldo. Los pedidos hechos a través de la API se pagan con él, en dólares estadounidenses.
Envíe la clave en cada solicitud:
Authorization: Bearer dlx_your_key
Dirección de la API: https://dleex.com/api/v1. Las solicitudes y las respuestas son JSON. Los precios y los importes se expresan en centavos de dólar estadounidense enteros: 1500 significa 15,00 $.
Servicios
GET /services devuelve lo que se puede pedir.
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 es lo que tarda el trabajo; revisions es cuántas veces puede solicitar cambios. addons son extras que puede pedir con los paquetes indicados en tiers: su precio se suma al del paquete, y extraDays, a su plazo (negativo: más rápido, nunca menos de 1 día). briefQuestions son las preguntas que el servicio hace sobre la tarea, algunas con una hint; respóndalas en answers al hacer un pedido. La lista está vacía cuando un servicio no pregunta nada. linkRequired es true para un servicio que se realiza a partir de lo que abre un enlace, como un perfil o una publicación, o una grabación que subtitular: un pedido de ese servicio necesita link.
files es null para un servicio que no admite archivos con el brief. Si no, indica cuáles admite, p. ej. {"accept": ["image"], "maxFiles": 3, "maxMb": 5, "required": true, "insteadOfLink": false}: los tipos (image, audio, video), cuántos archivos por brief o por solicitud de cambios, el tamaño máximo de cada archivo en MB, si el brief necesita al menos uno y si un archivo puede sustituir a link (en ese caso linkRequired sigue siendo true para los pedidos enviados sin archivos). Consulte Archivos.
script es null para un servicio que no lee ningún texto en voz alta. Un servicio de locución indica el texto más largo que lee cada paquete, en caracteres, p. ej. {"maxChars": {"basic": 1000, "standard": 3000, "premium": 9000}}: sus pedidos necesitan script, el texto que se leerá palabra por palabra. La grabación se lee con una voz sintetizada: dondequiera que la publique, indique a sus oyentes que la voz es sintetizada (consulte los Términos).
Saldo
GET /balance
{ "balanceUsdCents": 10000, "currency": "USD" }
Hacer un pedido
POST /orders. El precio (el paquete y los extras, menos cualquier descuento) se descuenta del saldo y el trabajo comienza de inmediato.
| Campo | ||
|---|---|---|
service | obligatorio | Servicio de /services |
tier | obligatorio | basic, standard o premium |
text | obligatorio sin answers, script ni awaitBrief | La tarea: qué hacer, hasta 10 000 caracteres. Con script: cómo leerlo (tono, ritmo, cómo pronunciar los nombres) |
link | opcional | Un enlace a la página, el perfil o la publicación, o a una grabación: un enlace directo al archivo, o un enlace de Dropbox o Yandex Disk. Obligatorio cuando linkRequired es true |
answers | opcional | Respuestas a las briefQuestions del servicio: [{"q": "question", "a": "answer"}], hasta 8, cada respuesta de hasta 5000 caracteres |
script | obligatorio cuando script en /services no es null, rechazado en los demás casos | El texto que se leerá en voz alta, palabra por palabra, hasta el maxChars del paquete (como máximo 20 000 caracteres; un salto de línea cuenta como uno). Deje una línea en blanco entre párrafos |
locale | opcional | Idioma del resultado, en o ru. Por defecto, el idioma de su cuenta |
addons | opcional | Ids de los extras de /services ofrecidos para este nivel, p. ej. [7] |
promoCode | opcional | Un código promocional; si no se aplica, el pedido no se realiza (consulte Errores) |
awaitBrief | opcional | true para enviar el brief más tarde, después de subir los archivos: el pedido se paga y queda en espera como awaiting_brief. En ese caso, omita text, link, answers y script. Consulte Archivos |
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 es opcional y le permite repetir la solicitud de forma segura; cada pedido nuevo necesita una clave nueva. Consulte Idempotencia más abajo.
Indique text o al menos una respuesta, o ambos; para una locución basta con script. Escriba cada pregunta en q tal como aparece en briefQuestions, en el idioma del pedido, y omita aquellas a las que no tenga respuesta:
{
"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 respuesta es el pedido (estado 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": []
}
Archivos
Algunos servicios trabajan a partir de archivos del cliente, como imágenes de páginas que transcribir o una grabación que subtitular: su files en /services no es null. Los archivos se suben a un pedido que espera su brief:
- Haga el pedido con
"awaitBrief": truey sintext,link,answersniscript. Se paga de inmediato y su estado esawaiting_brief; el plazo empieza a contar con el brief. - Para cada archivo,
POST /orders/{id}/filescon{"name": "page-1.png", "size": 482113, "mime": "image/png"}:sizees el tamaño exacto en bytes ymimees opcional. La respuesta (201) es el archivo y el lugar donde subirlo:
{
"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" }
}
- Envíe con
PUTlos bytes del archivo aupload.urlcon exactamente losheadersindicados y sin clave de API, antes deupload.expiresAt(una hora):
curl -X PUT "$url" -H "content-type: application/octet-stream" --data-binary @page-1.png
POST /orders/{id}/files/{fileId}/complete. Un archivo de un tamaño distinto desize, o cuyos bytes no sean de un tipo incluido enaccept, se rechaza con422y se elimina: el nombre ymimeno cuentan. Si no, la respuesta es el archivo, ahora enchecking. Al cabo de unos segundos, o de unos minutos si es una grabación larga, pasa aready, o arejectedcon el motivo enreason, p. ej.recording_no_soundofile_unreadable. Elfilesdel pedido muestra en qué estado están.POST /orders/{id}/briefcontext,link,answersyscriptcomo enPOST /orders. Los archivos listos que aún no se han enviado van con él, o bien indique enfileIdslos que quiere enviar. Mientras alguno de ellos siga enchecking, el brief se rechaza con409 files_not_ready: vuelva a enviarlo un poco más tarde. La respuesta (200) es el pedido, ahora enin_progress.
DELETE /orders/{id}/files/{fileId} retira un archivo que aún no se ha enviado. Un pedido admite como máximo 5 archivos y 4 GB en total; un archivo cuya subida se ha iniciado cuenta hasta que se completa o se retira, y durante un día desde el inicio de su subida, los archivos retirados o rechazados cuentan para un límite de 12 GB junto con los archivos del pedido: por encima de ese límite, la subida se rechaza con 409 upload_quota y retryAt, el momento en que se vuelve a admitir. Un pedido entregado también admite archivos para una solicitud de cambios: súbalos de la misma manera y luego envíe fileIds con la solicitud.
Sin awaitBrief, un pedido de un servicio cuyos archivos son required se rechaza con 400 files_required, y uno en el que un archivo puede sustituir al enlace, enviado sin enlace, con 400 link_required.
En el pedido, files enumera sus archivos con su status, y fileIds, los que se enviaron con el brief. Un archivo listo tiene una url que funciona hasta expiresAt, igual que los archivos de resultados. Los archivos se conservan durante 30 días después de cerrarse el pedido.
Idempotencia
Una solicitud puede agotar el tiempo de espera después de que el pedido ya se haya realizado. Para repetir POST /orders sin pagar dos veces, envíe con ella un encabezado Idempotency-Key: una cadena de 1 a 255 caracteres ASCII imprimibles que usted elige una vez por pedido, como un UUID o su propio número de pedido. Envíe la misma clave y el mismo cuerpo al repetir la solicitud.
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 ya se realizó un pedido con esta clave, la respuesta es ese pedido en su estado actual, con el estado 201 y un encabezado más. No se cobra nada de nuevo:
HTTP/1.1 201 Created
Idempotent-Replayed: true
- La clave pertenece a la solicitud con la que se envió por primera vez. La misma clave con un cuerpo diferente, por ejemplo con otros extras u otro código promocional, se rechaza con
422 idempotency_key_reused, y no se cobra nada. - Si llegan a la vez varias solicitudes con una misma clave, se realiza un solo pedido y las demás responden con él. Una solicitud que tenga que esperar demasiado responde
409 idempotency_key_in_progressy no cobra nada: repítala un momento después. - Una solicitud que ha fallado, por ejemplo con
400,402,404o un error de extra o de código promocional, no agota su clave: corríjala y vuelva a enviarla con la misma clave. - Una clave se conserva durante 24 horas. Pasado ese tiempo, la misma clave realiza un pedido nuevo.
- Las claves son independientes para cada cuenta. Sin el encabezado, cada solicitud realiza un pedido nuevo.
Aceptar el trabajo, enviar briefs y solicitar cambios no llevan clave. Aceptar se puede repetir sin riesgo: una vez completado el pedido, una repetición responde 409 order_not_delivered. Lo mismo ocurre con un brief: una vez aceptado, una repetición responde 409 brief_not_expected y el pedido está en in_progress. Una solicitud de cambios es distinta: mientras se rehace el trabajo, una repetición responde 409 order_not_delivered, pero una vez entregado el trabajo rehecho, una repetición solicita otros cambios. Antes de repetir una solicitud de cambios, compruebe el pedido con GET /orders/{id} (status y revisionsLeft).
Seguimiento de pedidos
GET /orders/{id} devuelve un pedido, GET /orders, sus pedidos, del más reciente al más antiguo. La lista admite status, limit (de 1 a 100, 20 por defecto) y before (un id de pedido, para obtener pedidos más antiguos).
Estado del pedido:
| Estado | Significado |
|---|---|
awaiting_brief | Realizado con awaitBrief: en espera de POST /orders/{id}/brief |
in_progress | El trabajo está en curso |
quality_check | El trabajo está terminado y se está revisando antes de la entrega |
delivered | El resultado está listo, consulte results. Acéptelo o solicite cambios antes de autoAcceptAt |
revision | Se están haciendo los cambios que solicitó |
completed | Usted aceptó el resultado, o se aceptó automáticamente |
refunded | El dinero volvió a su saldo |
Consulte cada pocos minutos; no hace falta hacerlo con más frecuencia. Cuando el pedido está en delivered, results contiene el trabajo: kind es text (Markdown), report (un informe de entrega para pedidos de redes sociales) o files (archivos para descargar, con una nota opcional en body). Cada resultado tiene una lista files, vacía para textos e informes: cada archivo tiene name, mime, size en bytes y una url que funciona hasta expiresAt, aproximadamente una hora. Vuelva a leer el pedido para obtener enlaces nuevos. El enlace puede redirigir al almacenamiento de archivos, así que siga las redirecciones, p. ej. curl -L -o result.png "$url", y no envíe la clave de API con él: el enlace por sí solo abre el archivo.
Aceptación y cambios
POST /orders/{id}/acceptacepta el resultado y completa el pedido.POST /orders/{id}/revisioncon{"text": "what to change"}solicita cambios, mientrasrevisionsLeftsea mayor que cero. Cuando el servicio admite archivos,fileIdsindica los archivos subidos para la solicitud; si se omite, se envían con ella los archivos listos que aún no se han enviado.
Si no acepta ni solicita cambios en un pedido entregado, este se acepta automáticamente 3 días después de la entrega, en el momento indicado en autoAcceptAt (null en los demás estados). Una nueva entrega tras unos cambios reinicia los 3 días. También puede aceptar el trabajo en el sitio. Si escribe en el chat del pedido en el sitio después de la entrega, el pedido no se acepta automáticamente y autoAcceptAt es null hasta que usted lo acepte o nosotros rehagamos el trabajo o lo reembolsemos. Después de responder a su mensaje, también podemos reiniciar los 3 días: autoAcceptAt muestra entonces el nuevo momento.
Errores
Los errores llegan con un estado HTTP y un código:
{ "code": "insufficient_balance" }
| Estado | Código | Significado |
|---|---|---|
| 400 | validation | Falta un campo o es incorrecto; fields los enumera |
| 400 | link_required | Este servicio necesita link |
| 400 | files_required | Este servicio necesita un archivo: haga el pedido con awaitBrief y súbalo |
| 400 | script_required | Este servicio lee un texto en voz alta: envíelo en script |
| 400 | script_too_long | script es más largo de lo que lee el paquete; maxChars en la respuesta es el máximo que admite. No se ha cobrado nada |
| 400 | script_not_accepted | El servicio no lee ningún texto en voz alta (su script en /services es null): omita script. No se ha cobrado nada |
| 400 | files_not_accepted, file_too_large | El servicio no admite archivos, o el archivo supera su maxMb |
| 400 | invalid_idempotency_key | Idempotency-Key está vacío, supera los 255 caracteres o no es ASCII imprimible |
| 401 | invalid_api_key | No hay clave, la clave es incorrecta o está revocada. Las claves también se revocan cuando el correo electrónico sin confirmar de la cuenta se confirma al iniciar sesión con Google o al establecer una contraseña nueva |
| 402 | insufficient_balance | No hay suficiente dinero en el saldo; no se ha cobrado nada |
| 404 | package_not_found, order_not_found, file_not_found | No existe ese servicio, paquete, pedido o archivo |
| 409 | order_not_delivered, no_revisions_left | El pedido no está en un estado que lo permita |
| 409 | brief_not_expected | El pedido no espera su brief: se realizó sin awaitBrief, o su brief ya se envió |
| 409 | uploads_closed | Solo se admiten archivos mientras el pedido espera su brief o está entregado |
| 409 | files_limit | Más archivos de los que admite el servicio por brief o solicitud, o más de 5 archivos o 4 GB para el pedido |
| 409 | upload_quota | Con este, los archivos del pedido (incluidos los enviados y las subidas sin terminar) y los iniciados en el último día y después retirados o rechazados superan los 12 GB: vuelva a intentarlo después de retryAt |
| 409 | files_not_ready, file_rejected | Un archivo que enviar aún se está revisando, o fue rechazado |
| 409 | upload_incomplete | Todavía no se ha subido nada al enlace: termine el PUT y vuelva a completar la subida |
| 409 | file_in_use, file_busy | El archivo se envió con el brief o con una solicitud y permanece en el pedido, o su revisión lo está moviendo: vuelva a intentarlo en un momento |
| 409 | addon_unavailable | Un extra no se ofrece para este servicio y nivel |
| 409 | promo_not_found, promo_inactive, promo_used_up, promo_already_used, promo_first_order_only, promo_min_order | El código promocional no existe, no está activo ahora, se ha agotado, ya lo ha usado usted, es solo para un primer pedido o requiere un pedido mayor. No se ha cobrado nada |
| 409 | idempotency_key_in_progress | Una solicitud con este Idempotency-Key todavía se está procesando; repítala un momento después |
| 410 | upload_expired, file_removed | El enlace de subida caducó antes de que se subiera nada, o usted retiró el archivo: inicie una nueva subida |
| 415 | file_type_not_accepted | El mime indicado no es de un tipo que admita el servicio |
| 422 | idempotency_key_reused | Este Idempotency-Key ya se usó con una solicitud diferente |
| 422 | upload_size_mismatch, file_type_not_accepted | El archivo subido no tiene el tamaño indicado en size, o sus bytes no son de un tipo que admita el servicio; se ha eliminado |
| 422 | file_unreadable, recording_no_sound, check_failed | Al completar un archivo que la revisión rechazó: no se abre, la grabación no tiene sonido o no se pudo revisar. Vuelva a subir el archivo u otro distinto |
| 429 | rate_limited | Más de 120 solicitudes por minuto con una misma clave; espere los segundos indicados en Retry-After |
Reembolsos
Si reembolsamos un pedido, el dinero vuelve al saldo y el pedido pasa a refunded.