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

# POST /api/v1/channels/{channelId}/messages

> Envie mensagens de texto, imagem, áudio, vídeo ou documento por um canal de API do BluBash. As respostas são geradas pelo agente de IA do seu workspace.

A Channels API permite enviar mensagens a contatos por meio de um canal de API configurado no seu workspace. Quando você envia uma mensagem, a plataforma cria ou localiza o contato pelo `contactIdentifier`, roteia a mensagem para o seu agente de IA e retorna a resposta do agente de forma síncrona na mesma chamada de API.

<Info>
  As conversas por um canal de API são tratadas exclusivamente por agentes de IA. Não há interface para agentes humanos participarem dessas conversas, portanto, a transferência para um humano não é suportada.
</Info>

## Endpoint

```http theme={null}
POST /api/v1/channels/{channelId}/messages
```

## Autenticação

Inclua sua Workspace API Key e, opcionalmente, uma chave de idempotência nos cabeçalhos da requisição.

```http theme={null}
X-API-Key: your_workspace_api_key
Content-Type: application/json
X-Idempotency-Key: optional_key_to_prevent_duplicates
```

## Parâmetros de path

<ParamField path="channelId" type="string" required>
  O ID do canal de API configurado no seu workspace.
</ParamField>

## Parâmetros do corpo da requisição

<ParamField body="type" type="string" required>
  O tipo de mensagem. Um de: `TEXT`, `IMAGE`, `AUDIO`, `VIDEO`, `DOCUMENT`.
</ParamField>

<ParamField body="contactIdentifier" type="string" required>
  Um identificador único para o contato. Usado para criar ou localizar o contato entre requisições. Recomendamos usar o endereço de e-mail do contato.
</ParamField>

<ParamField body="contactName" type="string">
  Nome de exibição do contato. Usado ao criar um novo registro de contato.
</ParamField>

<ParamField body="content" type="object" required>
  O payload da mensagem. O formato deste objeto depende do campo `type` — veja os exemplos de tipo de mensagem abaixo.
</ParamField>

<Warning>
  Use sempre o mesmo valor de `contactIdentifier` para a mesma pessoa. Usar identificadores diferentes para o mesmo contato (por exemplo, `joao@example.com` em uma requisição e `user@example.com` em outra) cria registros de contato separados e quebra o histórico da conversa.
</Warning>

## Tipos de mensagem

### Texto

<CodeGroup>
  ```json request theme={null}
  {
    "content": {
      "text": {
        "body": "Hello, how can I help you?"
      }
    },
    "type": "TEXT",
    "contactIdentifier": "user@example.com",
    "contactName": "User Name"
  }
  ```

  ```json response theme={null}
  {
    "success": true,
    "contactId": "cmg5gdkb60000sb75h4yu6mam",
    "conversationId": "cmg6etn5u000dsbx2htkjot8r",
    "messageId": "cmg6zqegm0001sbw9ip35juiq",
    "conversation": {
      "status": "ACTIVE",
      "assignedToHuman": false,
      "aiAgentId": "cmdi03x0z0003sbz6ubwtdrml",
      "aiAgentName": "Aurora",
      "teamId": "0fb043a2-75f7-42d7-b542-1ffcc1f75ccf",
      "teamName": "Technical Support"
    },
    "aiMessages": [
      {
        "content": {
          "text": {
            "body": "Hello! How can I help you today?"
          },
          "type": "text"
        },
        "type": "TEXT",
        "sender_type": "AI",
        "sender_name": "Aurora",
        "channel_message_id": null
      }
    ],
    "usage": {
      "credits": 1
    }
  }
  ```
</CodeGroup>

### Imagem

<CodeGroup>
  ```json request theme={null}
  {
    "content": {
      "image": {
        "url": "https://example.com/image.jpg",
        "caption": "Image caption"
      }
    },
    "type": "IMAGE",
    "contactIdentifier": "user@example.com"
  }
  ```

  ```json response theme={null}
  {
    "success": true,
    "contactId": "cmg5gdkb60000sb75h4yu6mam",
    "conversationId": "cmg6etn5u000dsbx2htkjot8r",
    "messageId": "cmg6zqegm0001sbw9ip35juiq",
    "conversation": {
      "status": "ACTIVE",
      "assignedToHuman": false,
      "aiAgentId": "cmdi03x0z0003sbz6ubwtdrml",
      "aiAgentName": "Aurora",
      "teamId": "0fb043a2-75f7-42d7-b542-1ffcc1f75ccf",
      "teamName": "Technical Support"
    },
    "aiMessages": [
      {
        "content": {
          "text": {
            "body": "I see an interesting image! How can I help you with that?"
          },
          "type": "text"
        },
        "type": "TEXT",
        "sender_type": "AI",
        "sender_name": "Aurora",
        "channel_message_id": null
      }
    ],
    "usage": {
      "credits": 1
    }
  }
  ```
</CodeGroup>

### Áudio

<CodeGroup>
  ```json request theme={null}
  {
    "content": {
      "audio": {
        "url": "https://example.com/audio.mp3"
      }
    },
    "type": "AUDIO",
    "contactIdentifier": "user@example.com"
  }
  ```

  ```json response theme={null}
  {
    "success": true,
    "contactId": "cmg5gdkb60000sb75h4yu6mam",
    "conversationId": "cmg6etn5u000dsbx2htkjot8r",
    "messageId": "cmg6zqegm0001sbw9ip35juiq",
    "conversation": {
      "status": "ACTIVE",
      "assignedToHuman": false,
      "aiAgentId": "cmdi03x0z0003sbz6ubwtdrml",
      "aiAgentName": "Aurora",
      "teamId": "0fb043a2-75f7-42d7-b542-1ffcc1f75ccf",
      "teamName": "Technical Support"
    },
    "aiMessages": [
      {
        "content": {
          "text": {
            "body": "Audio transcription: Hello, I need help with my order"
          },
          "type": "text"
        },
        "type": "TEXT",
        "sender_type": "AI",
        "sender_name": "Aurora",
        "channel_message_id": null
      }
    ],
    "usage": {
      "credits": 1
    }
  }
  ```
</CodeGroup>

### Vídeo

<CodeGroup>
  ```json request theme={null}
  {
    "content": {
      "video": {
        "url": "https://example.com/video.mp4",
        "caption": "Video caption"
      }
    },
    "type": "VIDEO",
    "contactIdentifier": "user@example.com"
  }
  ```

  ```json response theme={null}
  {
    "success": true,
    "contactId": "cmg5gdkb60000sb75h4yu6mam",
    "conversationId": "cmg6etn5u000dsbx2htkjot8r",
    "messageId": "cmg6zqegm0001sbw9ip35juiq",
    "conversation": {
      "status": "ACTIVE",
      "assignedToHuman": false,
      "aiAgentId": "cmdi03x0z0003sbz6ubwtdrml",
      "aiAgentName": "Aurora",
      "teamId": "0fb043a2-75f7-42d7-b542-1ffcc1f75ccf",
      "teamName": "Technical Support"
    },
    "aiMessages": [
      {
        "content": {
          "text": {
            "body": "I received your video! How can I help you with that?"
          },
          "type": "text"
        },
        "type": "TEXT",
        "sender_type": "AI",
        "sender_name": "Aurora",
        "channel_message_id": null
      }
    ],
    "usage": {
      "credits": 1
    }
  }
  ```
</CodeGroup>

### Documento

<CodeGroup>
  ```json request theme={null}
  {
    "content": {
      "document": {
        "url": "https://example.com/document.pdf",
        "filename": "document.pdf",
        "caption": "Document description"
      }
    },
    "type": "DOCUMENT",
    "contactIdentifier": "user@example.com"
  }
  ```

  ```json response theme={null}
  {
    "success": true,
    "contactId": "cmg5gdkb60000sb75h4yu6mam",
    "conversationId": "cmg6etn5u000dsbx2htkjot8r",
    "messageId": "cmg6zqegm0001sbw9ip35juiq",
    "conversation": {
      "status": "ACTIVE",
      "assignedToHuman": false,
      "aiAgentId": "cmdi03x0z0003sbz6ubwtdrml",
      "aiAgentName": "Aurora",
      "teamId": "0fb043a2-75f7-42d7-b542-1ffcc1f75ccf",
      "teamName": "Technical Support"
    },
    "aiMessages": [
      {
        "content": {
          "text": {
            "body": "I received your document! How can I help you with that?"
          },
          "type": "text"
        },
        "type": "TEXT",
        "sender_type": "AI",
        "sender_name": "Aurora",
        "channel_message_id": null
      }
    ],
    "usage": {
      "credits": 1
    }
  }
  ```
</CodeGroup>

## Campos da resposta

<ResponseField name="success" type="boolean" required>
  Indica se a operação foi bem-sucedida.
</ResponseField>

<ResponseField name="contactId" type="string" required>
  O ID único do contato criado ou correspondido pelo `contactIdentifier`.
</ResponseField>

<ResponseField name="conversationId" type="string" required>
  O ID único da conversa.
</ResponseField>

<ResponseField name="messageId" type="string" required>
  O ID único da mensagem que foi enviada.
</ResponseField>

<ResponseField name="conversation" type="object" required>
  Detalhes sobre a conversa e sua atribuição.

  <Expandable title="properties">
    <ResponseField name="status" type="string">
      Status atual da conversa (por exemplo, `ACTIVE`).
    </ResponseField>

    <ResponseField name="assignedToHuman" type="boolean">
      Se a conversa está atribuída a um agente humano.
    </ResponseField>

    <ResponseField name="aiAgentId" type="string">
      ID do agente de IA que está cuidando da conversa.
    </ResponseField>

    <ResponseField name="aiAgentName" type="string">
      Nome de exibição do agente de IA.
    </ResponseField>

    <ResponseField name="teamId" type="string">
      ID da equipe à qual a conversa pertence.
    </ResponseField>

    <ResponseField name="teamName" type="string">
      Nome de exibição da equipe.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="aiMessages" type="array" required>
  As mensagens de resposta do agente de IA, ordenadas de forma ascendente (primeiro as mais antigas). Trata-se de um array porque a IA pode dividir sua resposta em várias mensagens sequenciais.
</ResponseField>

<ResponseField name="usage" type="object" required>
  Informações de consumo de créditos.

  <Expandable title="properties">
    <ResponseField name="credits" type="number">
      Número de créditos consumidos por esta requisição.
    </ResponseField>
  </Expandable>
</ResponseField>

## Códigos de status HTTP

| Código | Descrição                                             |
| ------ | ----------------------------------------------------- |
| `200`  | Sucesso — mensagem processada                         |
| `400`  | Dados inválidos da requisição ou canal não encontrado |
| `401`  | Chave de API ausente ou inválida                      |
| `404`  | Canal não encontrado                                  |
| `500`  | Erro interno do servidor                              |

## Exemplos de integração

<CodeGroup>
  ```javascript JavaScript (Fetch) theme={null}
  async function sendMessage(channelId, apiKey, message) {
    const response = await fetch(`/api/v1/channels/${channelId}/messages`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': apiKey
      },
      body: JSON.stringify({
        content: {
          text: {
            body: message
          }
        },
        type: 'TEXT',
        contactIdentifier: 'user@example.com'
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    return await response.json();
  }

  try {
    const result = await sendMessage('channel_123', 'your_api_key', 'Hello!');
    console.log('Message sent:', result);
  } catch (error) {
    console.error('Error:', error);
  }
  ```

  ```python Python theme={null}
  import requests

  def send_message(channel_id, api_key, message_data):
      url = f"https://your-domain.com/api/v1/channels/{channel_id}/messages"

      headers = {
          'Content-Type': 'application/json',
          'X-API-Key': api_key
      }

      response = requests.post(url, headers=headers, json=message_data)

      if response.status_code == 200:
          return response.json()
      else:
          raise Exception(f"HTTP {response.status_code}: {response.text}")

  message_data = {
      "content": {
          "text": {
              "body": "Hello, I need help!"
          }
      },
      "type": "TEXT",
      "contactIdentifier": "customer@example.com",
      "contactName": "John Smith"
  }

  try:
      result = send_message('channel_123', 'your_api_key', message_data)
      print('Message sent:', result)
  except Exception as e:
      print('Error:', e)
  ```

  ```bash cURL theme={null}
  curl -X POST "https://your-domain.com/api/v1/channels/channel_123/messages" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: your_api_key" \
    -d '{
      "content": {
        "text": {
          "body": "Hello, I need help!"
        }
      },
      "type": "TEXT",
      "contactIdentifier": "customer@example.com",
      "contactName": "John Smith"
    }'
  ```
</CodeGroup>

## Limitações

* **Apenas IA**: As conversas são exclusivas dos agentes de IA — a transferência para agente humano não está disponível.
* **`contactIdentifier` consistente**: Use sempre o mesmo valor para o mesmo contato. Recomendamos usar o endereço de e-mail do contato.
* **URLs de mídia públicas**: As URLs de imagem, áudio, vídeo e documento precisam estar acessíveis publicamente.
* **Limite de tamanho de arquivo**: Máximo de 10 MB por arquivo.
* **Timeout de download**: Downloads de mídia têm timeout de 30 segundos.
* **Idempotência**: Use `X-Idempotency-Key` para evitar mensagens duplicadas em requisições reenviadas.
