Solicitudes
Una solicitud es una llamada a un modelo. Tiene un id (req_…), un estado, su costo en créditos de API (1000 = 1 USD) y, cuando tiene éxito, los archivos generados. El mismo objeto se devuelve desde cada endpoint siguiente, para cada modelo.
Buscar un modelo
El catálogo de los 1496 modelos es JSON público (no se necesita una clave):
curl "https://api.doitong.ru/v1/models?category=text-to-video&lab=Google&limit=20"
| Parámetro de consulta | Significado |
|---|---|
q |
Palabras que deben aparecer todas en el nombre, id, fabricante o etiquetas; por ejemplo, kling 3. |
category |
Un id de categoría, por ejemplo, text-to-video o upscale. GET https://api.doitong.ru/v1/categories muestra las 21 categorías con sus recuentos. |
lab |
El fabricante del modelo, por nombre o id; por ejemplo, Google o black-forest-labs. |
family |
Un id de family de una fila anterior: cada variante de un modelo (pro, fast, image-to-video, …). |
mode |
exact (el precio se calcula a partir de la entrada), measured (a partir de la duración o el tamaño de los archivos de entrada), estimate (un precio estimado por ejecución) o metered (se cobra según el uso real, hasta un máximo por ejecución). |
limit, cursor |
Tamaño de página (de 1 a 100, predeterminado 50) y el next_cursor de la página anterior. |
Cada fila tiene id, name, lab, category, family, summary, tags, output_kind, docs_url y un objeto price (consulta Precios). GET https://api.doitong.ru/v1/models/{model_id} añade el esquema JSON completo de entrada y salida, los nombres canónicos de los parámetros, las reglas de precios y un ejemplo de entrada. Una category o un mode desconocidos devuelven 400 invalid_parameter.
Ejecutar un modelo
curl -X POST "https://api.doitong.ru/v1/run/{model_id}?wait=20" \
-H "Authorization: Bearer $DOITONG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1842-cover" \
-d '{"prompt": "..."}'
- El cuerpo es la entrada del modelo, un objeto JSON. Cada página de modelo enumera sus parámetros.
- La entrada se valida antes de cobrar nada. Una entrada no válida devuelve
422 invalid_inputcon elparamproblemático y no cuesta nada. ?wait=N(hasta 20 segundos) mantiene la llamada abierta hasta que finaliza la solicitud o se agota el tiempo.?webhook_url=https://…envía un POST firmado a esa URL cuando finaliza la solicitud (consulta Webhooks).?storage=permanento?storage=temporarydetermina cuánto tiempo se conservan los archivos de salida; sin este parámetro se aplica la configuración de la cuenta (consulta Dónde se guardan los archivos).
La respuesta es 202 Accepted mientras la solicitud sigue procesándose y 200 OK cuando finalizó durante la espera (o cuando es una reproducción, consulta más abajo). Los encabezados Location y Doitong-Request-Id contienen la URL y el id de la solicitud.
Estados
-
queuedAceptada y cobrada; esperando un worker -
runningEl modelo está generando -
Estados finales:
succeededSe ha cobrado el presupuesto; outputs[] contiene las URL de nuestro almacenamientofailedReembolsada automáticamente; el error indica el motivocanceledDetenida antes de obtener un resultado; reembolsada
| Estado | Significado | Final |
|---|---|---|
queued |
Aceptada y cobrada; espera a un trabajador. queue_position puede mostrar su posición en la cola. |
no |
running |
El modelo está generando. | no |
succeeded |
Lista. outputs enumera los archivos. |
sí |
failed |
El modelo o un límite la detuvo. error indica el motivo. Los créditos de API se reembolsan. |
sí |
canceled |
Cancelada antes de producir un resultado. Los créditos de API se reembolsan. | sí |
Una solicitud que supera su límite de tiempo falla con el código timeout y se reembolsa: 15 minutos para imágenes, 60 minutos para video, 30 minutos para audio y todo lo demás.
El objeto de solicitud
{
"id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
"object": "request",
"model": "flux/schnell",
"status": "succeeded",
"created_at": "2026-10-20T12:00:00Z",
"started_at": "2026-10-20T12:00:01Z",
"completed_at": "2026-10-20T12:00:02Z",
"queue_position": null,
"cost": { "credits": 3, "usd": "0.003", "charged": 3, "refunded": 0 },
"input": { "prompt": "..." },
"output": { "images": [ { "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "width": 1024, "height": 768 } ] },
"outputs": [
{ "type": "image", "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "content_type": "image/jpeg",
"width": 1024, "height": 768, "file_size": 183920, "stored": true }
],
"error": null,
"metrics": { "inference_seconds": 1.2 },
"storage": { "mode": "permanent", "bytes": 183920, "expires_at": null, "expired": false },
"urls": {
"self": "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
"cancel": "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
}
}
outputses igual para todos los modelos: una entrada por cada archivo generado contype(image,video,audio,fileo3d), unaurlen nuestro almacenamiento,content_typey, cuando se conocen,file_size,width,height,duration.outputes el propio objeto de resultado del modelo (sus campos se enumeran en cada página de modelo) con las mismas URL.storageindica cómo se conservan los archivos:mode(permanentotemporary),bytesalmacenados,expires_at(cuándo se elimina un archivo temporal,nullpara los permanentes) yexpired(truecuando los archivos ya no están disponibles).cost.creditses el precio de la llamada en créditos de API (cost.usden USD),cost.chargedes lo debitado del saldo de API ycost.refundedlo que se devolvió. Para un modelometered,cost.creditses el máximo retenido al inicio (cost.held); cuando la ejecución tiene éxito,cost.settledindica a cuánto ascendió el uso y el resto del máximo aparece encost.refunded(consulta Cobro según el uso).- Cuando falla una solicitud,
errores{ "type": …, "code": …, "message": … }.
Leer una solicitud
curl "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t?wait=20" \
-H "Authorization: Bearer $DOITONG_API_KEY"
?wait=N(hasta 20 segundos) hace una espera prolongada: la llamada devuelve la respuesta en cuanto la solicitud es final, o después de N segundos con el estado actual. Repetir esta llamada es la forma más sencilla de esperar un resultado.?logs=1añade las líneas del registro de progreso del modelo (las últimas 50) comologs.
Solo puedes leer solicitudes de tu propia cuenta; cualquier otro id devuelve 404 request_not_found.
Enumerar solicitudes
curl "https://api.doitong.ru/v1/requests?limit=20&status=succeeded&model=flux/schnell" \
-H "Authorization: Bearer $DOITONG_API_KEY"
De más reciente a más antigua. limit va de 1 a 100 (predeterminado 20); status y model filtran los resultados. La respuesta es { "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }; pasa cursor=<next_cursor> para obtener la página siguiente.
Cancelar una solicitud
curl -X POST "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel" \
-H "Authorization: Bearer $DOITONG_API_KEY"
- Cancelada antes de que comenzara el modelo: el estado pasa a ser
canceled, los créditos de API se reembolsan y recibes200. - Ya está generando: la cancelación se transmite y recibes
202con"cancel_requested": true. Si el modelo termina de todos modos, la solicitud tiene éxito normalmente y se cobra. - Ya es final:
409 not_cancelable(una solicitud que ya estácanceledsimplemente devuelve200).
Eliminar los archivos de una solicitud
curl -X DELETE "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/files" \
-H "Authorization: Bearer $DOITONG_API_KEY"
Elimina ahora nuestras copias de los archivos de salida de la solicitud y detiene el cobro del almacenamiento. La respuesta es el objeto de solicitud con storage.expired: true; sus URL permanecen en el registro, pero dejan de funcionar. Volver a llamarlo no cambia nada (200). Una solicitud que aún está queued o running todavía no tiene archivos: 409 request_active. Requiere models:run.
Idempotencia: reintentar sin pagar dos veces
Las redes fallan. Para reintentar una ejecución de forma segura, envía un encabezado Idempotency-Key (cualquier cadena de hasta 255 caracteres, única por operación; por ejemplo, tu propio id de pedido):
- Misma clave y mismo cuerpo que antes: recibes la solicitud original (
200, encabezadoIdempotent-Replayed: true) y no se vuelve a cobrar nada. - Misma clave y cuerpo después de una ejecución que falló antes de llegar al modelo (
upstream_errorointernal_erroral enviar,insufficient_credits,budget_exceeded,too_many_inflight): no se produjo nada ni se cobró nada, por lo que el reintento ejecuta el modelo de nuevo en lugar de devolver el error. - Misma clave con un cuerpo diferente:
409 idempotency_mismatch. - Las claves están vinculadas a la clave de API que las envió.
Dónde se guardan los archivos
Cada archivo de salida se copia en nuestro almacenamiento antes de marcar la solicitud como succeeded, por lo que las URL de outputs están en nuestros propios hosts y puedes enlazarlas directamente. Tú eliges cuánto tiempo permanecen:
| Modo | Duración | Precio |
|---|---|---|
permanent (predeterminado) |
Hasta que los elimines | 100 créditos de API (0,10 $) por GB al mes, cobrados diariamente del saldo de API |
temporary |
7 días y después se eliminan | Gratis |
- La configuración de la cuenta se aplica a las nuevas solicitudes: el interruptor "Conservar archivos para siempre" del panel, o
PATCH https://api.doitong.ru/v1/account/storagecon{"mode": "temporary"}.GET https://api.doitong.ru/v1/accountlo muestra enstorage, junto con los bytes que conservas y la estimación mensual. ?storage=permanent|temporaryen una ejecución (el argumentostoragede la herramienta MCPrun) lo sobrescribe para esa ejecución.- Cambiar la configuración nunca afecta a los archivos que ya tienes; elimínalos con
DELETE /requests/{id}/files. - Cuando el saldo de API no puede pagar el almacenamiento, no se cobra nada y recibes un correo electrónico: haz una recarga en un plazo de 30 días o los archivos conservados pasarán a ser temporales y se eliminarán 7 días después.
En el caso poco frecuente de que falle nuestra copia, la entrada tiene "stored": false y la URL es la original, de corta duración: descárgala pronto.