# Biblioteca da comunidade

> Explore, pesquise, favorite e clone personagens, locais e objetos da Biblioteca da comunidade pela API REST, e denuncie uma publicação para moderação.

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

A **API da Biblioteca da comunidade** permite explorar o catálogo compartilhado de personagens, locais e objetos da sua instância do Nodaro e clonar uma publicação para a sua própria biblioteca. O catálogo tem curadoria: quem publica são os administradores da instância, e todo usuário com login pode pesquisar, favoritar, clonar e denunciar as publicações.

A biblioteca é um recurso multiusuário. Ela existe no Nodaro Cloud e na Business edition self-hosted. Em uma instância da Community Edition, essas rotas não são registradas e respondem `404`. As rotas aceitam um token Bearer: um token de API pessoal (`ndr_…`), um token de app OAuth (`ndr_app_…`) ou o token da sua sessão. Veja [Autenticação](https://nodaro.ai/docs/developers/api/authentication).

## Endpoints
| Método | Caminho | O que faz |
| --- | --- | --- |
| `GET` | `/v1/community/browse` | Lista as publicações públicas, uma página por vez. |
| `GET` | `/v1/community/detail/:slug` | Retorna uma publicação pelo slug. |
| `GET` | `/v1/community/favorites` | As publicações que você favoritou. |
| `POST` | `/v1/community/listings/:id/clone` | Copia uma publicação para a sua biblioteca. |
| `POST` | `/v1/community/listings/:id/favorite` | Adiciona ou remove um favorito. |
| `POST` | `/v1/community/listings/:id/report` | Denuncia uma publicação para moderação. |

## O que uma publicação contém
Toda rota de leitura retorna as publicações apenas com estes campos públicos.

| Campo | O que contém |
| --- | --- |
| `id`, `slug` | O ID da publicação, usado pelas rotas de escrita, e o slug, usado pela rota de detalhes. |
| `entity_type` | `character`, `location` ou `object`. |
| `title`, `description`, `category`, `style`, `tags` | O que o administrador escreveu ao publicar. |
| `creator_display_name` | Quem fez a publicação. |
| `preview_media_url`, `preview_images` | A imagem de prévia e a galeria de imagens. |
| `clone_count`, `favorite_count` | Quantas vezes a publicação foi clonada e favoritada. |
| `created_at` | Quando a publicação foi feita. |

## Explorar e pesquisar
`GET /v1/community/browse` retorna `{ data: Listing[], nextCursor }`. Para a próxima página, envie `nextCursor` de volta como `cursor`. Ele é `null` quando não há mais resultados.

| Parâmetro de consulta | O que faz |
| --- | --- |
| `entityType` | `character`, `location` ou `object`. |
| `q` | Busca de texto completo no título, na descrição e nas tags. |
| `category` | Somente uma categoria. |
| `sort` | `newest` (o padrão) ou `popular`, com as mais clonadas primeiro. |
| `limit` | Tamanho da página: 20 por padrão e no máximo 50. |
| `cursor` | O `nextCursor` da página anterior. |

**curl**

```bash
curl "https://app.nodaro.ai/v1/community/browse?entityType=character&sort=popular&limit=20" \
  -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 { data, nextCursor } = await client.community.browse({
entityType: 'character',
sort: 'popular',
limit: 20,
})
```

```json
{
"data": [
{
"id": "e4b2d8f1-6a3c-4e9b-8d7f-1c5a3e9b2d6f",
"entity_type": "character",
"slug": "detective-mara",
"title": "Detective Mara",
"description": "Noir-styled investigator",
"category": "people",
"style": "realistic",
"tags": ["noir", "detective"],
"creator_display_name": "Nodaro Team",
"preview_media_url": "https://cdn.nodaro.ai/community/detective-mara.png",
"clone_count": 128,
"favorite_count": 41,
"created_at": "2026-08-30T14:02:11Z"
}
],
"nextCursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wOC0zMCJ9"
}
```

`GET /v1/community/detail/:slug` retorna `{ data: Listing }`, ou `404 not_found` quando a publicação não existe ou foi removida. `GET /v1/community/favorites` retorna `{ data: Listing[] }`.

## Clonar uma publicação
`POST /v1/community/listings/:id/clone` copia uma publicação para a sua biblioteca e retorna `{ entityType, id }`: o tipo e o ID do seu novo personagem, local ou objeto. O corpo é `{ entityType }`, que precisa corresponder ao tipo da publicação.

- **É uma cópia, não um vínculo.** As imagens e os clipes da publicação são copiados para o seu próprio armazenamento. Alterações posteriores na original, ou a remoção da publicação, não afetam a sua cópia.
- **É sua.** O clone é um personagem, local ou objeto comum. Renomeie, edite, gere as mídias novamente ou exclua o clone.
- **Os nomes não entram em conflito.** Quando você já tem um com o mesmo nome, o clone recebe um nome único com um sufixo de cópia.
- **Usa o seu armazenamento.** Quando a sua conta passa do limite de armazenamento, a clonagem é recusada com `413 storage_limit_exceeded`.

Um token de app OAuth precisa do escopo `assets:write` para clonar. Tokens de API pessoais não precisam de escopo.

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/community/listings/e4b2d8f1-6a3c-4e9b-8d7f-1c5a3e9b2d6f/clone \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "entityType": "character" }'
```

**TypeScript SDK**

```ts
const { id } = await client.community.clone(listingId, 'character')
const mara = await client.characters.get(id)
```

```json
{ "entityType": "character", "id": "5a7c9e1b-3d4f-4a2c-b8e6-9f1d3b5a7c2e" }
```

Use o novo ID com a API de [Personagens](https://nodaro.ai/docs/developers/api/characters), de [Locais](https://nodaro.ai/docs/developers/api/locations) ou de [Objetos](https://nodaro.ai/docs/developers/api/objects).

## Favoritar uma publicação
`POST /v1/community/listings/:id/favorite` alterna o seu favorito e retorna `{ favorited }`: `true` depois de adicionar e `false` depois de remover.

```ts
const { favorited } = await client.community.favorite(listingId)
const { data: favorites } = await client.community.favorites()
```

## Denunciar uma publicação
`POST /v1/community/listings/:id/report` sinaliza uma publicação para a análise dos administradores e retorna `{ ok: true }`. O corpo é `{ reason }`, com um destes valores:

| `reason` | Use quando a publicação… |
| --- | --- |
| `real_person_no_consent` | Mostra uma pessoa real que não deu consentimento. |
| `inappropriate` | Tem conteúdo impróprio. |
| `ip_violation` | Viola a propriedade intelectual de alguém. |
| `other` | Tem qualquer outro problema. |

```ts
await client.community.report(listingId, 'real_person_no_consent')
```

Uma publicação pode ser removida após uma denúncia. As cópias que os usuários já clonaram continuam nas bibliotecas deles.

## A publicação tem curadoria
O catálogo tem curadoria dos administradores da instância. Publicar um item não faz parte da API pública nem do SDK. Veja [Biblioteca da comunidade](https://nodaro.ai/docs/guides/community-library).

## Erros
| Status | Código | Significado |
| --- | --- | --- |
| `400` | `validation_error` | Um campo está ausente ou é inválido. |
| `401` | `unauthorized` | O token está ausente, é inválido ou foi revogado. |
| `403` | `insufficient_scope` | Um token de app OAuth não tem `assets:write` para uma clonagem. |
| `404` | `not_found` | A publicação não existe ou foi removida, ou a instância é da Community Edition. |
| `413` | `storage_limit_exceeded` | A sua conta passou do limite de armazenamento. |

## Frequently asked questions

### Uma publicação clonada fica vinculada à original?

Não. A clonagem copia as imagens e os clipes da publicação para o seu próprio armazenamento. Você pode editar a cópia como quiser, e ela continua existindo se a original for alterada ou removida.

### Posso publicar meu próprio personagem na Biblioteca da comunidade pela API?

Não. O catálogo tem curadoria dos administradores da instância. A API permite que todo usuário com login explore, favorite, clone e denuncie publicações.

### Por que a API da Biblioteca da comunidade retorna 404 na minha instância?

A biblioteca é um recurso multiusuário do Nodaro Cloud e da Business edition. Uma instância da Community Edition não registra essas rotas, então toda chamada retorna 404.

### O que acontece se eu clonar uma publicação com o armazenamento cheio?

A clonagem é recusada com 413 storage_limit_exceeded, e nada é copiado. Libere espaço de armazenamento e tente de novo.
