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étodo | Caminho | O que faz |
|---|---|---|
GET | /v1/locations | Lista os seus locais. |
GET | /v1/locations/:id | Retorna um local com os jobs dele em andamento e os candidatos recentes. |
POST | /v1/locations | Cria um local, ou atualiza um quando o corpo tem um id. |
DELETE | /v1/locations/:id | Arquiva um local. Ele pode ser restaurado. |
DELETE | /v1/locations/:id?permanent=true | Exclui para sempre um local arquivado e os arquivos dele. |
POST | /v1/locations/:id/restore | Restaura um local arquivado. |
POST | /v1/generate-location | Gera de 1 a 10 candidatos a plano de estabelecimento. |
POST | /v1/generate-location-asset | Gera uma variação de hora do dia, tempo, estação, ângulo, iluminação ou personalizada. |
POST | /v1/generate-surround-continuation | Nodaro Cloud. Gera a próxima vista de um giro de 360 graus. |
POST | /v1/generate-location-motion | Anima o plano de estabelecimento em um clipe de atmosfera. |
POST | /v1/locations/:id/approve-main-image | Aprova um candidato como imagem principal e escreve a descrição do local. |
POST | /v1/locations/:id/llm-caption | Escreve a descrição de novo a partir da imagem principal atual. |
O que um local contém
| Campo | O que contém |
|---|---|
id, name, description | O identificador, o nome de exibição e as notas de identidade. |
category | indoor, outdoor, urban, nature, fantasy, sci-fi, historical, futuristic ou other. |
style | realistic, anime, 3d-pixar ou illustration. |
sourceImageUrl | O plano de estabelecimento âncora, definido quando você aprova um candidato. |
canonicalDescription | Uma descrição visual de cerca de 80 a 120 palavras, escrita pelo Nodaro quando a imagem principal é aprovada. Até lá, é uma string vazia. |
styleLock | Se as variações são geradas a partir da imagem principal. true por padrão. |
timeOfDay, weather, seasons, angles, lighting, atmosphereMotions | Os grupos de mídias. Cada entrada é { name, url }; atmosphereMotions guarda vídeos. |
referencePhotos | Até 20 fotos do painel de inspiração, cada uma { kind, url }. |
piiConsentAt | Quando você confirmou o consentimento para as fotos de referência, ou null. |
pendingJobs, previousCandidates | Só 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
| Grupo | O que mostra | Variações predefinidas |
|---|---|---|
timeOfDay | O mesmo quadro em outro horário | dawn, morning, noon, afternoon, golden hour, dusk, blue hour, night, midnight |
weather | O mesmo quadro com outro tempo | clear, cloudy, light rain, heavy rain, storm, snow, blizzard, fog, mist |
seasons | O mesmo quadro em outra estação | spring, summer, autumn, winter |
angles | O lugar de outro ângulo de câmera | wide, medium, closeup, aerial, low-angle, eye-level, bird's-eye, dutch tilt |
lighting | Outra configuração de iluminação | soft natural, harsh sunlight, golden, blue hour, neon, candlelit, cinematic, dramatic chiaroscuro |
atmosphereMotions | Movimentos de câmera ambientes em loop | slow dolly-in, slow pan-left, slow pan-right, push up, drone fly-over, gentle drift, parallax, static atmospheric |
Fotos de referência e consentimento
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:
kind | Para que serve |
|---|---|
wide | Uma vista mais ampla do mesmo lugar. |
interior, exterior | O interior quando a imagem principal mostra o exterior, ou o contrário. |
detail | Um detalhe marcante, como uma estátua, uma placa ou um material. |
moodBoard | A paleta ou a sensação. |
other | Qualquer 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> --jsonCriar 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 falseProp
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
attachToLocationIdecountigual 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
previousCandidatesemGET /v1/locations/:id. Aprove o que preferir. - Editar o plano atual.
userPrompté uma instrução avulsa, por exemplo “add rain and puddles”. ComsourceImageUrl, 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"] }| Campo | O que faz |
|---|---|
name | Obrigatório. O nome do local. |
description, category, style | A identidade do local. |
count | Candidatos a gerar, de 1 a 10. O padrão é 1. |
userPrompt | Uma instrução avulsa que conduz esta geração. Nunca é salva. |
sourceImageUrl | Uma imagem para editar ou usar como ponto de partida. |
provider | O ID do modelo de imagem. Omita para usar o modelo padrão. |
quality, resolution | O nível de saída do modelo de imagem, com preço igual ao do Gerar imagem (Generate Image). |
attachToLocationId | Anexa 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 --watchassetType é 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°',
})| Campo | O que faz |
|---|---|
referenceImageUrl | Obrigatório. A vista anterior a partir da qual continuar. |
direction | Obrigatório. right ou left para girar, up ou down para inclinar. |
degrees | O ângulo desta vista, de 0 a 360, salvo com o resultado. |
carriedFraction | Quanto 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, aspectRatio | O 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, attachName | Anexam 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| Campo | O que faz |
|---|---|
name, motionPrompt | Obrigatórios. O nome do local e o movimento a criar. |
sourceImageUrl | Obrigatório. O quadro inicial. |
provider | kling (o padrão), kling-turbo, kling-3.0, wan-i2v, wan-2.7-i2v ou seedance-2. |
aspectRatio | 16:9 (o padrão), 1:1, 3:4 ou 9:16. |
refineFromVideoUrl | Um 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, attachName | O local e o nome do clipe em atmosphereMotions. |
| Modelo | Desenvolvedor | Modos | Créditos | Detalhes |
|---|---|---|---|---|
| Kling 2.6 | Kuaishou | Imagem para vídeo, Texto para vídeo | a partir de 152 | Kling 2.6 I2V — movimento muito realista. Clipes de 5 ou 10 s, com áudio nativo opcional. |
| Kling 2.5 Turbo Pro | Kuaishou | Imagem para vídeo, Texto para vídeo | a partir de 121 | Kling mais rápido — boa qualidade por um custo menor. Aceita quadro final. |
| Kling 3.0 | Kuaishou | Imagem para vídeo, Texto para vídeo | a partir de 297 | Kling 3.0 premium — duração variável de 3 a 15 s, áudio nativo, 720P/1080P. |
| Wan 2.6 I2V | Alibaba | Imagem para vídeo | a partir de 193 | Wan 2.6 de imagem para vídeo — 5, 10 ou 15 s em 720p/1080p. |
| Wan 2.7 I2V | Alibaba | Imagem para vídeo | 207 | Wan 2.7 de imagem para vídeo — de 2 a 15 s em 720p/1080p, com suporte a quadro inicial e final. |
| Seedance 2 | Bytedance | Imagem para vídeo, Texto para vídeo | a partir de 253 | Seedance 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ção | curl | TypeScript SDK | CLI |
|---|---|---|---|
| Arquivar | DELETE /v1/locations/:id | client.locations.delete(id) | nodaro locations delete <id> |
| Restaurar | POST /v1/locations/:id/restore | client.locations.restore(id) | nodaro locations restore <id> |
| Excluir para sempre | DELETE /v1/locations/:id?permanent=true | Não disponível | Nã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
| Ferramenta | O que faz |
|---|---|
list_locations, get_location | Encontra um local e lê as URLs das variações dele. |
create_location, update_location | Cria um local ou muda os campos de identidade dele. |
generate_location | Gera uma imagem principal (kind: "main") ou uma variação (kind: "asset"). |
generate_location_motion | Anima a imagem principal. |
approve_main_image, recaption_location | Aprova 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
| Rota | Preço no Nodaro Cloud |
|---|---|
POST /v1/generate-location | O preço do modelo de imagem vezes count, reservado para todos os candidatos antes de o primeiro job começar. |
POST /v1/generate-location-asset | O preço do modelo de imagem, por variação. |
POST /v1/generate-surround-continuation | O preço do modelo de imagem, por vista. |
POST /v1/generate-location-motion | O preço de imagem para vídeo do modelo de vídeo, por clipe. |
approve-main-image | Gratuito. |
llm-caption | 8 créditos por chamada. |
Erros
| Status | Código | Significado |
|---|---|---|
400 | validation_error | Um campo está ausente ou é inválido. |
400 | not_archived | Uma exclusão permanente foi enviada para um local que não está arquivado. |
400 | no_source_image | llm-caption foi chamado antes de o local ter uma imagem principal. |
401 | unauthorized | O token está ausente, é inválido ou foi revogado. |
402 | insufficient_credits | Só no Nodaro Cloud. A conta não cobre a reserva. |
403 | edition_required | A rota de vista de 360 graus foi chamada na Community Edition ou na Business edition. |
404 | not_found | Nenhum local com esse ID pertence a você. |
409 | concurrent_modification | expectedUpdatedAt 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
Páginas relacionadas
Locais
Local
Personagens
Objetos
Jobs
Última atualização
Objetos
API REST de objetos: crie e arquive adereços e produtos, gere e aprove a imagem principal e gere variações de material e ângulo e clipes de movimento.
Criaturas
Crie e gerencie animais e criaturas via REST: gere imagens principais, ângulos, poses, variações e clipes de movimento, e dê uma voz à criatura.