Avançar para o conteúdo
Guia da API

Pedidos

Ver como Markdown Atualizado

Um pedido é uma chamada de um modelo. Tem um id (req_…), um estado, o seu custo em créditos de API (1000 = 1 USD) e, quando é concluído com sucesso, os ficheiros gerados. O mesmo objeto é devolvido por todos os endpoints abaixo, para todos os modelos.

Encontrar um modelo

O catálogo dos 1496 modelos é um JSON público (não é necessária uma chave):

terminal
curl "https://api.doitong.com/v1/models?category=text-to-video&lab=Google&limit=20"
Parâmetro de consulta Significado
q Palavras que têm de aparecer todas no nome, id, fabricante ou etiquetas, por exemplo kling 3.
category Um id de categoria, por exemplo text-to-video ou upscale. GET https://api.doitong.com/v1/categories lista as 21 categorias com as respetivas 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: todas as variantes 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 ficheiros de entrada), estimate (um preço estimado por execução) ou metered (cobrado com base na utilização real, até a um máximo por execução).
limit, cursor Tamanho da página (1 a 100, predefiniçã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.com/v1/models/{model_id} acrescenta o JSON Schema completo da entrada e da saída, os nomes canónicos dos parâmetros, as regras de preço e um exemplo de entrada. Uma category ou mode desconhecida resulta em 400 invalid_parameter.

Executar um modelo

terminal
curl -X POST "https://api.doitong.com/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 os seus parâmetros.
  • A entrada é validada antes de qualquer cobrança. Uma entrada inválida devolve 422 invalid_input com o param que causou o problema e não tem qualquer custo.
  • ?wait=N (até 20 segundos) mantém a chamada aberta até o pedido terminar ou o tempo esgotar-se.
  • ?webhook_url=https://… envia um POST assinado para esse URL quando o pedido termina (consulte Webhooks).
  • ?storage=permanent ou ?storage=temporary escolhe durante quanto tempo os ficheiros de saída são mantidos; sem este parâmetro, aplica-se a definição da conta (consulte Onde ficam os ficheiros).

A resposta é 202 Accepted enquanto o pedido ainda está a ser processado e 200 OK quando terminou dentro do período de espera (ou quando é uma repetição, conforme descrito abaixo). Os cabeçalhos Location e Doitong-Request-Id contêm o URL e o id do pedido.

Estados

Ciclo de vida do pedido
  1. queued Aceite e cobrado, à espera de um worker
  2. running O modelo está a gerar
  3. Estados finais:
    • succeededO orçamento foi debitado; outputs[] contém URLs no nosso armazenamento
    • failedReembolsado automaticamente; o erro indica o motivo
    • canceledParado antes de obter um resultado; reembolsado
Estado Significado Final
queued Aceite e cobrado, à espera de um worker. queue_position pode mostrar a posição na fila. não
running O modelo está a gerar. não
succeeded Concluído. outputs lista os ficheiros. sim
failed O modelo ou um limite interrompeu-o. error indica o motivo. Os créditos de API são reembolsados. sim
canceled Cancelado antes de produzir um resultado. Os créditos de API são reembolsados. sim

Um pedido que exceda o seu limite de tempo falha com o código timeout e é reembolsado: 15 minutos para imagens, 60 minutos para vídeo, 30 minutos para áudio e tudo o resto.

O objeto do pedido

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.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
    "cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
  }
}
  • outputs é igual para todos os modelos: uma entrada por ficheiro gerado com type (image, video, audio, file ou 3d), um url no nosso armazenamento, content_type e, quando conhecidos, file_size, width, height, duration.
  • output é o próprio objeto de resultado do modelo (os respetivos campos estão listados em cada página de modelo), com os mesmos URLs.
  • storage indica como os ficheiros são mantidos: mode (permanent ou temporary), bytes armazenados, expires_at (quando um ficheiro temporário é eliminado, null para os permanentes) e expired (true quando os ficheiros já desapareceram).
  • cost.credits é o preço da chamada em créditos de API (cost.usd em USD), cost.charged é o montante debitado do saldo de API e cost.refunded é o montante devolvido. Para um modelo metered, cost.credits é o máximo retido no início (cost.held); quando a execução é concluída com sucesso, cost.settled indica o custo efetivo da utilização e o restante do máximo está em cost.refunded (consulte Cobrado com base na utilização).
  • Quando um pedido falha, error é { "type": …, "code": …, "message": … }.

Consultar um pedido

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

Só pode consultar pedidos da sua própria conta; qualquer outro id resulta em 404 request_not_found.

Listar pedidos

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

Do mais recente para o mais antigo. limit varia entre 1 e 100 (predefinição 20); status e model funcionam como filtros. A resposta é { "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }; passe cursor=<next_cursor> para obter a página seguinte.

Cancelar um pedido

terminal
curl -X POST "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
  • Cancelado antes de o modelo começar: o estado passa a canceled, os créditos de API são reembolsados e recebe 200.
  • Já em geração: o cancelamento é encaminhado e recebe 202 com "cancel_requested": true. Se o modelo terminar mesmo assim, o pedido é concluído normalmente e cobrado.
  • Já num estado final: 409 not_cancelable (um pedido que já esteja canceled devolve simplesmente 200).

Eliminar os ficheiros de um pedido

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

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

Idempotência: repetir sem pagar duas vezes

As redes falham. Para repetir uma execução em segurança, envie um cabeçalho Idempotency-Key (qualquer sequência com até 255 caracteres, única por operação, por exemplo o seu próprio id de encomenda):

  • A mesma chave e o mesmo corpo de antes: recebe o pedido original (200, cabeçalho Idempotent-Replayed: true) e não há nova cobrança.
  • A mesma chave e o mesmo corpo depois de 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 nem cobrado, por isso a repetição executa novamente o modelo em vez de devolver a falha.
  • A mesma chave com um corpo diferente: 409 idempotency_mismatch.
  • As chaves estão associadas à chave de API que as enviou.

Onde ficam os ficheiros

Cada ficheiro de saída é copiado para o nosso armazenamento antes de o pedido ser marcado como succeeded, pelo que os URLs em outputs apontam para os nossos próprios hosts e podem ser ligados diretamente. A duração da retenção é uma escolha sua:

Modo Duração Preço
permanent (predefinição) Até os eliminar 100 créditos de API (0,10 $) por GB por mês, cobrados diariamente ao saldo de API
temporary 7 dias, depois são eliminados Gratuito
  • A definição da conta aplica-se aos novos pedidos: o interruptor "Guardar ficheiros para sempre" no dashboard ou PATCH https://api.doitong.com/v1/account/storage com {"mode": "temporary"}. GET https://api.doitong.com/v1/account mostra-a em storage, juntamente com os bytes que mantém e a estimativa mensal.
  • ?storage=permanent|temporary numa execução (o argumento storage da ferramenta run do MCP) substitui-a nessa execução.
  • Alterar a definição nunca afeta os ficheiros que já possui; elimine-os com DELETE /requests/{id}/files.
  • Quando o saldo de API não consegue pagar o armazenamento, nada é cobrado e recebe um email: faça um carregamento no prazo de 30 dias ou os ficheiros mantidos passam a temporários e são eliminados 7 dias depois.

No caso raro de a nossa cópia falhar, a entrada tem "stored": false e o URL é o original, de curta duração: descarregue-o rapidamente.