Docs do Nodaro
DocumentaçãoReferência de nósModelosAgentes de IA (MCP)DesenvolvedoresSelf-hostingPesquisa
API REST

Produções do Studio

Leia e edite produções do Studio via REST com operações atômicas, gere imagens fixas e clipes, incorpore jobs, planeje a exportação, compartilhe e copie.

Disponível em Nodaro Cloud

A API de produções do Studio lê e grava os filmes que você monta no Nodaro Studio. Uma produção é um workflow do Nodaro cujas configurações guardam uma lista ordenada de tomadas. Cada tomada tem uma imagem fixa enquadrada, um clipe animado opcional e o plano, os visuais, o elenco e a voz que os produziram. Um script, um assistente de IA e o editor do Studio trabalham na mesma produção por meio destas rotas, ao mesmo tempo.

As produções do Studio só rodam no Nodaro Cloud. Uma implantação que não oferece produções retorna 404 em todas as rotas, então detecte o recurso uma vez com a rota de listagem. Em uma instalação self-hosted, monte o filme como um workflow com nós como Cena (Scene), Gerar vídeo (Generate Video) e Combinar vídeos (Combine Videos). As rotas recebem um bearer token; os tokens de app OAuth precisam de workflows:read para ler e de workflows:write para gravar. Veja Autenticação.

Toda rota retorna 404, nunca 403, quando você não tem acesso a uma produção, então não é possível sondar um ID.

Os termos do editor e as chaves do documento

O editor e o documento dão nomes diferentes às mesmas coisas. Use as chaves do documento no código e os termos do editor com as pessoas.

No editorNo documento
filmea produção
cena, por exemplo Cena 3uma entrada de shots[], identificada pelo shotId
o quadro de uma cena e os takes deleos resultados still da tomada
o movimento de uma cena e os takes deleos resultados clip da tomada
as tomadas dentro de um movimentoos beats[] da tomada

Endpoints

MétodoCaminhoO que faz
GET/v1/studio/productions/skillO guia de criação, o catálogo, o JSON Schema do plano e o vocabulário de operações. Grátis.
GET/v1/studio/productions/capabilitiesQuais operações opcionais esta implantação aceita.
POST/v1/studio/productions/validateValida um plano. Grátis, e não guarda nada.
GET/v1/studio/productionsLista as suas produções, da mais nova para a mais antiga.
POST/v1/studio/productionsCria uma produção, opcionalmente a partir de um plano.
GET/v1/studio/productions/:idLê uma produção. Nunca grava nada.
POST/v1/studio/productions/:id/opsAplica um lote de operações, ou mostra uma prévia dele.
POST/v1/studio/productions/:id/reconcileTransforma jobs concluídos em resultados.
POST/v1/studio/productions/:id/importAdiciona as tomadas de um plano à produção.
POST/v1/studio/productions/:id/describeEscreve o plano a partir de um briefing.
POST/v1/studio/productions/:id/generateGera uma imagem fixa ou um clipe para uma tomada, ou faz a cotação.
POST/v1/studio/productions/:id/frameExtrai um quadro de um clipe.
POST/v1/studio/productions/:id/voiceNarra uma fala sobre uma tomada.
POST/v1/studio/productions/:id/revoiceTroca as vozes do clipe de uma tomada.
POST/v1/studio/productions/:id/musicGera a trilha sonora.
GET/v1/studio/productions/:id/export-planOs passos com preço que montam o filme.
POST/v1/studio/productions/:id/shareAtiva ou desativa o compartilhamento por link.
POST/v1/studio/productions/:id/unshareDesativa o compartilhamento por link.
POST/v1/studio/productions/:id/cloneCopia uma produção.

Não existe rota de exclusão. Arquivar é uma operação, e ela pode ser desfeita.

Ler uma produção

Toda resposta vem envolvida como { "data": { "production": { … } } }. O SDK desembrulha esse envelope: um método que retorna uma produção resolve para a própria produção. O nível superior da produção guarda:

CampoO que guarda
id, name, version, updatedAtA identidade e o contador que toda gravação verifica.
thumbnailUrl, shared, archivedO quadro de capa, se o compartilhamento por link está ativo e se a produção está arquivada.
film, cast, folders, storyboard, music, musicPlan, cutsO visual do filme, os papéis, as pastas da linha do tempo, o briefing, a trilha sonora e os cortes exportados.
trash{ count, items? }: o que foi removido e pode ser restaurado.
pending{ stills, clips, music, draft }: o que está sendo gerado agora.
shots[]As tomadas na ordem da linha do tempo, cada uma com still, clip, startFrame, endFrame, plan, beats, look, voice e mais.

GET /v1/studio/productions/:id aceita detail=summary (o padrão: contagens e as URLs ativas) ou detail=full (todos os resultados do histórico de cada tomada, com o contexto que os produziu). shot_id retorna uma tomada, o jeito barato de ler de novo depois de uma geração. GET /v1/studio/productions aceita limit, cursor e includeArchived.

Os resultados se acumulam. Gerar nunca substitui: as imagens fixas de uma tomada são todas as candidatas que ela já teve, e o mesmo vale para os clipes. Excluir uma imagem fixa nunca afeta os clipes. Um resultado é identificado pela chave de resultado, que é o ID do job quando ele tem um e, caso contrário, a URL, nunca pela posição.

curl "https://app.nodaro.ai/v1/studio/productions/5d8f2b4a-7c1e-4a9d-8b3f-2e6c9a1d4f7b?detail=summary" \
  -H "Authorization: Bearer $NODARO_API_KEY"
import { createClient, StaticTokenAuth } from '@nodaro/sdk'

const client = createClient({
  baseUrl: 'https://app.nodaro.ai',
  auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})

const production = await client.studio.productions.get(id, { detail: 'full' })
const shot = await client.studio.productions.get(id, { shotId: 'shot-2' })

O SDK tipa os envelopes (version, rebased, receipts, warnings, os credits de uma cotação, os jobIds de uma execução) e deixa o documento da produção como JSON aberto.

Editar com operações

Toda alteração em uma produção é uma operação: uma edição com nome, como renomear uma tomada, movê-la, vincular um papel do elenco ou manter uma candidata. POST /v1/studio/productions/:id/ops valida e aplica um lote delas. O vocabulário é servido pela API, não impresso aqui: leia a parte operating de GET …/skill, que sempre corresponde à implantação com que você está falando.

# batch.json: { "ops": [ ...operations from GET /v1/studio/productions/skill... ], "baseVersion": 7 }
curl -X POST https://app.nodaro.ai/v1/studio/productions/5d8f2b4a-7c1e-4a9d-8b3f-2e6c9a1d4f7b/ops \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d @batch.json
const { production, version, rebased, receipts } =
  await client.studio.productions.ops(id, { ops, baseVersion: 7 })

A resposta é { production, version, rebased, receipts, warnings }. Seis regras valem para todo lote:

  1. Tudo ou nada. Uma operação inválida faz o lote inteiro ser recusado, e nada é gravado. O erro indica a operação pelo opIndex, contado a partir de zero. Um lote tem até 100 operações.
  2. Rebase por padrão. baseVersion é informativo: um lote escrito com base em uma versão mais antiga é aplicado ao documento mais novo, e a resposta diz rebased: true. Envie strict: true para receber 409 workflow_conflict no lugar.
  3. Identifique pela chave estável. Uma tomada pelo ID, uma pasta ou um corte pelo ID, uma linha do elenco pelo slug do papel, um resultado pela chave de resultado. Nunca pela posição, porque o editor e um script podem editar a mesma produção ao mesmo tempo.
  4. Crie os seus próprios IDs. Uma operação que cria uma tomada, uma pasta, um corte ou uma cópia usa o ID que você fornece. Assim, a sua cópia local e o servidor concordam em todos os IDs.
  5. As exclusões vão para a lixeira. Uma remoção move o que foi removido para a lixeira da produção, e uma operação o restaura. Só uma exclusão definitiva explícita destrói algo.
  6. Adote a resposta. Substitua a sua cópia por production em vez de mesclar, e envie version como o próximo baseVersion.

O compartilhamento não é uma operação; um lote que tenta alterá-lo é recusado. receipts tem uma linha no passado por operação, { op, summary, ids?, impact? }: mostre essas linhas a quem quiser saber o que um assistente fez. warnings lista coisas que vale dizer e que não são falhas, como uma operação que não mudou nada.

Ver a prévia de um lote antes de aplicá-lo

dryRun: true pergunta o que um lote faria. O servidor executa a própria gravação, no mesmo contexto e com as mesmas recusas, e para antes de salvar. A resposta é { dryRun: true, version, receipts, warnings }, sem production. Cada recibo adiciona class (S: seguro, D: exclui, P: muda quem tem acesso ao trabalho, $: gasta) e, quando uma exclusão pode ser desfeita, restorable: true.

Uma implantação anterior às prévias ignora dryRun e aplica o lote. Por isso, confirme a flag primeiro, com um lote vazio, que não muda nada em nenhuma implantação:

{ "ops": [], "dryRun": true }

Só uma resposta que traz dryRun: true é um sim. Qualquer outra coisa é um não: diga à pessoa que não é possível ver a prévia aqui e não envie o lote. Verifique o marcador também na resposta da prévia real, porque uma implantação em atualização pode atender a próxima requisição a partir de outro servidor. Uma resposta com production no lugar do marcador significa que o lote foi aplicado: adote essa resposta e não envie o lote de novo. O SDK faz as duas verificações por você e lança StudioPreviewUnavailable ou StudioPreviewAppliedError.

const preview = await client.studio.productions.ops(id, { ops, baseVersion, dryRun: true })
for (const r of preview.receipts) console.log(r.class, r.summary, r.restorable ?? false)

Gerar imagens fixas e clipes

A geração funciona em dois tempos: executar e depois consultar periodicamente. POST /v1/studio/productions/:id/generate com kind: "still" ou kind: "clip" e um shotId envia os jobs, registra-os como pendentes na produção e retorna na hora com { jobIds, lane?, deduped?, production? }.

  • Montada a partir da tomada. O servidor monta a requisição com o plano, os visuais, o elenco e a direção da tomada. Por isso, uma chamada de um script e um clique no editor produzem a mesma imagem. overrides muda uma execução sem mudar a tomada.
  • Cote primeiro. dryRun: true calcula o preço da execução e não grava nada. A resposta é { dryRun: true, provider, count, credits, lane? }. credits: null significa que o modelo não tem preço, ou seja, o custo é desconhecido, não gratuito.
  • Repita com segurança. clientRequestId, de 8 a 128 caracteres de A-Za-z0-9_.:- criados por você, torna uma nova tentativa segura: o mesmo ID retorna os jobs da primeira chamada com deduped: true e não cobra nada. Nunca repita uma chamada paga sem ele.
  • Incorpore os resultados. POST /v1/studio/productions/:id/reconcile transforma os jobs concluídos em resultados e limpa os que falharam. A rota retorna { landed, pending, failed, warnings, production, version }. Um GET nunca grava nada, então chame reconcile quando estiver esperando algo.
  • A via do clipe é escolhida automaticamente. Para um clipe, a rota do modelo (generate-video ou text-to-video) decorre das entradas da tomada e volta como lane. mode só diz a partir de qual conjunto de entradas dirigir: "start" ou "references".
curl -X POST https://app.nodaro.ai/v1/studio/productions/5d8f2b4a-7c1e-4a9d-8b3f-2e6c9a1d4f7b/generate \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "still", "shotId": "shot-2", "count": 2, "clientRequestId": "still-shot-2-take-1" }'

curl -X POST https://app.nodaro.ai/v1/studio/productions/5d8f2b4a-7c1e-4a9d-8b3f-2e6c9a1d4f7b/reconcile \
  -H "Authorization: Bearer $NODARO_API_KEY"
import { isStudioGenerateEstimate } from '@nodaro/sdk'

const quote = await client.studio.productions.generateStill(id, 'shot-2', { count: 2, dryRun: true })
if (isStudioGenerateEstimate(quote)) console.log(quote.credits)

const run = await client.studio.productions.generateStill(id, 'shot-2', {
  count: 2,
  clientRequestId: crypto.randomUUID(),
})
// ...once the jobs finish:
const { landed, pending } = await client.studio.productions.reconcile(id)

As outras rotas de mídia trabalham em uma tomada:

RotaCorpoO que faz
frame{ shotId, mode?, timestamp?, target?, clientRequestId? }Extrai um quadro de um clipe. Espera alguns segundos e retorna { production, url? }.
voice{ shotId, text, voiceId?, voiceType?, ttsProvider?, delivery?, clientRequestId? }Narra uma fala sobre a tomada. Espera e retorna { production }.
revoice{ shotId, plan, clientRequestId? }Troca as vozes do clipe da tomada. Retorna { jobId, production }; o resultado é incorporado pelo reconcile.
music{ prompt, duration?, instrumental?, vocalGender?, model?, clientRequestId? }Gera a trilha sonora. Retorna { jobId, production }; o resultado é incorporado pelo reconcile.

clientRequestId é aceito em todas as rotas pagas aqui, inclusive frame e voice.

Clipes vinculados e novos takes

Algumas implantações aceitam clipes que vão de um quadro revisado a outro. Verifique primeiro GET /v1/studio/productions/capabilities: operations.generateLinkedClips e operations.retakeLinkedClips dizem se eles estão disponíveis.

  • Cote um clipe vinculado. generate com kind: "clip", o shotId e dryRun: true verifica os dois quadros e retorna uma cotação com um inputHash. Envie esse valor de volta como expectedInputHash na requisição real. Quando as configurações ou os quadros mudaram nesse meio-tempo, a rota retorna 409 sequence_quote_changed antes de enviar qualquer coisa.
  • Gere um novo take de um clipe. Adicione retakeResultKey para cotar um novo take de um clipe vinculado existente, com as configurações e os quadros originais. Depois, envie a requisição com o inputHash da cotação e um clientRequestId novo. Não envie mode, overrides nem count. Um take cuja requisição original ou cujos quadros não foram guardados não pode ganhar um novo take.

Do briefing à produção

Ler o guia

GET /v1/studio/productions/skill retorna { skill, catalog, schema, operating, generatedFrom }: como um plano é escrito, todos os seletores, modelos e valores permitidos, o JSON Schema do plano e o vocabulário de operações.

Validar um plano

POST /v1/studio/productions/validate com { plan } retorna { valid, errors, warnings, summary? }. Corrija o path de cada erro até valid ser true. Os nomes do elenco são verificados na sua própria biblioteca.

Criar a produção

POST /v1/studio/productions com { name?, plan? } cria a produção e incorpora o plano. POST …/:id/import com { plan, mode: "append" } adiciona as tomadas de um plano a uma produção existente. Nenhuma das duas rotas gera mídia.

Ou deixar o diretor escrever o plano

POST …/:id/describe com { brief, llmModel, mode?, label?, clientRequestId? } inicia uma execução do diretor e retorna { jobId, production }. Quando o job terminar, chame reconcile para incorporar as tomadas rascunhadas.

const { production } = await client.studio.productions.create({ name: 'The Lighthouse' })
const { jobId } = await client.studio.productions.describe(production.id, {
  brief: 'A keeper, a storm, and a light that will not start.',
  llmModel: 'gpt-5-mini',
  mode: 'replace',
})
// poll jobId with client.jobs.getStatus, then:
await client.studio.productions.reconcile(production.id)

Planejar a exportação

GET /v1/studio/productions/:id/export-plan retorna os passos ordenados que montam o filme: as mesclagens de áudio por tomada, a junção e um acabamento opcional em 4K com upscale. A rota não executa nada.

{
  "canExport": true,
  "steps": [
    {
      "id": "voice-shot-2",
      "node": "merge-video-audio",
      "label": "Voice over shot 2",
      "credits": 20,
      "params": { "videoUrl": "https://cdn.nodaro.ai/studio/shot-2.mp4", "audioUrl": "https://cdn.nodaro.ai/studio/vo.mp3" }
    },
    {
      "id": "combine",
      "node": "combine-videos",
      "label": "Join 2 shots",
      "credits": 4,
      "params": {
        "videoUrls": [{ "fromStep": "voice-shot-2" }, "https://cdn.nodaro.ai/studio/shot-3.mp4"],
        "transition": "cut",
        "audioMode": "keep"
      }
    }
  ],
  "resultStepId": "combine",
  "estimate": 24,
  "unpriced": []
}

Execute os passos em ordem com as rotas comuns de nós, como Mesclar vídeo e áudio (Merge Video & Audio) e Combinar vídeos. Um valor { "fromStep": "…" } é a saída de um passo anterior: substitua-o pela URL que esse passo produziu. Depois, registre o arquivo final na produção como um corte, com a operação que adiciona um corte.

canExport é false quando não há nada para montar, ou seja, menos de dois clipes. estimate é null quando algum passo não tem preço, e unpriced indica esses modelos, porque uma soma parcial subestimaria o custo.

Compartilhar e copiar uma produção

  • Compartilhar. POST …/:id/share com { shared: true } ativa o link de compartilhamento somente leitura; { shared: false } ou POST …/:id/unshare o desativa. Só o dono ou um administrador do espaço de trabalho pode mudar o compartilhamento (caso contrário, 403 forbidden). Quando operations.revisionedSharing está disponível, adicione expectedVersion para vincular a mudança à versão que você revisou; uma edição mais nova então retorna 409 workflow_conflict.
  • Permitir cópias editáveis. Com operations.editableSharedCopies, o dono também pode enviar allowEditableCopy: true com shared: true e expectedVersion. Quem abrir o link com a sessão iniciada pode então copiar o plano, os prompts, as descrições do elenco, as entradas mantidas e o histórico de takes. A lixeira e as notas de revisão privadas não são copiadas, e desativar o compartilhamento impede novas cópias.
  • Copiar. POST …/:id/clone com { name? } copia uma produção a partir da sua própria visão dela. A cópia começa privada e não arquivada, e usa o seu armazenamento.

Exportar uma linha do tempo para um app de edição

POST /v1/freecut-export transforma uma linha do tempo de clipes de cenas em um arquivo de projeto de edição, para que você finalize a montagem em um app de edição externo. A rota grava um arquivo FreeCut JSON (freecut-v1) ou Final Cut Pro XML (fcpxml-v1.10) no seu armazenamento e retorna a URL dele. Ela não custa créditos e aceita 10 requisições por minuto. Como o resto desta página, ela exige o Nodaro Cloud; as outras edições retornam 404.

curl -X POST https://app.nodaro.ai/v1/freecut-export \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "format": "json",
    "name": "The Lighthouse, cut 1",
    "timeline": {
      "musicAssetUrl": "https://cdn.nodaro.ai/studio/score.mp3",
      "scenes": [
        {
          "sceneEntityId": "scene-1",
          "compositeUrl": "https://cdn.nodaro.ai/studio/scene-1.mp4",
          "shots": [{ "shot_id": "s1", "duration_seconds": 4 }]
        },
        {
          "sceneEntityId": "scene-2",
          "compositeUrl": "https://cdn.nodaro.ai/studio/scene-2.mp4",
          "shots": [{
            "shot_id": "s2",
            "duration_seconds": 6,
            "cut_decision": { "in_offset_sec": 0, "out_offset_sec": 0.5, "transition_to_next": "dissolve" }
          }]
        }
      ]
    }
  }'
const file = await client.request('POST', '/v1/freecut-export', {
  body: { format: 'json', name: 'The Lighthouse, cut 1', timeline },
})
{
  "url": "https://cdn.nodaro.ai/exports/7b2d4f6a/freecut-3c5e7a9b-1d2f-4a6c-8e3b-5f7a9c1e2d4b.json",
  "format": "json",
  "assetId": "1e3a5c7b-9d2f-4b4a-8c6e-5f7d9b1a3c2e"
}

assetId é a entrada do arquivo na sua biblioteca, ou null quando não foi possível criar essa entrada; a url é válida nos dois casos.

CampoO que guarda
formatObrigatório. json para FreeCut JSON ou fcpxml para Final Cut Pro XML.
timelineObrigatório. A linha do tempo, descrita abaixo.
nameUm rótulo para os seus registros, até 200 caracteres.
timeline.scenesObrigatório. Pelo menos uma cena, na ordem de reprodução. Cada cena vira um clipe na faixa de vídeo.
timeline.musicAssetUrlA faixa de música. Uma string vazia, o padrão, deixa a música de fora.
timeline.narrationAssetUrlUma faixa de narração, colocada em uma camada de áudio própria.
timeline.fadeOutDurationSecO fade no fim da música, 0,8 segundo por padrão. Só no FreeCut JSON.
scene.sceneEntityId, scene.compositeUrlObrigatórios. O ID da cena e o clipe mesclado dela.
scene.shotsObrigatório. Pelo menos uma tomada, { shot_id, duration_seconds, cut_decision? }. As durações das tomadas somam a duração da cena.
cut_decision.in_offset_sec, cut_decision.out_offset_secObrigatórios em uma decisão de corte. O recorte no início (lido da primeira tomada de uma cena) e no fim (lido da última tomada).
cut_decision.transition_to_nextObrigatório em uma decisão de corte. hard_cut, dissolve, match_cut ou overlap: a transição para a próxima cena.
cut_decision.transition_duration_secSubstitui a duração padrão da transição: 0 para hard_cut e match_cut, 0,5 segundo para dissolve, 1 segundo para overlap.

dissolve e overlap sobrepõem os dois clipes pela duração da transição; hard_cut e match_cut encostam um no outro. Quando nenhuma tomada tem cut_decision, a exportação é uma concatenação simples: um clipe por cena, um após o outro, com cortes secos e a música por toda a linha do tempo. Os recortes dentro de uma cena não são aplicados, porque cada clipe de cena já vem mesclado.

Registros para compartilhar e remixar

Um registro de tomada salva o estado de uma tomada que você montou: as escolhas dos seletores, os prompts, os modelos de destino, as entidades mencionadas com @ e os resultados. Ele fica atrás de um ID curto e impossível de adivinhar, que alimenta os links de compartilhamento /s/:id e os remixes com um clique. Estas rotas são separadas das produções.

MétodoCaminhoAutenticaçãoO que faz
POST/v1/shotsBearer tokenCria um registro. Retorna { id }.
GET/v1/shots/:idNenhumaLê um registro. Um registro privado retorna 404 para todos, menos para o dono. Limitado por endereço IP.
PATCH/v1/shots/:idDonoAtualiza quaisquer campos, inclusive visibility.
DELETE/v1/shots/:idDonoExclui o registro.

O corpo traz mode (single, multi-shot, frame-to-motion ou storyboard), selectionState (o valor escolhido em cada seletor, como { pickerNodeType: valueId } ou { pickerNodeType: { field: valueId } }) e, opcionalmente, freeText, negativePrompt, assembledPrompt, perModelPrompts, models, entityRefs e resultUrls. visibility é private por padrão; defina como public para tornar o registro compartilhável.

resultUrls aceita só URLs públicas simples, http ou https. URLs assinadas são recusadas, para que um token nunca vaze em um registro compartilhado. Os registros trazem um schemaVersion. Quando um registro indica uma entrada de catálogo que não existe mais, pule essa entrada com um aviso em vez de fazer o remix falhar.

curl -X POST https://app.nodaro.ai/v1/shots \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "single",
    "selectionState": { "mood": "melancholy", "lighting": { "timeOfDay": "blue-hour" } },
    "freeText": "a woman at a bus stop",
    "models": ["nano-banana-pro"],
    "visibility": "public"
  }'
const { id: shotId } = await client.shots.create({
  mode: 'single',
  selectionState: { mood: 'melancholy', lighting: { timeOfDay: 'blue-hour' } },
  freeText: 'a woman at a bus stop',
})
await client.shots.update(shotId, { visibility: 'public' })
const { shot } = await client.shots.get(shotId)
nodaro shots create --file shot.json --visibility public
nodaro shots get <id> --json
nodaro shots delete <id>

Usar pelo MCP

Os assistentes de IA usam as mesmas produções por meio de ferramentas como get_studio_production_skill, validate_studio_plan, create_studio_production, edit_studio_production, generate_studio_still, generate_studio_clip e plan_studio_export. Ler uma produção com acesso de escrita também incorpora os jobs concluídos. Veja Produções do Studio pelo MCP.

Erros

StatusCódigoSignificado
400validation_errorO corpo ou o plano está errado. path indica o campo; na rota de exportação, issues lista os problemas.
400op_invalid, op_target_missingEm …/ops: uma operação estava errada, e opIndex indica qual. Nada foi gravado. Corrija a operação e envie o lote de novo.
402insufficient_creditsA conta não tem créditos para cobrir a geração.
403forbiddenSó o dono ou um administrador do espaço de trabalho pode mudar o compartilhamento.
404not_foundNão existe essa produção para quem faz a chamada, ou a implantação não oferece produções.
404op_target_missingEm uma rota de geração ou de mídia: a tomada, o resultado ou o papel indicado não está na produção.
409workflow_conflictstrict: true ou expectedVersion foi enviado, e a produção mudou. Leia a produção de novo e reaplique.
409production_busyA produção continuou mudando durante a gravação. Leia a produção de novo e tente outra vez.
409sequence_quote_changedAs configurações ou os quadros de um clipe vinculado mudaram desde a cotação. Faça a cotação de novo.
413storage_exceededA conta passou do limite de armazenamento.
429rate_limit_exceededMais de 10 exportações de linha do tempo em um minuto. Espere o tempo indicado em Retry-After.

No SDK, esses erros chegam tipados: StudioOpError (com opIndex), WorkflowConflictError para os dois códigos 409 de uma gravação, InsufficientCreditsError, StorageExceededError e NotFoundError.

Perguntas frequentes

Última atualização

Nesta página