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

Locais

Pela API REST, crie e arquive locais e gere planos de estabelecimento, variações de hora do dia, tempo e ângulo, vistas de 360° e clipes de movimento.

A API de locais automatiza tudo o que o Estúdio de locais faz. Você cria um local, gera candidatos a plano de estabelecimento, aprova um deles e adiciona variações de hora do dia, tempo, estação, ângulo de câmera e iluminação, além de clipes de atmosfera em loop. Os nós de imagem e de vídeo então reaproveitam o local, para que o mesmo beco ou a mesma biblioteca tenha a mesma aparência em todas as tomadas.

As rotas funcionam em todas as edições, exceto a rota de vista de 360 graus, que precisa do Nodaro Cloud. 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. Veja Autenticação.

Endpoints

MétodoCaminhoO que faz
GET/v1/locationsLista os seus locais.
GET/v1/locations/:idRetorna um local com os jobs dele em andamento e os candidatos recentes.
POST/v1/locationsCria um local, ou atualiza um quando o corpo tem um id.
DELETE/v1/locations/:idArquiva um local. Ele pode ser restaurado.
DELETE/v1/locations/:id?permanent=trueExclui para sempre um local arquivado e os arquivos dele.
POST/v1/locations/:id/restoreRestaura um local arquivado.
POST/v1/generate-locationGera de 1 a 10 candidatos a plano de estabelecimento.
POST/v1/generate-location-assetGera uma variação de hora do dia, tempo, estação, ângulo, iluminação ou personalizada.
POST/v1/generate-surround-continuationNodaro Cloud. Gera a próxima vista de um giro de 360 graus.
POST/v1/generate-location-motionAnima o plano de estabelecimento em um clipe de atmosfera.
POST/v1/locations/:id/approve-main-imageAprova um candidato como imagem principal e escreve a descrição do local.
POST/v1/locations/:id/llm-captionEscreve a descrição de novo a partir da imagem principal atual.

O que um local contém

CampoO que contém
id, name, descriptionO identificador, o nome de exibição e as notas de identidade.
categoryindoor, outdoor, urban, nature, fantasy, sci-fi, historical, futuristic ou other.
stylerealistic, anime, 3d-pixar ou illustration.
sourceImageUrlO plano de estabelecimento âncora, definido quando você aprova um candidato.
canonicalDescriptionUma descrição visual de cerca de 80 a 120 palavras, escrita pelo Nodaro quando a imagem principal é aprovada. Até lá, é uma string vazia.
styleLockSe as variações são geradas a partir da imagem principal. true por padrão.
timeOfDay, weather, seasons, angles, lighting, atmosphereMotionsOs grupos de mídias. Cada entrada é { name, url }; atmosphereMotions guarda vídeos.
referencePhotosAté 20 fotos do painel de inspiração, cada uma { kind, url }.
piiConsentAtQuando você confirmou o consentimento para as fotos de referência, ou null.
pendingJobs, previousCandidatesSó em GET /v1/locations/:id: os jobs de variações ainda em execução e até 5 candidatos recentes a imagem principal, dos mais recentes para os mais antigos.

Os grupos de mídias

GrupoO que mostraVariações predefinidas
timeOfDayO mesmo quadro em outro horáriodawn, morning, noon, afternoon, golden hour, dusk, blue hour, night, midnight
weatherO mesmo quadro com outro tempoclear, cloudy, light rain, heavy rain, storm, snow, blizzard, fog, mist
seasonsO mesmo quadro em outra estaçãospring, summer, autumn, winter
anglesO lugar de outro ângulo de câmerawide, medium, closeup, aerial, low-angle, eye-level, bird's-eye, dutch tilt
lightingOutra configuração de iluminaçãosoft natural, harsh sunlight, golden, blue hour, neon, candlelit, cinematic, dramatic chiaroscuro
atmosphereMotionsMovimentos de câmera ambientes em loopslow dolly-in, slow pan-left, slow pan-right, push up, drone fly-over, gentle drift, parallax, static atmospheric

Um painel de inspiração acompanha o local. Todo nó que usa o local recebe essas fotos como referências extras. O kind de cada foto diz ao modelo para que a foto serve:

kindPara que serve
wideUma vista mais ampla do mesmo lugar.
interior, exteriorO interior quando a imagem principal mostra o exterior, ou o contrário.
detailUm detalhe marcante, como uma estátua, uma placa ou um material.
moodBoardA paleta ou a sensação.
otherQualquer outra coisa.

Você pode adicionar até 20 fotos, com qualquer quantidade de cada tipo.

As fotos de referência podem mostrar o rosto de pessoas. Quando anexar fotos a um local pela primeira vez, defina também piiConsentAt com o horário atual. Esse campo registra que você tem os direitos e o consentimento para usar as fotos. Enquanto ele for null, o editor pede o consentimento na próxima vez que alguém abrir o local.

Listar e ler locais

GET /v1/locations retorna os seus locais ativos. Adicione archived=true para ver os arquivados. Sem limit, a rota retorna a lista completa. Com limit (no máximo 500), ela retorna uma página e um nextCursor para enviar de volta como cursor até ele ser null.

GET /v1/locations/:id retorna um local, arquivado ou não, então os workflows que usam um local arquivado continuam funcionando.

curl "https://app.nodaro.ai/v1/locations?limit=100" \
  -H "Authorization: Bearer $NODARO_API_KEY"

curl https://app.nodaro.ai/v1/locations/9a1d3f5b-7c2e-4a8d-b6f1-3e5c7a9b2d4f \
  -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 { locations } = await client.locations.list()
const alley = await client.locations.get(locations[0].id)
console.log(alley.previousCandidates)
nodaro locations list --json
nodaro locations get <id> --json

Criar ou atualizar um local

POST /v1/locations cria um local quando o corpo não tem id e o atualiza quando tem. Uma criação precisa de nodeId e name; use qualquer rótulo em nodeId, como "scripted", quando não houver um nó no canvas.

Em uma atualização, só os campos que você envia são gravados, e os grupos de mídias nunca são gravados. Envie expectedUpdatedAt, o updatedAt atual do local, para que a atualização seja recusada com 409 concurrent_modification quando alguém tiver alterado o local depois que você o leu.

curl -X POST https://app.nodaro.ai/v1/locations \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "nodeId": "scripted",
    "name": "Rainy Tokyo Alley",
    "description": "Neon-soaked alley with vending machines and wet pavement",
    "category": "urban",
    "style": "realistic"
  }'
const { id } = await client.locations.create({
  nodeId: 'scripted',
  name: 'Rainy Tokyo Alley',
  description: 'Neon-soaked alley with vending machines and wet pavement',
  category: 'urban',
  style: 'realistic',
})

const location = await client.locations.get(id)
await client.locations.update(id, {
  referencePhotos: [{ kind: 'wide', url: 'https://cdn.nodaro.ai/uploads/alley-wide.jpg' }],
  piiConsentAt: new Date().toISOString(),
  expectedUpdatedAt: location.updatedAt,
})
nodaro locations create "Rainy Tokyo Alley" --node-id scripted \
  --description "Neon-soaked alley with vending machines and wet pavement" \
  --category urban --style realistic

nodaro locations update <id> --style-lock false

Prop

Type

Uma criação retorna { id }.

O Bloqueio de estilo (Style Lock) decide como as variações são feitas. Com o Bloqueio de estilo ativado, o padrão, toda variação é gerada a partir da imagem principal aprovada, então o prédio, os materiais e a composição continuam iguais. Com o Bloqueio de estilo desativado, as variações são geradas só a partir de texto e podem reinterpretar o lugar.

Gerar candidatos a plano de estabelecimento

POST /v1/generate-location inicia um job por candidato e retorna jobIds. Uma requisição de um único candidato também retorna jobId.

  • Um candidato, anexado. Com attachToLocationId e count igual a 1, o resultado vira a imagem principal quando o job termina.
  • Vários candidatos. Nada é anexado. A imagem principal atual continua, e os candidatos concluídos aparecem em previousCandidates em GET /v1/locations/:id. Aprove o que preferir.
  • Editar o plano atual. userPrompt é uma instrução avulsa, por exemplo “add rain and puddles”. Com sourceImageUrl, a imagem de origem é editada de acordo com a instrução. A instrução nunca é salva no local.
curl -X POST https://app.nodaro.ai/v1/generate-location \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Rainy Tokyo Alley",
    "count": 1,
    "attachToLocationId": "9a1d3f5b-7c2e-4a8d-b6f1-3e5c7a9b2d4f"
  }'
const { jobIds } = await client.locations.generate({
  name: 'Rainy Tokyo Alley',
  description: 'Neon-soaked alley with vending machines',
  count: 4,
})
nodaro locations generate --name "Rainy Tokyo Alley" --count 1 \
  --attach-to-location-id <id> --watch
{ "jobId": "4d6f8b1a-3c5e-4f7a-9b2d-6e8a1c3f5b7d", "jobIds": ["4d6f8b1a-3c5e-4f7a-9b2d-6e8a1c3f5b7d"] }
CampoO que faz
nameObrigatório. O nome do local.
description, category, styleA identidade do local.
countCandidatos a gerar, de 1 a 10. O padrão é 1.
userPromptUma instrução avulsa que conduz esta geração. Nunca é salva.
sourceImageUrlUma imagem para editar ou usar como ponto de partida.
providerO ID do modelo de imagem. Omita para usar o modelo padrão.
quality, resolutionO nível de saída do modelo de imagem, com preço igual ao do Gerar imagem (Generate Image).
attachToLocationIdAnexa um único candidato a este local.

quality e resolution funcionam como nos personagens: um valor que o modelo não aceita é trocado pelo valor aceito mais próximo, e os créditos seguem o valor trocado. O input_data do job mostra o valor que foi executado.

Gerar uma variação

POST /v1/generate-location-asset gera uma variação e retorna { jobId }. Envie attachToLocationId, attachToColumn e attachName para acrescentar { name: attachName, url } ao grupo quando o job terminar.

curl -X POST https://app.nodaro.ai/v1/generate-location-asset \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Rainy Tokyo Alley",
    "assetType": "weather",
    "variant": "storm",
    "attachToLocationId": "9a1d3f5b-7c2e-4a8d-b6f1-3e5c7a9b2d4f",
    "attachToColumn": "weather",
    "attachName": "storm"
  }'
await client.locations.generateAsset({
  name: 'Rainy Tokyo Alley',
  assetType: 'timeOfDay',
  variant: 'blue hour',
  attachToLocationId: id,
  attachToColumn: 'time_of_day',
  attachName: 'blue hour',
})
nodaro locations generate-asset <id> --asset-type weather --variant storm --watch

assetType é timeOfDay, weather, seasons, angles, lighting ou custom. attachToColumn é time_of_day, weather, seasons, angles ou lighting, e uma variação custom precisa indicar essa coluna. A rota também aceita provider, quality, resolution e sourceImageUrl.

Montar uma vista de 360 graus

POST /v1/generate-surround-continuation monta um giro de 360 graus uma vista por vez, por exemplo a cada 45 graus. Cada chamada continua a vista anterior. O Nodaro reaproveita a borda dessa vista no novo quadro e pinta só o resto. Depois, ajusta a exposição e a cor da parte pintada à parte reaproveitada. A parte reaproveitada fica idêntica pixel a pixel, então vistas vizinhas se alinham em um visualizador de panoramas. Esta rota precisa do Nodaro Cloud; as outras edições respondem 403 edition_required.

curl -X POST https://app.nodaro.ai/v1/generate-surround-continuation \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "referenceImageUrl": "https://cdn.nodaro.ai/locations/alley-main.png",
    "direction": "right",
    "degrees": 45,
    "provider": "nano-banana-pro",
    "aspectRatio": "16:9",
    "attachToLocationId": "9a1d3f5b-7c2e-4a8d-b6f1-3e5c7a9b2d4f",
    "attachToColumn": "angles",
    "attachName": "Surround 45°"
  }'
const { jobId } = await client.locations.generateSurroundContinuation({
  referenceImageUrl: previousView,
  direction: 'right',
  degrees: 45,
  provider: 'nano-banana-pro',
  aspectRatio: '16:9',
  attachToLocationId: id,
  attachToColumn: 'angles',
  attachName: 'Surround 45°',
})
CampoO que faz
referenceImageUrlObrigatório. A vista anterior a partir da qual continuar.
directionObrigatório. right ou left para girar, up ou down para inclinar.
degreesO ângulo desta vista, de 0 a 360, salvo com o resultado.
carriedFractionQuanto do quadro é reaproveitado da vista anterior, de 0,1 a 0,9. O padrão é 0,5 para um giro e uma faixa fina para uma inclinação.
provider, aspectRatioO modelo de imagem e o quadro. O editor usa nano-banana-pro e 16:9 para que todas as vistas combinem com o plano de estabelecimento.
attachToLocationId, attachToColumn, attachNameAnexam a vista, normalmente ao grupo angles.

Cada vista custa uma geração no modelo de imagem escolhido. O reaproveitamento da borda e o ajuste de cor não são cobrados à parte.

Animar o plano de estabelecimento

POST /v1/generate-location-motion transforma o plano de estabelecimento em um clipe de ambiente: neblina se movendo, um dolly lento, um sobrevoo de drone. A rota retorna { jobId }. sourceImageUrl é obrigatório; envie a imagem principal aprovada. Com attachToLocationId e attachName, o clipe é acrescentado a atmosphereMotions; você não envia uma coluna.

curl -X POST https://app.nodaro.ai/v1/generate-location-motion \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Rainy Tokyo Alley",
    "motionPrompt": "slow dolly-in, neon signs flicker, light rain falling",
    "sourceImageUrl": "https://cdn.nodaro.ai/locations/alley-main.png",
    "provider": "kling",
    "attachToLocationId": "9a1d3f5b-7c2e-4a8d-b6f1-3e5c7a9b2d4f",
    "attachName": "neon dolly-in"
  }'
await client.locations.generateMotion({
  name: 'Rainy Tokyo Alley',
  motionPrompt: 'slow dolly-in, neon signs flicker, light rain falling',
  sourceImageUrl: location.sourceImageUrl!,
  provider: 'kling',
  attachToLocationId: id,
  attachName: 'neon dolly-in',
})
nodaro locations generate-motion --name "Rainy Tokyo Alley" \
  --motion-prompt "slow dolly-in, neon signs flicker, light rain falling" \
  --source-image-url "https://cdn.nodaro.ai/locations/alley-main.png" \
  --provider kling --attach-to-location-id <id> --attach-name "neon dolly-in" --watch
CampoO que faz
name, motionPromptObrigatórios. O nome do local e o movimento a criar.
sourceImageUrlObrigatório. O quadro inicial.
providerkling (o padrão), kling-turbo, kling-3.0, wan-i2v, wan-2.7-i2v ou seedance-2.
aspectRatio16:9 (o padrão), 1:1, 3:4 ou 9:16.
refineFromVideoUrlUm clipe existente para refinar com o novo prompt, por exemplo para transformar neblina em chuva sem mover a câmera. Use um modelo que aceite vídeo para vídeo, como wan-i2v.
attachToLocationId, attachNameO local e o nome do clipe em atmosphereMotions.
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.
Seedance 2BytedanceImagem para vídeo, Texto para vídeoa partir de 253Seedance 2 — nível premium com áudio nativo. Preço por segundo conforme a resolução.

Aprovar uma imagem principal

POST /v1/locations/:id/approve-main-image com { candidateJobId } define um candidato concluído como imagem principal e escreve canonicalDescription na mesma chamada. A rota retorna { sourceImageUrl, canonicalDescription }.

Quando a escrita da descrição falha, a imagem principal continua definida e canonicalDescription é uma string vazia; o SDK retorna null. Chame POST /v1/locations/:id/llm-caption para tentar de novo. A rota retorna { canonicalDescription }, responde 502 quando não consegue escrever a descrição e 400 no_source_image quando ainda não há imagem principal. 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/locations/9a1d3f5b-7c2e-4a8d-b6f1-3e5c7a9b2d4f/approve-main-image \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "candidateJobId": "4d6f8b1a-3c5e-4f7a-9b2d-6e8a1c3f5b7d" }'
const { sourceImageUrl, canonicalDescription } =
  await client.locations.approveMainImage(id, jobIds[2])
nodaro locations approve-main-image <id> --candidate-job-id <jobId>
nodaro locations recaption <id>

Arquivar, restaurar e excluir um local

AçãocurlTypeScript SDKCLI
ArquivarDELETE /v1/locations/:idclient.locations.delete(id)nodaro locations delete <id>
RestaurarPOST /v1/locations/:id/restoreclient.locations.restore(id)nodaro locations restore <id>
Excluir para sempreDELETE /v1/locations/:id?permanent=trueNão disponívelNão disponível
  • Arquivar retorna { success: true, archived: true }. O local sai da lista padrão, mas continua carregando pelo ID.
  • Restaurar retorna { id, name }, com o sufixo (restored) quando um local ativo tem o mesmo nome, sem diferenciar maiúsculas de minúsculas.
  • Excluir para sempre só funciona em um local arquivado (caso contrário, 400 not_archived) e remove o local e todos os arquivos a que ele faz referência. O SDK e a CLI não oferecem essa ação; a visualização de arquivados do editor pede que você digite o nome para confirmar.

Escolher uma variação ao executar um app

Quando um workflow com um nó Local (Location Asset) é publicado como app, o local vira uma das entradas do app. Envie "<bucket>/<variant>", por exemplo "weather/light-rain", para usar essa variação como a imagem principal do local na execução. Escreva o nome da variação em minúsculas, com hífens no lugar dos espaços. Com um grupo ou uma variação desconhecidos, a execução usa a imagem principal.

Usar o local em outras gerações

Envie as URLs das mídias do local como imagens de referência para o Gerar imagem ou o Gerar vídeo (Generate Video); URLs explícitas são a opção mais simples no código. Em um workflow, conecte o nó do local ao nó de imagem, ou mencione uma variação no prompt, por exemplo @oldlibrary:1:weather/rain para um local chamado Old Library. Sem menção, o Nodaro procura nomes de variações no seu prompt: “at sunset” seleciona uma variação dusk, quando você tem uma. Veja Locais.

Uso pelo MCP

FerramentaO que faz
list_locations, get_locationEncontra um local e lê as URLs das variações dele.
create_location, update_locationCria um local ou muda os campos de identidade dele.
generate_locationGera uma imagem principal (kind: "main") ou uma variação (kind: "asset").
generate_location_motionAnima a imagem principal.
approve_main_image, recaption_locationAprova uma imagem principal ou escreve a descrição dela de novo.

Arquivar e restaurar não estão disponíveis pelo MCP, de propósito. Veja a Referência das ferramentas MCP.

Créditos

RotaPreço no Nodaro Cloud
POST /v1/generate-locationO preço do modelo de imagem vezes count, reservado para todos os candidatos antes de o primeiro job começar.
POST /v1/generate-location-assetO preço do modelo de imagem, por variação.
POST /v1/generate-surround-continuationO preço do modelo de imagem, por vista.
POST /v1/generate-location-motionO preço de imagem para vídeo do modelo de vídeo, por clipe.
approve-main-imageGratuito.
llm-caption8 créditos por chamada.

Erros

StatusCódigoSignificado
400validation_errorUm campo está ausente ou é inválido.
400not_archivedUma exclusão permanente foi enviada para um local que não está arquivado.
400no_source_imagellm-caption foi chamado antes de o local ter uma imagem principal.
401unauthorizedO token está ausente, é inválido ou foi revogado.
402insufficient_creditsSó no Nodaro Cloud. A conta não cobre a reserva.
403edition_requiredA rota de vista de 360 graus foi chamada na Community Edition ou na Business edition.
404not_foundNenhum local com esse ID pertence a você.
409concurrent_modificationexpectedUpdatedAt não corresponde mais. Leia o local de novo, mescle as mudanças e tente de novo.
502—Não foi possível escrever a descrição canônica. Tente de novo.

Perguntas frequentes

Última atualização

Nesta página