Ir para o conteúdo
Guia da API

Solicitações

Ver como Markdown Atualizado

Uma requisição é uma chamada de um modelo. Ela tem um id (req_…), um status, seu custo em créditos de API (1000 = 1 USD) e, quando é bem-sucedida, os arquivos gerados. O mesmo objeto é retornado por todos os endpoints abaixo, para qualquer modelo.

Encontrar um modelo

O catálogo de todos os 1.496 modelos é um JSON público (não é necessária uma chave):

terminal
curl "https://api.doitong.ru/v1/models?category=text-to-video&lab=Google&limit=20"
Parâmetro de consulta Significado
q Palavras que devem aparecer todas no nome, id, fabricante ou tags, por exemplo kling 3.
category Um id de categoria, por exemplo text-to-video ou upscale. GET https://api.doitong.ru/v1/categories lista todas as 21 com suas contagens.
lab O fabricante do modelo, por nome ou id, por exemplo Google ou black-forest-labs.
family Um id de family de uma linha anterior: cada variante de um modelo (pro, fast, image-to-video, …).
mode exact (o preço é calculado a partir da entrada), measured (a partir da duração ou do tamanho dos arquivos de entrada), estimate (um preço estimado por execução) ou metered (cobrado pelo uso real, até um máximo por execução).
limit, cursor Tamanho da página (1 a 100, padrão 50) e o next_cursor da página anterior.

Cada linha tem id, name, lab, category, family, summary, tags, output_kind, docs_url e um objeto price (consulte Preços). GET https://api.doitong.ru/v1/models/{model_id} adiciona o JSON Schema completo de entrada e saída, os nomes canônicos dos parâmetros, as regras de preço e um exemplo de entrada. Uma category ou mode desconhecida retorna 400 invalid_parameter.

Executar um modelo

terminal
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": "..."}'
  • O corpo é a entrada do modelo, um objeto JSON. Cada página de modelo lista seus parâmetros.
  • A entrada é verificada antes de qualquer cobrança. Uma entrada inválida retorna 422 invalid_input com o param incorreto e não custa nada.
  • ?wait=N (até 20 segundos) mantém a chamada aberta até a requisição terminar ou o tempo se esgotar.
  • ?webhook_url=https://… envia um POST assinado para essa URL quando a requisição termina (consulte Webhooks).
  • ?storage=permanent ou ?storage=temporary escolhe por quanto tempo os arquivos de saída são mantidos; sem isso, aplica-se a configuração da conta (consulte Onde os arquivos ficam).

A resposta é 202 Accepted enquanto a requisição ainda está em andamento e 200 OK quando ela termina dentro do tempo de espera (ou quando é uma repetição, veja abaixo). Os cabeçalhos Location e Doitong-Request-Id contêm a URL e o id da requisição.

Status

Ciclo de vida da solicitação
  1. queued Aceita e cobrada, aguardando um worker
  2. running O modelo está gerando
  3. Status finais:
    • succeededCotação cobrada; outputs[] contém URLs em nosso armazenamento
    • failedReembolsada automaticamente; o erro informa o motivo
    • canceledInterrompida antes de um resultado; reembolsada
Status Significado Final
queued Aceita e cobrada, aguardando um worker. queue_position pode mostrar a posição na fila. não
running O modelo está gerando. não
succeeded Concluída. outputs lista os arquivos. sim
failed O modelo ou um limite a interrompeu. error informa o motivo. Os créditos de API são reembolsados. sim
canceled Cancelada antes de produzir um resultado. Os créditos de API são reembolsados. sim

Uma requisição que ultrapassa seu limite de tempo falha com o código timeout e é reembolsada: 15 minutos para imagens, 60 minutos para vídeo, 30 minutos para áudio e todo o restante.

O objeto de requisição

JSON
{
  "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"
  }
}
  • outputs é igual para todos os modelos: uma entrada por arquivo gerado com type (image, video, audio, file ou 3d), uma url em nosso armazenamento, content_type e, quando conhecidos, file_size, width, height, duration.
  • output é o próprio objeto de resultado do modelo (seus campos são listados em cada página de modelo), com as mesmas URLs.
  • storage informa como os arquivos são mantidos: mode (permanent ou temporary), bytes armazenados, expires_at (quando um arquivo temporário é excluído, null para arquivos permanentes) e expired (true quando os arquivos desaparecem).
  • cost.credits é o preço da chamada em créditos de API (cost.usd em USD), cost.charged é o que foi debitado do saldo de API e cost.refunded é o que voltou. Para um modelo metered, cost.credits é o máximo retido no início (cost.held); quando a execução é bem-sucedida, cost.settled informa o valor correspondente ao uso e o restante do máximo fica em cost.refunded (consulte Cobrança por uso).
  • Quando uma requisição falha, error é { "type": …, "code": …, "message": … }.

Ler uma requisição

terminal
curl "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
  • ?wait=N (até 20 segundos) faz long polling: a chamada retorna assim que a requisição chega a um estado final ou, após N segundos, com o estado atual. Repetir essa chamada é a maneira mais simples de aguardar um resultado.
  • ?logs=1 adiciona as linhas do log de progresso do modelo (as últimas 50) como logs.

Você só pode ler requisições da sua própria conta; qualquer outro id retorna 404 request_not_found.

Listar requisições

terminal
curl "https://api.doitong.ru/v1/requests?limit=20&status=succeeded&model=flux/schnell" \
  -H "Authorization: Bearer $DOITONG_API_KEY"

Mais recentes primeiro. limit vai de 1 a 100 (padrão 20); status e model filtram. A resposta é { "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }; envie cursor=<next_cursor> para a próxima página.

Cancelar uma requisição

terminal
curl -X POST "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
  • Cancelada antes de o modelo começar: o status muda para canceled, os créditos de API são reembolsados e você recebe 200.
  • Já em geração: o cancelamento é encaminhado e você recebe 202 com "cancel_requested": true. Se o modelo terminar mesmo assim, a requisição será concluída normalmente e cobrada.
  • Já finalizada: 409 not_cancelable (uma requisição que já está canceled simplesmente retorna 200).

Excluir os arquivos de uma requisição

terminal
curl -X DELETE "https://api.doitong.ru/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/files" \
  -H "Authorization: Bearer $DOITONG_API_KEY"

Exclui agora nossas cópias dos arquivos de saída da requisição e interrompe a cobrança de armazenamento. A resposta é o objeto da requisição com storage.expired: true; as URLs permanecem no registro, mas deixam de funcionar. Chamá-lo novamente não altera nada (200). Uma requisição que ainda está queued ou running não tem arquivos: 409 request_active. Requer models:run.

Idempotência: repetir sem pagar duas vezes

As redes falham. Para repetir uma execução com segurança, envie um cabeçalho Idempotency-Key (qualquer string de até 255 caracteres, exclusiva por operação, por exemplo seu próprio id do pedido):

  • Mesma chave e mesmo corpo de antes: você recebe a requisição original (200, cabeçalho Idempotent-Replayed: true) e nada é cobrado novamente.
  • Mesma chave e corpo após uma execução que falhou antes de chegar ao modelo (upstream_error ou internal_error no envio, insufficient_credits, budget_exceeded, too_many_inflight): nada foi produzido e nada foi cobrado, então a repetição executa o modelo novamente em vez de retornar a falha.
  • Mesma chave com corpo diferente: 409 idempotency_mismatch.
  • As chaves são vinculadas à chave de API que as enviou.

Onde os arquivos ficam

Cada arquivo de saída é copiado para nosso armazenamento antes de a requisição ser marcada como succeeded, portanto as URLs em outputs estão em nossos próprios hosts e você pode vinculá-las diretamente. Você escolhe por quanto tempo elas ficam:

Modo Duração Preço
permanent (padrão) Até você excluí-los 100 créditos de API ($ 0,10) por GB por mês, cobrados diariamente do saldo de API
temporary 7 dias, depois excluídos Grátis
  • A configuração da conta decide para novas requisições: a chave "Manter arquivos para sempre" no dashboard, ou PATCH https://api.doitong.ru/v1/account/storage com {"mode": "temporary"}. GET https://api.doitong.ru/v1/account a mostra em storage, com os bytes mantidos e a estimativa mensal.
  • ?storage=permanent|temporary em uma execução (o argumento storage da ferramenta run do MCP) substitui essa configuração para essa execução.
  • Alterar a configuração nunca afeta arquivos que você já tem; exclua-os com DELETE /requests/{id}/files.
  • Quando o saldo de API não pode pagar pelo armazenamento, nada é cobrado e você recebe um e-mail: faça uma recarga em até 30 dias ou os arquivos mantidos se tornarão temporários e serão excluídos 7 dias depois.

No caso raro de nossa cópia falhar, a entrada terá "stored": false e a URL será a original, de curta duração: baixe-a em breve.