Jobs
Consulte status e resultados de jobs, leia dicas de falha e créditos, verifique 100 jobs em uma chamada, cancele jobs e pare ou continue o Gerar vídeo Pro.
Um job é uma unidade de geração no Nodaro: uma imagem, uma renderização de vídeo, um clipe de fala. A execução de um nó retorna o ID de um job, e uma execução de workflow cria um job para cada nó de IA. Os endpoints de jobs informam o status, o progresso, o resultado e os créditos de cada job. Você consulta um job periodicamente até ele chegar a completed, failed ou cancelled e, depois, lê o resultado em output_data.
Endpoints
| Método | Caminho | O que faz |
|---|---|---|
GET | /v1/jobs/:id/status | O status enxuto para a consulta periódica: status, progresso, resultado e erro. |
GET | /v1/jobs/:id | O job completo, incluindo o que foi enviado (input_data) e os créditos. |
GET | /v1/jobs | Os seus jobs, dos mais recentes para os mais antigos, em páginas. |
GET | /v1/jobs/status?ids=… | O status de até 100 jobs, com os IDs na query string. |
POST | /v1/jobs/batch-status | O status de até 100 jobs, com os IDs no corpo. |
POST | /v1/jobs/:id/cancel | Cancela um job e libera os créditos reservados para ele. |
DELETE | /v1/jobs/:id | Exclui um job e a mídia privada que ele produziu. |
GET | /v1/component/execute/:jobId/wait-limit | Quanto tempo o servidor espera por uma execução de componente. |
POST | /v1/generate-video-pro/:jobId/stop | Interrompe uma execução do Gerar vídeo Pro (Generate Video Pro) e mantém os segmentos concluídos. |
POST | /v1/generate-video-pro/continue | Continua uma execução do Gerar vídeo Pro como um novo job. |
POST | /v1/credits/video-pro-estimate | Calcula o preço de uma execução do Gerar vídeo Pro sem iniciá-la. |
Um token OAuth precisa do escopo jobs:read para ler jobs. Tokens de API pessoais não precisam de escopo.
Ler um job
curl -s https://app.nodaro.ai/v1/jobs/0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10/status \
-H "Authorization: Bearer $NODARO_API_KEY"{
"data": {
"id": "0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10",
"status": "completed",
"progress": 100,
"output_data": { "imageUrl": "https://…/0f1a9c2e.png" },
"error_message": null,
"error_hint": null,
"credit_status": "committed"
}
}const { data } = await client.jobs.getStatus(jobId)
if (data.status === 'completed') console.log(data.output_data)
// The full record, with input_data and credits:
const { data: job } = await client.jobs.get(jobId)nodaro jobs get 0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10 --jsonGET /v1/jobs/:id/status foi feito para loops de consulta periódica: ele omite input_data e os campos de custo, por isso é mais leve que GET /v1/jobs/:id. Os dois respondem { "data": … }, e os dois respondem 404 para um job que não existe ou não é seu. Os campos dos jobs usam snake_case, do jeito que o servidor os envia.
| Campo | Significado |
|---|---|
id | O ID do job. |
status | Em que ponto o job está. Veja Status dos jobs. |
progress | De 0 a 100. |
output_data | O resultado. Os jobs de mídia trazem imageUrl, videoUrl ou audioUrl, muitas vezes com thumbnailUrl. Os outros jobs trazem campos próprios, como text ou json. |
error_message | Por que o job falhou, em palavras. |
error_hint | Um motivo estruturado para dois tipos de falha. Veja Por que um job falhou. |
credit_status | reserved, committed, refunded ou null. Veja Créditos de um job. |
recovering | true enquanto a plataforma repara um job cujo worker parou depois que o modelo já tinha entregado o resultado. |
input_data | Só no job completo. O que foi enviado, depois das correções: por exemplo, o prompt final, o seu próprio userPrompt e os IDs de direction. |
credits | Só no job completo. Os créditos do job. |
job_type, source, source_detail | Só no job completo. O tipo de job e de onde ele veio: source é internal, mcp, app, cli, sdk, extension, web ou api, e source_detail indica o cliente, como sdk/1.10.0. |
created_at, started_at, completed_at | Só no job completo. Carimbos de data e hora. |
input_data e output_data são visões públicas: os campos que existem só para o servidor são removidos para todos os chamadores.
Status dos jobs
| Status | Final | Significado |
|---|---|---|
pending, queued, processing | Não | O job está aguardando a execução ou em execução. |
pending_review | Não | O resultado existe, e a implantação o retém para uma revisão humana. Continue consultando periodicamente. |
completed | Sim | O resultado está em output_data. |
failed | Sim | error_message e error_hint dizem por quê. |
cancelled | Sim | Você ou a plataforma cancelou o job. |
Jobs em recuperação. Quando um worker para depois que o modelo já entregou o resultado, o job fica em processing com recovering: true enquanto a plataforma o repara. Depois, ele é concluído ou reembolsado por conta própria. Em modelos lentos, isso pode levar dezenas de minutos, mais do que a espera padrão do SDK. Um JobTimeoutError de runAndWait não cancela o job, então busque o job de novo mais tarde.
Jobs retidos para revisão. Em uma implantação que registra uma política de revisão, um job pode entrar em pending_review. O trabalho está feito, os créditos continuam reserved durante toda a retenção, e uma pessoa decide se o resultado é liberado. O job então termina como completed (aprovado), failed com uma dica policy-block (rejeitado) ou cancelled. Um job retido pode ser cancelado como qualquer job em andamento. Não envie a requisição de novo, porque uma duplicata também ficaria retida. Quando a implantação define um prazo de revisão, um job que ninguém revisa a tempo é rejeitado: ele termina como failed, a reserva é reembolsada e o resultado retido é excluído. Um job retido nunca é aprovado automaticamente. O runAndWait do SDK lança JobHeldError na primeira consulta periódica que encontra pending_review, e o --watch da CLI sai com o código 3.
Boas práticas de consulta periódica
- Consulte periodicamente a cada 2 a 5 segundos. Um job muda de estado em segundos, não em milissegundos.
- As leituras de status não contam para o limite de taxa do token. Só as execuções e as listagens de workflows contam para o limite por minuto de um token de API pessoal. Veja Limites de taxa.
- Acompanhe muitos jobs com uma chamada. Use os endpoints em lote em vez de uma requisição por job.
- Deixe o cliente esperar por você. O
client.nodes.runAndWaitdo SDK consulta periodicamente a cada 2 segundos por até 15 minutos, e o--watchda CLI consulta periodicamente até o job terminar.
Por que um job falhou
A tabela de erros em Erros cobre as requisições que nunca criaram um job. Um job que falha depois traz error_message e, em dois tipos de falha, também um error_hint estruturado.
O filtro de segurança de um modelo bloqueou a requisição:
{ "kind": "safety-block", "class": "safety", "retried": true, "suggestedProvider": "nano-banana-pro" }classécopyright,likenessousafety. Um bloqueiocopyrightoulikenessé definitivo: a mesma requisição nunca passa.- Em alguns modelos, um filtro
safetynem sempre é consistente. No GPT Image 2, no GPT Image 2.5 Flare e no GPT Image 2.5 Sunburst, o Nodaro tenta a mesma requisição de novo uma vez, sem custo extra.retriedinforma se essa nova tentativa já aconteceu. suggestedProvidersó aparece quando o modelo tem uma alternativa recomendada. É um ID de modelo real: envie o mesmo prompt e as mesmas referências para ele.
A política de uma implantação rejeitou o job:
{ "kind": "policy-block", "policyId": "brand-safety", "reason": "This image was not approved for release.", "hookPoint": "result" }reasoné um texto escrito para o seu usuário pela política da implantação. Mostre esse texto como está.hookPointérequestquando o job foi recusado antes de ser executado, eresultquando o resultado dele foi rejeitado depois, inclusive por um revisor.- A plataforma não tenta de novo depois de uma rejeição por política e não oferece outro modelo.
Nenhuma outra falha tem error_hint. Quando um modelo recusa a própria requisição, porque as configurações ou a mídia de entrada são inválidas para esse modelo, error_message informa isso: mude as configurações ou a mídia antes de executar de novo. Um erro do lado do modelo continua valendo uma nova tentativa, seja qual for o texto. error_hint aparece em todo payload de job que traz error_message: o job completo, as rotas de status, a lista e as duas rotas em lote.
Créditos de um job
credit_status acompanha a reserva de créditos do job:
| Valor | Significado |
|---|---|
reserved | Os créditos ficam reservados enquanto o job é executado. |
committed | O job entregou o resultado e foi cobrado. |
refunded | A reserva foi liberada, por exemplo, depois de um bloqueio de segurança. |
null | O job não tem um registro de créditos para informar. |
Ele aparece em GET /v1/jobs/:id, GET /v1/jobs/:id/status e GET /v1/jobs/status, nunca em GET /v1/jobs nem em POST /v1/jobs/batch-status. Uma geração que termina em um bloqueio de segurança ou de política é sempre reembolsada. A rara exceção é um job cujos créditos já tinham sido liquidados antes de uma política rejeitar o resultado dele. Veja Créditos.
Listar os seus jobs
GET /v1/jobs retorna os seus jobs, dos mais recentes para os mais antigos, como { data: Job[], next }:
| Parâmetro de consulta | Significado |
|---|---|
limit | Tamanho da página, até 100. |
cursor | O valor next da página anterior. |
type | A rota que criou o job, com o valor exato, como llm-structured ou video-analysis. |
origin | O app cliente que enviou o job, com o valor exato, como studio. |
attachToCharacterId | Os jobs de um personagem. Veja Personagens. |
type e origin podem ser combinados. Uma página pode ter menos linhas que limit, até nenhuma, e ainda trazer um next: continue paginando enquanto next estiver presente, nunca contando linhas.
const { data: runs, next } = await client.jobs.list({ type: 'llm-structured', origin: 'my-app' })Consultar periodicamente muitos jobs de uma vez
Dois endpoints retornam o status de até 100 jobs em uma única ida e volta:
curl -s "https://app.nodaro.ai/v1/jobs/status?ids=$JOB_A,$JOB_B,$JOB_C" \
-H "Authorization: Bearer $NODARO_API_KEY"{
"jobs": [
{ "id": "0f1a9c2e-…", "status": "completed", "output_data": { "imageUrl": "https://…/a.png" }, "error_message": null, "error_hint": null, "credit_status": "committed" },
{ "id": "7d3e5f60-…", "status": "processing", "output_data": null, "error_message": null, "error_hint": null, "credit_status": "reserved" }
]
}curl -s -X POST https://app.nodaro.ai/v1/jobs/batch-status \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"jobIds\": [\"$JOB_A\", \"$JOB_B\", \"$JOB_C\"]}"A resposta é { "data": [ … ] }, com id, status, output_data, error_message e error_hint para cada job, e sem credit_status.
Os IDs que não existem, ou que pertencem a outra pessoa, ficam de fora sem erro. Compare a resposta com a sua própria lista de IDs.
Cancelar ou excluir um job
POST /v1/jobs/:id/cancel cancela um job e libera os créditos que ele reservou. A resposta é { "success": true, "cancelled": 1 }. Um job retido em pending_review também pode ser cancelado.
DELETE /v1/jobs/:id exclui um job e a mídia privada que ele produziu, e responde { "success": true }. Só o dono do job pode excluí-lo. Um job em execução é excluído do jeito que está, então cancele-o antes quando o trabalho dele precisar parar.
curl -s -X POST https://app.nodaro.ai/v1/jobs/$JOB_ID/cancel \
-H "Authorization: Bearer $NODARO_API_KEY"const { cancelled } = await client.jobs.cancel(jobId)
await client.jobs.delete(jobId)nodaro jobs cancel 0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10Para interromper uma execução de workflow inteira, cancele essa execução: veja Execuções.
Execuções de componentes
POST /v1/component/execute executa um Componente (Component) salvo em segundo plano e responde 202 com { jobId }. Consulte esse job periodicamente, como qualquer outro. O servidor dá 90 minutos a uma execução de componente, mais o orçamento de tempo de qualquer renderização longa dentro dela, como a renderização final de um nó Aplicar EDL (Apply EDL).
Um cliente com um limite de tempo próprio pode perguntar quanto tempo o servidor vai esperar:
curl -s https://app.nodaro.ai/v1/component/execute/$JOB_ID/wait-limit \
-H "Authorization: Bearer $NODARO_API_KEY"{ "data": { "budgetExcessMs": 0, "waitLimitMs": 5400000, "pendingBudgetedNodes": true } }waitLimitMsé a espera do servidor para esta execução: 90 minutos maisbudgetExcessMs.budgetExcessMsfica em0até a execução iniciar uma renderização longa.pendingBudgetedNodesétrueenquanto uma renderização longa ainda não começou e enquanto a própria execução ainda não começou. Por isso, um excesso0ainda não significa que não há nada longo dentro dela.
Os dois valores podem mudar durante a execução, então pergunte de novo quando waitLimitMs for atingido. A rota só responde ao dono da execução, com 404 para qualquer outra pessoa e para jobs que não são execuções de componentes. O próprio editor usa esta regra: espera 30 minutos por uma execução sem nada longo dentro, waitLimitMs depois que uma renderização longa começa e pelo menos 90 minutos enquanto pendingBudgetedNodes é true. Depois, pergunta de novo.
Execuções do Gerar vídeo Pro
O Gerar vídeo Pro faz vídeos longos um segmento por vez e salva o progresso entre os segmentos, então uma execução pode ser interrompida e continuada depois. Ele roda no Nodaro Cloud, e uma instalação self-hosted o executa pela conexão com o Nodaro Cloud.
Interromper uma execução
POST /v1/generate-video-pro/:jobId/stop interrompe de forma controlada uma execução em processing:
- O segmento que está sendo gerado é abandonado e, mesmo assim, é cobrado, porque o modelo continua a renderizá-lo.
- Os segmentos restantes são pulados.
- Todos os segmentos concluídos são unidos no vídeo final do job.
- A parte não usada da reserva é reembolsada.
A resposta é { "jobId": "…", "stopping": true }. Continue consultando o job periodicamente: ele termina como completed, com output_data.pro.stopped igual a true e com stoppedAtSegment. Já um job que ainda está em pending é cancelado com reembolso total.
Continuar uma execução
POST /v1/generate-video-pro/continue inicia um novo job a partir de um job terminado. Ele reaproveita o plano do job original e todos os segmentos entregues antes de fromSegment, e gera de novo a partir dali:
{ "fromJobId": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "fromSegment": 4 }fromSegmentcomeça em 1. Por padrão, é o primeiro segmento que não foi entregue.- O job original precisa estar terminado: interrompido, com falha e pelo menos um segmento entregue, ou concluído. Um
fromSegmentexplícito em uma execução concluída gera o final dela de novo. - Você paga só pelos segmentos gerados de novo, mais a taxa fixa do Gerar vídeo Pro.
- A rota respeita o cabeçalho
Idempotency-Key, então uma requisição repetida não inicia um segundo job.
A resposta é { jobId, continuedFromJobId, fromSegment, segmentCount }. Consulte periodicamente o novo jobId.
curl -s -X POST https://app.nodaro.ai/v1/generate-video-pro/$JOB_ID/stop \
-H "Authorization: Bearer $NODARO_API_KEY"
curl -s -X POST https://app.nodaro.ai/v1/generate-video-pro/continue \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4c1f0a7e-2b3d-4e5f-8a9b-0c1d2e3f4a5b" \
-d "{\"fromJobId\": \"$JOB_ID\", \"fromSegment\": 4}"await client.videoPro.stop(jobId)
const { data } = await client.jobs.getStatus(jobId) // completes with a partial video
const { jobId: childId } = await client.videoPro.continueRun(jobId, { fromSegment: 4 })nodaro video-pro stop 9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d
nodaro video-pro continue 9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d --from-segment 4 --watchAs duas rotas respondem 404 para um job que não é seu e 400 para um job que não é uma execução do Gerar vídeo Pro.
Estimar uma execução
POST /v1/credits/video-pro-estimate calcula o preço de uma execução do Gerar vídeo Pro sem criar um job nem reservar créditos:
{ "provider": "gemini-omni-flash", "resolution": "720p", "duration": 12, "renderMethod": "keyframes", "segmentMode": "short" }Em uma configuração de exemplo, a resposta é { "data": { "credits": 760, "upperBound": true } }. Leia a resposta em tempo real para ver os preços atuais.
Prop
Type
- Com
segmentModeshortoulong, a execução primeiro atribui ações completas a trechos da origem, eupperBound: truesignifica que o valor é o limite da reserva antes do planejamento. A cobrança final segue o plano real. - Uma estimativa
planOnlycobre a taxa de planejamento e retornaupperBound: false. Os valoressourceSegmentDurationseplanCheckpointdela podem ser enviados de volta comosourceSegmentDurationseseedPlan, com o mesmo modo e as mesmas configurações.
Leia Gerar vídeo Pro para saber como a segmentação funciona e o que cada configuração faz.
Perguntas frequentes
Páginas relacionadas
Nós
Execuções
Erros
Créditos
Gerar vídeo Pro
Última atualização
Nós
Execute qualquer nó do Nodaro com POST /v1/<node-type>, descubra nós, modelos e valores de seletores e guie o prompt com referências e IDs de direção.
Execuções
Acompanhe uma execução de workflow nó a nó, leia o resultado de cada nó, liste execuções passadas e cancele agora ou quando os nós em andamento terminarem.