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

Personagens

Crie, atualize, arquive e restaure personagens via REST, gere candidatos a retrato, expressões, ângulos e clipes de movimento e aprove o retrato-âncora.

A API de personagens automatiza tudo o que o Estúdio de personagens faz. Você cria um personagem, gera candidatos a retrato, aprova um deles como retrato-âncora e adiciona expressões, ângulos, poses, variações de iluminação e clipes de movimento. Os nós de imagem e de vídeo então reaproveitam o personagem, para que a mesma pessoa tenha a mesma aparência em todas as tomadas.

As rotas funcionam em todas as edições. Elas aceitam um token Bearer: um token de API pessoal (ndr_…), um token de app OAuth (ndr_app_…) ou o token da sua sessão na Community Edition. Toda rota se limita a quem chama: você só vê e altera os seus próprios personagens. Veja Autenticação.

Endpoints

MétodoCaminhoO que faz
GET/v1/charactersLista os seus personagens, uma página por vez.
GET/v1/characters/:idRetorna um personagem com os jobs dele em andamento.
POST/v1/charactersCria um personagem, ou atualiza um quando o corpo tem um id.
POST/v1/characters/:id/duplicateCopia um personagem para um novo, com o sufixo (copy) no nome.
DELETE/v1/characters/:idArquiva um personagem. Ele pode ser restaurado.
POST/v1/characters/:id/restoreRestaura um personagem arquivado.
GET/v1/characters/:id/usageConta e lista os workflows que usam o personagem.
POST/v1/generate-characterGera de 1 a 10 candidatos a retrato.
POST/v1/generate-character-assetGera uma expressão, pose, ângulo ou variação de iluminação.
POST/v1/generate-character-motionAnima o personagem em um clipe de movimento.
POST/v1/characters/:id/approve-portraitAprova um candidato como retrato e escreve a descrição do personagem.
POST/v1/characters/:id/llm-captionEscreve a descrição de novo a partir do retrato atual.

Treinar um modelo dedicado com um personagem é um recurso do Nodaro Cloud com rotas próprias. Veja Treinamento de personagem.

O que um personagem contém

Um personagem é uma identidade salva. Os campos abaixo voltam de GET /v1/characters/:id em camelCase.

CampoO que contém
id, nameO identificador e o nome de exibição. Os nomes são únicos por conta, sem diferenciar maiúsculas de minúsculas.
description, gender, style, baseOutfitNotas de identidade que moldam todas as imagens geradas do personagem.
seedPromptUm prompt curto que enquadra o retrato, com até 4.000 caracteres.
sourceImageUrlO retrato-âncora. É definido quando você aprova um candidato.
canonicalDescriptionUma descrição visual de cerca de 80 a 120 palavras, escrita pelo Nodaro quando o retrato é aprovado. Os prompts que fazem referência ao personagem a incluem.
expressions, poses, angles, bodyAngles, lightingVariations, motionsOs grupos de mídias. Cada entrada é { name, url }.
referencePhotosAté 20 fotos reais, cada uma marcada com o enquadramento.
realLifeRefsByVariant, referenceVideosByVariantFotos ou clipes de referência extras para uma variação, por exemplo a expressão smile.
person, wardrobeEscolhas estruturadas de aparência e de figurino, definidas na página Seletores do Estúdio de personagens.
voice, personalityA voz e a personalidade do personagem.
identityLockCom que rigor as mídias geradas mantêm o rosto: off, soft ou strict. O padrão é off.
deletedAtDefinido quando o personagem é arquivado.

Os grupos de mídias

Cada grupo guarda variações do retrato-âncora. Você pode dar qualquer nome a uma variação; estes são os nomes predefinidos.

GrupoO que mostraVariações predefinidas
expressionsCabeça e ombros, com outra emoçãoneutral, smile, angry, surprised, sad, talking, laughing, disgusted, fearful, smirk, crying
anglesCabeça e ombros de outro ângulo de câmerafront, 3/4 left, left profile, right profile, 3/4 right
bodyAnglesCorpo inteiro de outro ângulo, com os braços relaxadosfront, 3/4 left, left profile, right profile, 3/4 right, back
posesCorpo inteiro em outra posturastanding, walking, sitting, running, crouching, pointing, fighting stance, jumping, turning
lightingVariationsA mesma pose sob outra luzdaylight, night, dramatic
motionsClipes de vídeo do personagem em movimentoQualquer rótulo, por exemplo walking ou head turn

Listar personagens

GET /v1/characters retorna uma página dos seus personagens, dos mais recentes para os mais antigos. Continue pedindo páginas até nextCursor ser null: uma única resposta nunca traz “todos os personagens” de uma conta que passa do tamanho da página.

Parâmetro de consultaO que faz
limitLinhas por página. O padrão é 100 e o máximo é 500.
cursorO nextCursor da página anterior.
projectIdSó os personagens de um projeto.
archivedtrue lista os personagens arquivados em vez dos ativos.
CURSOR=""
while :; do
  PAGE=$(curl -s "https://app.nodaro.ai/v1/characters?limit=100${CURSOR:+&cursor=$CURSOR}" \
    -H "Authorization: Bearer $NODARO_API_KEY")
  echo "$PAGE" | jq -r '.characters[] | "\(.id) \(.name)"'
  CURSOR=$(echo "$PAGE" | jq -r '.nextCursor // empty')
  [ -z "$CURSOR" ] && break
done
import { createClient, StaticTokenAuth } from '@nodaro/sdk'

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

const all = []
let cursor: string | undefined
do {
  const page = await client.characters.list({ limit: 100, cursor })
  all.push(...page.characters)
  cursor = page.nextCursor ?? undefined
} while (cursor)
nodaro characters list --limit 100 --json
nodaro characters list --archived
{
  "characters": [
    {
      "id": "3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94",
      "name": "Kira",
      "description": "young protagonist with auburn hair",
      "sourceImageUrl": "https://cdn.nodaro.ai/characters/kira-portrait.png",
      "expressions": [{ "name": "smile", "url": "https://cdn.nodaro.ai/characters/kira-smile.png" }]
    }
  ],
  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTA5LTIwVDEwOjAwOjAxWiJ9"
}

O cursor é opaco. Envie de volta apenas um nextCursor que o servidor deu a você, e nunca guarde um cursor de uma versão para outra. Um cursor malformado gera 400 validation_error, não uma volta silenciosa para a primeira página. Os personagens criados enquanto você pagina não são incluídos; comece de novo sem cursor para vê-los.

Criar ou atualizar um personagem

POST /v1/characters cria um personagem quando o corpo não tem id e atualiza o personagem quando tem. Uma criação precisa de nodeId e name. nodeId vincula o personagem a um nó do canvas; use qualquer rótulo, como "scripted", quando criar o personagem por código.

Em uma atualização, só os campos que você envia são gravados. Os campos omitidos mantêm os valores, então um salvamento nunca sobrescreve grupos de mídias que um job em execução está preenchendo. Envie um grupo de mídias só quando quiser substituí-lo.

curl -X POST https://app.nodaro.ai/v1/characters \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "nodeId": "scripted",
    "name": "Kira",
    "description": "young protagonist with auburn hair",
    "style": "realistic",
    "seedPrompt": "kira portrait, warm natural lighting"
  }'
const { id } = await client.characters.create({
  nodeId: 'scripted',
  name: 'Kira',
  description: 'young protagonist with auburn hair',
  style: 'realistic',
  seedPrompt: 'kira portrait, warm natural lighting',
})

await client.characters.update(id, { gender: 'female', identityLock: 'soft' })
nodaro characters create --name "Kira" \
  --description "young protagonist with auburn hair" \
  --style realistic --seed-prompt "kira portrait, warm natural lighting"

nodaro characters update <id> --gender female
{ "id": "3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94", "name": "Kira" }

Prop

Type

person e wardrobe moldam só as gerações do retrato e das mídias do próprio personagem. Eles usam os mesmos catálogos do seletor Pessoa (Person). Veja Catálogos de seletores.

Quando um workflow é executado, a voice do personagem preenche qualquer nó Texto para fala (Text to Speech) conectado depois do personagem: a voz, o tipo de voz e o modelo recomendado. Um valor definido no próprio nó Texto para fala tem prioridade.

Gerar candidatos a retrato

POST /v1/generate-character inicia um job por candidato e retorna os IDs deles na hora. Consulte cada job periodicamente com a API de jobs até ele estar completed.

Com attachToCharacterId, o primeiro candidato a terminar vira o retrato do personagem. Para um único candidato, isso é tudo de que você precisa. Para vários candidatos, aprove o que preferir; a aprovação substitui o retrato.

curl -X POST https://app.nodaro.ai/v1/generate-character \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Kira",
    "seedPrompt": "kira portrait, warm natural lighting",
    "count": 4,
    "attachToCharacterId": "3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94"
  }'
const { jobIds } = await client.characters.generate({
  name: 'Kira',
  seedPrompt: 'kira portrait, warm natural lighting',
  count: 4,
  attachToCharacterId: id,
})
nodaro characters generate <id> --count 4 \
  --seed-prompt "kira portrait, warm natural lighting" --watch
{
  "jobId": "a1c4e8f2-5b3d-4e6a-8f7c-2d9b1e0a3c5f",
  "jobIds": [
    "a1c4e8f2-5b3d-4e6a-8f7c-2d9b1e0a3c5f",
    "b7d2f9a1-6c4e-4a8b-9d3f-3e0c2f1b4d6a",
    "c3e5a7b9-8d1f-4c2e-a6b8-4f1d3a2c5e7b",
    "d9f1b3c5-2e4a-4d6f-b8c1-5a2e4b3d6f8c"
  ]
}

Prop

Type

quality e resolution definem o preço do job exatamente como no Gerar imagem (Generate Image): uma execução em 4K ou de alta qualidade custa mais que o mesmo modelo no nível básico. Um valor que o modelo não aceita é trocado pelo mais próximo que ele aceita, nunca recusado, e os créditos seguem o valor trocado. Essas rotas não retornam uma lista adjustments; leia o valor que foi executado no input_data do job, em GET /v1/jobs/:id.

Gerar uma variação de expressão, ângulo, pose ou iluminação

POST /v1/generate-character-asset gera uma variação do retrato-âncora e retorna { jobId }. Para adicionar o resultado ao personagem, envie os três campos de anexo: attachToCharacterId, attachToColumn e attachName. Quando o job termina, o worker acrescenta { name: attachName, url } a esse grupo.

curl -X POST https://app.nodaro.ai/v1/generate-character-asset \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Kira",
    "assetType": "expressions",
    "variant": "smile",
    "attachToCharacterId": "3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94",
    "attachToColumn": "expressions",
    "attachName": "smile"
  }'
await client.characters.generateAsset({
  name: 'Kira',
  assetType: 'bodyAngles',
  variant: 'front',
  attachToCharacterId: id,
  attachToColumn: 'body_angles',
  attachName: 'front',
})
nodaro characters generate-asset <id> --asset-type expressions --variant smile --watch
CampoO que faz
nameObrigatório. O nome do personagem.
assetTypeObrigatório. expressions, poses, lighting, headAngles, angles (igual a headAngles), bodyAngles ou custom.
variantObrigatório. A variação a gerar, de 1 a 100 caracteres, por exemplo smile ou 3/4 left.
descriptionUma descrição de uma frase desta variação, com até 1.000 caracteres. Quando você anexa a um personagem e omite este campo, o Nodaro rascunha uma a partir da descrição canônica do personagem.
sourceImageUrlA imagem a variar, normalmente o retrato aprovado.
provider, quality, resolutionO modelo de imagem e o nível de saída dele, com preço igual ao do Gerar imagem.
aspectRatio1:1, 3:4, 16:9 ou 9:16. O padrão depende do tipo: 1:1 para expressões, 9:16 para poses e ângulos do corpo e 3:4 para os demais.
attachToCharacterId, attachToColumn, attachNamePara onde vai o resultado. attachToColumn é expressions, poses, angles, body_angles ou lighting_variations. Uma variação custom precisa indicar a coluna.

Quando você anexa a variação a um personagem, as fotos reais salvas na chave da variação em realLifeRefsByVariant são enviadas com a requisição automaticamente.

Animar o personagem

POST /v1/generate-character-motion transforma uma imagem fixa do personagem em um clipe de vídeo e retorna { jobId }. Com attachToCharacterId e attachName, o clipe é acrescentado ao grupo motions quando termina.

Quando você anexa a um personagem, o Nodaro escolhe o quadro inicial nesta ordem:

  1. O sourceImageUrl que você envia, que sempre tem prioridade.
  2. A entrada front de bodyAngles. Um quadro de corpo inteiro fica muito melhor animado do que um retrato de cabeça e ombros.
  3. Qualquer outra entrada de bodyAngles, da mais recente para a mais antiga.
  4. O retrato-âncora.

Para obter os melhores clipes, gere um ângulo do corpo front antes do primeiro movimento.

curl -X POST https://app.nodaro.ai/v1/generate-character-motion \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Kira",
    "motionPrompt": "slow head turn left, soft smile",
    "provider": "kling",
    "attachToCharacterId": "3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94",
    "attachName": "head turn"
  }'
await client.characters.generateMotion({
  name: 'Kira',
  motionPrompt: 'slow head turn left, soft smile',
  provider: 'kling',
  attachToCharacterId: id,
  attachName: 'head turn',
})
nodaro characters generate-motion <id> \
  --motion-prompt "slow head turn left, soft smile" --attach-name "head turn" --watch
CampoO que faz
nameObrigatório. O nome do personagem.
motionPromptObrigatório. O que se move e como, de 1 a 2.000 caracteres.
providerO modelo de vídeo: kling (o padrão), kling-turbo, kling-3.0, wan-i2v ou wan-2.7-i2v.
sourceImageUrlO quadro inicial. Obrigatório quando você não anexa a um personagem.
description, motionDescriptionUma descrição visual (até 1.000 caracteres) e uma descrição do movimento (até 500). O Nodaro rascunha as duas quando você anexa e as omite.
aspectRatio1:1, 3:4, 16:9 ou 9:16. O padrão é 9:16, um clipe vertical de corpo inteiro.
attachToCharacterId, attachNameO personagem e o nome do clipe em motions.

Estes modelos podem animar um personagem. O preço é o preço de imagem para vídeo do modelo:

ModeloDesenvolvedorModosCréditosDetalhes
Kling 2.6KuaishouImagem para vídeo, Texto para vídeoa partir de 152Kling 2.6 I2V — movimento muito realista. Clipes de 5 ou 10 s, com áudio nativo opcional.
Kling 2.5 Turbo ProKuaishouImagem para vídeo, Texto para vídeoa partir de 121Kling mais rápido — boa qualidade por um custo menor. Aceita quadro final.
Kling 3.0KuaishouImagem para vídeo, Texto para vídeoa partir de 297Kling 3.0 premium — duração variável de 3 a 15 s, áudio nativo, 720P/1080P.
Wan 2.6 I2VAlibabaImagem para vídeoa partir de 193Wan 2.6 de imagem para vídeo — 5, 10 ou 15 s em 720p/1080p.
Wan 2.7 I2VAlibabaImagem para vídeo207Wan 2.7 de imagem para vídeo — de 2 a 15 s em 720p/1080p, com suporte a quadro inicial e final.

Aprovar um retrato

POST /v1/characters/:id/approve-portrait define um candidato concluído como o retrato-âncora. Na mesma chamada, o Nodaro analisa o retrato e escreve canonicalDescription, o texto que os prompts seguintes usam para descrever o personagem. Sem essa descrição, um personagem varia muito mais de uma cena para outra.

O candidato precisa ser um job completed que pertence a você. Se a escrita da descrição falhar, o retrato continua definido e canonicalDescription fica null; chame POST /v1/characters/:id/llm-caption para tentar de novo. As duas rotas podem ser repetidas com segurança. Aprovar é gratuito. Cada chamada de llm-caption custa 8 créditos, e uma chamada com falha (502) é reembolsada.

curl -X POST https://app.nodaro.ai/v1/characters/3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94/approve-portrait \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "candidateJobId": "b7d2f9a1-6c4e-4a8b-9d3f-3e0c2f1b4d6a" }'
const { portraitUrl, canonicalDescription } =
  await client.characters.approvePortrait(id, jobIds[1])

if (canonicalDescription === null) {
  await client.characters.recaption(id)
}
nodaro characters approve-portrait <id> --job <jobId>
nodaro characters recaption <id>
{
  "portraitUrl": "https://cdn.nodaro.ai/characters/kira-portrait-2.png",
  "canonicalDescription": "Kira is a woman in her mid-twenties with shoulder-length auburn hair, green eyes and light freckles..."
}

llm-caption retorna { canonicalDescription }. A rota responde 400 no_portrait quando o personagem ainda não tem retrato e 502 quando não foi possível escrever a descrição.

Arquivar, restaurar e copiar um personagem

  • Arquivar. DELETE /v1/characters/:id arquiva o personagem e retorna { success: true, archived: true }. O personagem sai da lista padrão, mas GET /v1/characters/:id continua retornando o personagem, então os workflows que o usam continuam funcionando. No Nodaro Cloud, arquivar também cancela um treinamento em andamento, reembolsa os créditos dele e remove o modelo treinado.
  • Restaurar. POST /v1/characters/:id/restore retorna { id, name }. Quando um personagem ativo já tem o mesmo nome, o Nodaro adiciona o sufixo (restored) e retorna o novo nome.
  • Excluir para sempre. Nenhuma rota da API exclui um personagem permanentemente. Use a visualização de arquivados na biblioteca do editor.
  • Copiar. POST /v1/characters/:id/duplicate retorna { id, name } de um novo personagem com o sufixo (copy). A cópia compartilha as URLs das mídias do original até você gerá-las de novo.
  • Uso. GET /v1/characters/:id/usage retorna { workflowCount, workflows: [{ id, name }] }. Verifique o uso antes de arquivar um personagem.
AçãocurlTypeScript SDKCLI
ArquivarDELETE /v1/characters/:idclient.characters.delete(id)nodaro characters delete <id>
RestaurarPOST /v1/characters/:id/restoreclient.characters.restore(id)nodaro characters restore <id>
CopiarPOST /v1/characters/:id/duplicateclient.characters.duplicate(id)nodaro characters duplicate <id>
UsoGET /v1/characters/:id/usageclient.characters.usage(id)nodaro characters usage <id>

Um fluxo completo: criar, gerar, aprovar e adicionar variações

Criar o personagem

POST /v1/characters com nodeId, name e um seedPrompt. Guarde o id retornado.

Gerar candidatos a retrato

POST /v1/generate-character com count: 4 e attachToCharacterId. Consulte periodicamente cada job pelo ID até ele estar completed ou failed.

Aprovar o seu favorito

POST /v1/characters/:id/approve-portrait com o ID do job desse candidato. O retrato e a descrição canônica são definidos.

Adicionar variações e movimento

Gere um ângulo do corpo front e, depois, expressões e poses com POST /v1/generate-character-asset, e clipes com POST /v1/generate-character-motion.

Usar o personagem em outras gerações

Depois que as mídias existirem, envie as URLs delas como imagens de referência para o Gerar imagem ou o Gerar vídeo (Generate Video). Por exemplo, leia a entrada smile de expressions e envie a URL dela como referência com o seu prompt. URLs explícitas são a opção mais simples no código, porque não dependem de como um workflow está conectado. Veja Executar um único nó para os campos da requisição.

Em um workflow, conecte o nó Personagem (Character Asset) ao nó de imagem ou de vídeo, ou mencione o personagem no prompt com @, por exemplo @kira:1:smile. Papéis de referência explica a sintaxe das menções, e Personagens consistentes, o método completo.

Uso pelo MCP

Os assistentes de IA usam as mesmas rotas por meio destas ferramentas. Arquivar e restaurar não estão disponíveis pelo MCP, de propósito.

FerramentaO que faz
list_characters, get_characterEncontra um personagem e lê as URLs das mídias dele.
create_character, update_characterCria um personagem ou muda os campos de identidade dele.
generate_characterGera um retrato (kind: "main") ou uma variação (kind: "asset").
generate_character_motionAnima o personagem em um clipe.
approve_portrait, recaption_characterAprova um retrato ou escreve a descrição dele de novo.

Veja a Referência das ferramentas MCP.

Créditos

No Nodaro Cloud, a geração de personagens usa os mesmos preços em créditos dos nós correspondentes.

RotaPreço
POST /v1/generate-characterO preço do modelo de imagem vezes count, reservado para todos os candidatos antes de o primeiro job começar.
POST /v1/generate-character-assetO preço do modelo de imagem, por variação.
POST /v1/generate-character-motionO preço de imagem para vídeo do modelo de vídeo, por clipe.
approve-portraitGratuito.
llm-caption8 créditos por chamada.

A página de cada modelo informa o preço exato. Veja Créditos.

Erros

Os erros usam o envelope padrão, { "error": { "code", "message" } }. Veja Erros.

StatusCódigoSignificado
400validation_errorUm campo está ausente ou é inválido, um cursor está malformado, ou uma requisição de geração não tem seedPrompt, description nem referencePhotos.
400no_portraitllm-caption foi chamado antes de o personagem ter um retrato.
401unauthorizedO token está ausente, é inválido ou foi revogado.
402insufficient_creditsSó no Nodaro Cloud. A conta não cobre a reserva.
404not_foundNenhum personagem ou job com esse ID pertence a você.
409name_takenOutro personagem ativo já tem esse nome.
502—Não foi possível escrever a descrição canônica. O retrato não muda. Tente de novo.

Perguntas frequentes

Última atualização

Nesta página