# 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.

Source: https://nodaro.ai/pt-BR/docs/developers/api/locations

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](https://nodaro.ai/docs/developers/api/authentication).

## 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**

```bash
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"
```

**TypeScript SDK**

```ts

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)
```

**CLI**

```bash
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**

```bash
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"
}'
```

**TypeScript SDK**

```ts
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,
})
```

**CLI**

```bash
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
```

<TypeTable
type={{
id: { type: 'string (uuid)', description: 'O local a atualizar. Omita para criar um local.' },
nodeId: { type: 'string', description: 'Obrigatório na criação. O nó do canvas ao qual o local pertence, ou qualquer rótulo quando não há nenhum.' },
name: { type: 'string', description: 'Obrigatório na criação.' },
description: { type: 'string', description: 'O que torna o lugar único, em uma a três frases.' },
category: { type: 'string', description: 'indoor, outdoor, urban, nature, fantasy, sci-fi, historical, futuristic ou other.' },
style: { type: 'string', description: 'realistic, anime, 3d-pixar ou illustration.' },
styleLock: { type: 'boolean', description: 'Gera as variações a partir da imagem principal aprovada.', default: 'true' },
referencePhotos: { type: 'array', description: 'Até 20 fotos { kind, url } do painel de inspiração.' },
piiConsentAt: { type: 'string (ISO 8601)', description: 'Quando você confirmou os direitos e o consentimento para as fotos de referência. Defina este campo quando anexar fotos pela primeira vez.' },
canonicalDescription: { type: 'string', description: 'Substitui a descrição escrita.' },
sourceImageUrl: { type: 'string', description: 'Define a imagem principal diretamente.' },
projectId: { type: 'string (uuid)', description: 'O projeto em que o local fica guardado.' },
expectedUpdatedAt: { type: 'string (ISO 8601)', description: 'Na atualização: recusa a gravação com 409 quando o local mudou desde esse carimbo de data e hora.' },
}}
/>

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**

```bash
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"
}'
```

**TypeScript SDK**

```ts
const { jobIds } = await client.locations.generate({
name: 'Rainy Tokyo Alley',
description: 'Neon-soaked alley with vending machines',
count: 4,
})
```

**CLI**

```bash
nodaro locations generate --name "Rainy Tokyo Alley" --count 1 \
  --attach-to-location-id <id> --watch
```

```json
{ "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)](https://nodaro.ai/docs/nodes/image/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**

```bash
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"
}'
```

**TypeScript SDK**

```ts
await client.locations.generateAsset({
name: 'Rainy Tokyo Alley',
assetType: 'timeOfDay',
variant: 'blue hour',
attachToLocationId: id,
attachToColumn: 'time_of_day',
attachName: 'blue hour',
})
```

**CLI**

```bash
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**

```bash
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°"
}'
```

**TypeScript SDK**

```ts
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**

```bash
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"
}'
```

**TypeScript SDK**

```ts
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',
})
```

**CLI**

```bash
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`. |

| Model | Maker | Modes | Credits | Details |
| --- | --- | --- | --- | --- |
| [Kling 2.6](https://nodaro.ai/docs/models/video/kling-2-6) | Kuaishou | Image to video, Text to video | a partir de 152 | Kling 2.6 I2V — strong motion realism. 5s/10s, optional native audio. |
| [Kling 2.5 Turbo Pro](https://nodaro.ai/docs/models/video/kling-2-5-turbo-pro) | Kuaishou | Image to video, Text to video | a partir de 121 | Faster Kling — good quality at lower cost. Supports end frame. |
| [Kling 3.0](https://nodaro.ai/docs/models/video/kling-3-0) | Kuaishou | Image to video, Text to video | a partir de 297 | Premium Kling 3.0 — variable 3-15s duration, native audio, 720P/1080P. |
| [Wan 2.6 I2V](https://nodaro.ai/docs/models/video/wan-2-6-i2v) | Alibaba | Image to video | a partir de 193 | Wan 2.6 image-to-video — 5/10/15s at 720p/1080p. |
| [Wan 2.7 I2V](https://nodaro.ai/docs/models/video/wan-2-7-i2v) | Alibaba | Image to video | 207 | Wan 2.7 image-to-video — 2–15s at 720p/1080p, supports start+end frame. |
| [Seedance 2](https://nodaro.ai/docs/models/video/seedance-2) | Bytedance | Image to video, Text to video | a partir de 253 | Seedance 2 — premium tier with native audio. Per-second pricing by resolution. |

## 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**

```bash
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" }'
```

**TypeScript SDK**

```ts
const { sourceImageUrl, canonicalDescription } =
await client.locations.approveMainImage(id, jobIds[2])
```

**CLI**

```bash
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)](https://nodaro.ai/docs/nodes/assets/location) é 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](https://nodaro.ai/docs/nodes/image/generate-image) ou o [**Gerar vídeo** (Generate Video)](https://nodaro.ai/docs/nodes/video/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](https://nodaro.ai/docs/guides/locations).

## 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](https://nodaro.ai/docs/mcp/tools).

## 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. |

## Frequently asked questions

### O que é um local na API do Nodaro?

Um local é um lugar salvo com um plano de estabelecimento aprovado, uma descrição escrita e imagens de variações, como a mesma rua ao anoitecer ou na chuva. Os nós de imagem e de vídeo reaproveitam o local para que o lugar tenha a mesma aparência em todas as tomadas.

### Como testo novos planos de estabelecimento sem perder o atual?

Gere vários candidatos sem anexá-los. A imagem principal atual continua até você aprovar um candidato, e GET /v1/locations/:id lista até 5 candidatos recentes em previousCandidates.

### Preciso de consentimento para adicionar fotos de referência a um local?

Sim. As fotos de referência podem mostrar pessoas, então defina piiConsentAt, um carimbo de data e hora ISO, quando anexar fotos pela primeira vez. Ele registra que você tem os direitos e o consentimento para usá-las.

### Posso montar uma vista de 360 graus de um local?

No Nodaro Cloud, POST /v1/generate-surround-continuation gera a próxima vista de um panorama a partir da anterior e mantém a metade compartilhada idêntica pixel a pixel, para que as vistas se alinhem. Cada vista custa uma geração de imagem.

### Quais modelos animam um local?

Seis modelos de vídeo, pelos IDs de provedor kling (o padrão, Kling 2.6), kling-turbo, kling-3.0, wan-i2v, wan-2.7-i2v e seedance-2. Cada clipe custa o preço de imagem para vídeo desse modelo.
