> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notifique.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Capacidades y bloqueo

> Techo en la Chat App, interruptor en la conversación, silenciar y bloquear usuarios.

<Tip>
  Hay **dos capas**, al estilo Stream/Sendbird: la app declara el techo; cada conversación activa un subconjunto. Bloquear y silenciar son de la **persona**, no de la sala.
</Tip>

## Techo de la Chat App

El producto declara lo que *puede* existir:

| Campo                                                    | Default                          | Qué es                                                   |
| -------------------------------------------------------- | -------------------------------- | -------------------------------------------------------- |
| `allowedMessageTypes`                                    | `text`, `image`, `audio`, `file` | Tipos que una conversación puede activar                 |
| `allowEdit`                                              | `false`                          | Techo para editar (la v1 solo guarda el flag)            |
| `allowDeleteForEveryone`                                 | `false`                          | Techo para borrar para todos (la v1 solo guarda el flag) |
| `allowUserManageCapabilities`                            | `false`                          | Si un `USER` en DIRECT puede cambiar la sala             |
| `defaultEnabledMessageTypes`                             | copia el techo                   | Lo que **nace activo** en una conversación nueva         |
| `defaultEditEnabled` / `defaultDeleteForEveryoneEnabled` | `false`                          | Flags iniciales de la conversación nueva                 |

`PATCH /v1/chat/apps/{id}` (alcance `chat:apps:manage`) cambia el techo. No existe “la conversación activó vídeo si la app no tiene vídeo”.

## Interruptor en la conversación

Serializado en GET/list:

```json theme={null}
{
  "capabilities": {
    "enabledMessageTypes": ["text"],
    "editEnabled": false,
    "deleteForEveryoneEnabled": false
  },
  "appCapabilities": {
    "allowedMessageTypes": ["text", "image", "audio", "file"],
    "allowEdit": false,
    "allowDeleteForEveryone": false,
    "allowUserManageCapabilities": false
  }
}
```

Crear una conversación aplica el default de la app; el body puede pasar un subconjunto. `PATCH /v1/chat/conversations/{id}` cambia el interruptor y emite `conversation.updated` (WebSocket) y `chat.conversation.updated` (webhook).

**Quién cambia la conversación**

* API Key: siempre
* `AGENT`: siempre
* `GROUP` + `OWNER` (y `ADMIN`): sí
* `USER` en `DIRECT`: solo si `allowUserManageCapabilities` está activo

## Envío rechazado

El composer de la app del cliente **solo oculta botones**. Quien manda es el servidor:

* Tipo fuera de la sala o del techo → `CHAT_CAPABILITY_DISABLED` (403)
* DIRECT con bloqueo entre los `USER` → `CHAT_USER_BLOCKED` (403)

El agente también respeta la sala. Lo mismo en REST y WebSocket (`message.send` con `type` + `mediaUrl`). `recording.start` exige `audio` activo.

Ejemplo de soporte: la app permite texto, imagen, audio y archivo. La conversación del pedido nace **solo texto**. El agente (o la API Key) activa media en esa sala. Apagar después vuelve a rechazar `IMAGE` / `AUDIO` / `FILE`.

## Silenciar

`POST /v1/chat/conversations/{id}/mute`

* JWT: silencia **a sí mismo**
* API Key: envía `memberExternalUserId`

`mutedUntil` nulo o `muted: false` lo apaga. El miembro silenciado sigue enviando y leyendo; el campo va en `members[].mutedUntil`. Evento WebSocket: `member.updated`.

## Bloquear

Por Chat App (`PUT` / `DELETE` / `GET /v1/chat/blocks/{externalUserId}`).

* No crea DIRECT con el bloqueado
* No añade al bloqueado a un grupo (y no entra si `joinPolicy=OPEN`)
* DIRECT ya existente: envío rechazado en ambos sentidos
* No borra el historial
* `USER` bloquea `USER`. No se puede bloquear a un `AGENT`
* Con API Key, envía `chatAppId` y `blockerExternalUserId`

Eventos: WebSocket `user.blocked` / `user.unblocked` en las DIRECT afectadas; webhooks `chat.user.blocked` / `chat.user.unblocked`.

Quitar un miembro sigue siendo “sacar de la sala”, no un bloqueo global.

## Siguientes pasos

* [Enviar mensajes](/es/chat-api/como-funciona/enviar-mensagens)
* [Eventos de webhooks](/es/chat-api/como-funciona/eventos-do-webhooks)
* [Usuario y agente](/es/chat-api/como-funciona/usuario-e-agente)
