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

# Enviar template em massa (Bulk Send)

> 
**ENVIO EM MASSA DE TEMPLATES DO WHATSAPP**

Envia mensagens de template do WhatsApp para múltiplos contatos de uma só vez.
Esta é uma funcionalidade poderosa para campanhas de marketing, notificações em massa e comunicações importantes.

---

## 📋 **Estrutura da Requisição**

A requisição deve ser feita como **multipart/form-data** com os seguintes campos:

| Campo | Tipo | Obrigatório | Descrição |
|-------|------|-------------|-----------|
| `inboxId` | string | ✅ Sim | ID do inbox pelo qual as mensagens serão enviadas |
| `templateName` | string | ✅ Sim | Nome do template aprovado no WhatsApp (3-512 caracteres) |
| `languageCode` | string | ✅ Sim | Código de idioma (ex: pt_BR, en_US, es_ES, pt_PT) |
| `components` | array | ❌ Não | Array de componentes do template (header, body, buttons) |
| `contacts` | array | ⚠️ Condicional | Array de contatos (obrigatório se não enviar arquivo) |
| `file` | file | ⚠️ Condicional | Arquivo CSV/XLSX (obrigatório se não enviar contacts) |

---

## 📝 **Schema Zod dos DTOs**

### **BulkContactSchema**
```typescript
{
  name: string,      // Nome do contato (obrigatório, mín. 1 caractere)
  phone: string      // Telefone do contato (obrigatório, mín. 1 caractere)
}
```

### **TemplateParameterSchema**
```typescript
{
  type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time' | 'payload',
  
  // Campos opcionais (usar conforme o tipo):
  text?: string,                        // Para tipo 'text'
  image?: { link?: string },            // Para tipo 'image'
  document?: { 
    link?: string, 
    filename?: string 
  },                                    // Para tipo 'document'
  video?: { link?: string },            // Para tipo 'video'
  currencyCode?: string,                // Para tipo 'currency' (ex: 'BRL', 'USD')
  currencyAmount?: number,              // Para tipo 'currency'
  dateTime?: string,                    // Para tipo 'date_time' (ISO 8601)
  payload?: string,                     // Para tipo 'payload' (botões)
  
  // Campos alternativos (compatibilidade):
  value?: string,
  link?: string,
  imageUrl?: string,
  imageId?: string,
  documentUrl?: string,
  documentFilename?: string,
  videoUrl?: string,
  parameter_name?: string
}
```

### **TemplateComponentSchema**
```typescript
{
  type: 'header' | 'body' | 'button',
  sub_type?: 'quick_reply' | 'url' | 'phone_number',  // Apenas para buttons
  index?: string,                                       // Índice do botão (apenas para buttons)
  parameters?: TemplateParameter[]                      // Array de parâmetros
}
```

### **SendBulkTemplateMessageDto**
```typescript
{
  inboxId: string,                          // Obrigatório, mín. 1 caractere
  templateName: string,                     // Obrigatório, 3-512 caracteres, lowercase, sem espaços
  languageCode: string,                     // Obrigatório, formato: xx_XX
  components?: TemplateComponent[],         // Opcional
  contacts?: BulkContact[]                  // Opcional (se não enviar arquivo)
}
```

---

## 👥 **Formatos de Contatos**

### **Opção 1: JSON (campo contacts)**
```json
{
  "inboxId": "65f1a2b3c4d5e6f7g8h9i0j1",
  "templateName": "welcome_message",
  "languageCode": "pt_BR",
  "contacts": [
    { "name": "João Silva", "phone": "5511999999999" },
    { "name": "Maria Santos", "phone": "5511888888888" }
  ]
}
```

### **Opção 2: Arquivo CSV**
```csv
name,phone
João Silva,5511999999999
Maria Santos,5511888888888
Pedro Costa,5511777777777
```

### **Opção 3: Arquivo XLSX**
Arquivo Excel com colunas obrigatórias: **name** | **phone**

---

## 🎨 **Componentes de Template**

Templates do WhatsApp são compostos por **componentes** que podem ter **parâmetros** dinâmicos.

### **Tipos de Componentes:**

| Tipo | Descrição | Parâmetros Permitidos |
|------|-----------|----------------------|
| **header** | Cabeçalho do template | text, image, video, document |
| **body** | Corpo principal | text, currency, date_time |
| **button** | Botões interativos | text, payload |

### **Sub-tipos de Botão:**

- `quick_reply`: Resposta rápida (payload)
- `url`: Botão com link dinâmico (text para variável da URL)
- `phone_number`: Botão de telefone

---

## 📝 **Exemplos Práticos**

### **1️⃣ Template Simples de Texto**

**Template aprovado no WhatsApp:**
```
Olá {{1}}! Bem-vindo à nossa loja.
```

**Requisição:**
```json
{
  "inboxId": "65f1a2b3c4d5e6f7g8h9i0j1",
  "templateName": "welcome_message",
  "languageCode": "pt_BR",
  "components": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "João" }
      ]
    }
  ],
  "contacts": [
    { "name": "João Silva", "phone": "5511999999999" }
  ]
}
```

**Resultado:** _"Olá João! Bem-vindo à nossa loja."_

---

### **2️⃣ Template com Header de Imagem**

**Template aprovado:**
```
[HEADER: IMAGEM]
Olá {{1}}!
Confira nossa promoção de {{2}}.
```

**Requisição:**
```json
{
  "inboxId": "...",
  "templateName": "promotion",
  "languageCode": "pt_BR",
  "components": [
    {
      "type": "header",
      "parameters": [
        {
          "type": "image",
          "image": { "link": "https://example.com/promo.jpg" }
        }
      ]
    },
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "João" },
        { "type": "text", "text": "Black Friday" }
      ]
    }
  ],
  "contacts": [...]
}
```

---

### **3️⃣ Template com Botão URL Dinâmico**

**Template aprovado:**
```
Olá! Seu pedido #{{1}} foi confirmado.
[BOTÃO URL: Rastrear Pedido - https://example.com/track/{{1}}]
```

**Requisição:**
```json
{
  "inboxId": "...",
  "templateName": "order_confirmation",
  "languageCode": "pt_BR",
  "components": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "12345" }
      ]
    },
    {
      "type": "button",
      "sub_type": "url",
      "index": "0",
      "parameters": [
        { "type": "text", "text": "12345" }
      ]
    }
  ],
  "contacts": [...]
}
```

---

### **4️⃣ Template com Documento no Header**

**Template aprovado:**
```
[HEADER: DOCUMENTO]
Olá {{1}}, segue seu boleto de cobrança.
```

**Requisição:**
```json
{
  "inboxId": "...",
  "templateName": "invoice",
  "languageCode": "pt_BR",
  "components": [
    {
      "type": "header",
      "parameters": [
        {
          "type": "document",
          "document": {
            "link": "https://example.com/boleto.pdf",
            "filename": "boleto_janeiro.pdf"
          }
        }
      ]
    },
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "João Silva" }
      ]
    }
  ],
  "contacts": [...]
}
```

---

### **5️⃣ Template com Moeda e Data**

**Template aprovado:**
```
Olá {{1}}!
Sua fatura de {{2}} no valor de {{3}} vence em {{4}}.
```

**Requisição:**
```json
{
  "inboxId": "...",
  "templateName": "billing",
  "languageCode": "pt_BR",
  "components": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "João" },
        { "type": "text", "text": "Janeiro/2024" },
        {
          "type": "currency",
          "currencyCode": "BRL",
          "currencyAmount": 150.50
        },
        {
          "type": "date_time",
          "dateTime": "2024-01-31T23:59:59Z"
        }
      ]
    }
  ],
  "contacts": [...]
}
```

**Resultado:** _"Olá João! Sua fatura de Janeiro/2024 no valor de R$ 150,50 vence em 31/01/2024."_

---

### **6️⃣ Template Carousel (Carrossel)**

Templates tipo carrossel permitem enviar múltiplos cards deslizáveis.

```json
{
  "inboxId": "...",
  "templateName": "product_catalog",
  "languageCode": "pt_BR",
  "isCarousel": true,
  "carouselCards": [
    {
      "card_index": 0,
      "components": [
        {
          "type": "HEADER",
          "parameters": [
            {
              "type": "image",
              "image": { "link": "https://example.com/product1.jpg" }
            }
          ]
        },
        {
          "type": "BODY",
          "parameters": [
            { "type": "text", "text": "Produto 1" },
            { "type": "text", "text": "R$ 99,90" }
          ]
        },
        {
          "type": "BUTTON",
          "sub_type": "quick_reply",
          "index": 0,
          "parameters": [
            { "type": "payload", "payload": "product_1" }
          ]
        }
      ]
    },
    {
      "card_index": 1,
      "components": [
        // Componentes do card 2...
      ]
    }
  ],
  "contacts": [...]
}
```

---

## 📊 **Resposta da API**

### **Schema de Resposta:**
```typescript
{
  totalProcessed: number,      // Total de contatos processados
  sentCount: number,            // Quantidade enviada com sucesso
  errorCount: number,           // Quantidade de erros
  sentContacts: [               // Contatos enviados com sucesso
    {
      conversationId: string,   // ID da conversa criada/utilizada
      phoneNumber: string       // Número de telefone formatado
    }
  ],
  errors: [                     // Erros detalhados
    {
      row: number,              // Linha do erro (arquivo ou índice)
      contact: string,          // Nome do contato
      error: string             // Descrição do erro
    }
  ]
}
```

### **Exemplo de Resposta:**
```json
{
  "totalProcessed": 100,
  "sentCount": 95,
  "errorCount": 5,
  "sentContacts": [
    {
      "conversationId": "65f1a2b3c4d5e6f7g8h9i0j1",
      "phoneNumber": "5511999999999"
    },
    {
      "conversationId": "65f1a2b3c4d5e6f7g8h9i0j2",
      "phoneNumber": "5511888888888"
    }
  ],
  "errors": [
    {
      "row": 5,
      "contact": "João Silva",
      "error": "Número de telefone inválido"
    },
    {
      "row": 23,
      "contact": "Maria Santos",
      "error": "Template não encontrado para este inbox"
    }
  ]
}
```

---

## ⚠️ **Observações Importantes**

### **Validações e Restrições:**

1. **✅ Templates Aprovados**: Só é possível enviar templates previamente aprovados pelo Meta/WhatsApp
2. **⏱️ Limite de Taxa**: O WhatsApp possui limites de envio (tier-based):
   - Tier 1: até 1.000 conversas únicas/dia
   - Tier 2: até 10.000 conversas únicas/dia
   - Tier 3: até 100.000 conversas únicas/dia
3. **📞 Validação de Números**: Números são validados automaticamente (formato internacional E.164)
4. **🕐 Janela de 24h**: Templates podem ser enviados FORA da janela de 24 horas
5. **🎯 Parâmetros Corretos**: Número e tipo de parâmetros devem coincidir EXATAMENTE com o template
6. **🔢 Índices de Botão**: Botões dinâmicos são indexados começando em `"0"` (string)
7. **🖼️ Formato de Mídia**: Links de mídia devem ser URLs públicas HTTPS acessíveis
8. **📦 Tamanho de Lote**: Recomenda-se enviar em lotes de até 1.000 contatos por vez

### **Códigos de Idioma Aceitos:**

| Código | Idioma |
|--------|--------|
| `pt_BR` | Português (Brasil) |
| `pt_PT` | Português (Portugal) |
| `en_US` | Inglês (EUA) |
| `en_GB` | Inglês (Reino Unido) |
| `es_ES` | Espanhol (Espanha) |
| `es_MX` | Espanhol (México) |
| `fr_FR` | Francês |
| `de_DE` | Alemão |
| `it_IT` | Italiano |

### **Limites do WhatsApp por Tipo de Mídia:**

| Tipo | Tamanho Máximo | Formatos Aceitos |
|------|----------------|------------------|
| **Imagem** | 5 MB | JPG, JPEG, PNG |
| **Vídeo** | 16 MB | MP4, 3GPP |
| **Documento** | 100 MB | PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT |
| **Áudio** | 16 MB | AAC, M4A, AMR, MP3, OGG |

---

## 🔗 **Tipos de Parâmetros Suportados**

| Tipo | Uso | Campos Obrigatórios | Exemplo |
|------|-----|---------------------|---------|
| `text` | Texto simples | `text` | `{ "type": "text", "text": "João" }` |
| `image` | Imagem (header) | `image.link` | `{ "type": "image", "image": { "link": "https://..." } }` |
| `video` | Vídeo (header) | `video.link` | `{ "type": "video", "video": { "link": "https://..." } }` |
| `document` | Documento (header) | `document.link`, `document.filename` | `{ "type": "document", "document": { "link": "https://...", "filename": "doc.pdf" } }` |
| `currency` | Valor monetário | `currencyCode`, `currencyAmount` | `{ "type": "currency", "currencyCode": "BRL", "currencyAmount": 99.90 }` |
| `date_time` | Data/hora | `dateTime` (ISO 8601) | `{ "type": "date_time", "dateTime": "2024-01-15T10:30:00Z" }` |
| `payload` | Dados para botão | `payload` | `{ "type": "payload", "payload": "button_data" }` |

---

## 🚀 **Boas Práticas**

1. **Teste com poucos contatos** antes de enviar para uma lista grande
2. **Valide seus números** no formato internacional (ex: 5511999999999)
3. **Use templates específicos** para cada caso de uso
4. **Monitore as estatísticas** de entrega na resposta da API
5. **Respeite os limites** de taxa do WhatsApp
6. **Mantenha templates atualizados** e aprovados
7. **Use CSV/XLSX** para listas grandes (melhor performance)
8. **Implemente retry** para contatos que falharam




## OpenAPI

````yaml https://api.nuvia.ai/api/docs/user-json post /v1/messages/send-bulk-template
openapi: 3.0.0
info:
  title: Nuvia API - Empresa
  description: Documentação da API para empresas
  version: '1.0'
  contact: {}
servers:
  - url: https://api.nuvia.ai
security: []
tags:
  - name: auth
    description: Autenticação
paths:
  /v1/messages/send-bulk-template:
    post:
      tags:
        - messages
      summary: Enviar template em massa (Bulk Send)
      description: >

        **ENVIO EM MASSA DE TEMPLATES DO WHATSAPP**


        Envia mensagens de template do WhatsApp para múltiplos contatos de uma
        só vez.

        Esta é uma funcionalidade poderosa para campanhas de marketing,
        notificações em massa e comunicações importantes.


        ---


        ## 📋 **Estrutura da Requisição**


        A requisição deve ser feita como **multipart/form-data** com os
        seguintes campos:


        | Campo | Tipo | Obrigatório | Descrição |

        |-------|------|-------------|-----------|

        | `inboxId` | string | ✅ Sim | ID do inbox pelo qual as mensagens serão
        enviadas |

        | `templateName` | string | ✅ Sim | Nome do template aprovado no
        WhatsApp (3-512 caracteres) |

        | `languageCode` | string | ✅ Sim | Código de idioma (ex: pt_BR, en_US,
        es_ES, pt_PT) |

        | `components` | array | ❌ Não | Array de componentes do template
        (header, body, buttons) |

        | `contacts` | array | ⚠️ Condicional | Array de contatos (obrigatório
        se não enviar arquivo) |

        | `file` | file | ⚠️ Condicional | Arquivo CSV/XLSX (obrigatório se não
        enviar contacts) |


        ---


        ## 📝 **Schema Zod dos DTOs**


        ### **BulkContactSchema**

        ```typescript

        {
          name: string,      // Nome do contato (obrigatório, mín. 1 caractere)
          phone: string      // Telefone do contato (obrigatório, mín. 1 caractere)
        }

        ```


        ### **TemplateParameterSchema**

        ```typescript

        {
          type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time' | 'payload',
          
          // Campos opcionais (usar conforme o tipo):
          text?: string,                        // Para tipo 'text'
          image?: { link?: string },            // Para tipo 'image'
          document?: { 
            link?: string, 
            filename?: string 
          },                                    // Para tipo 'document'
          video?: { link?: string },            // Para tipo 'video'
          currencyCode?: string,                // Para tipo 'currency' (ex: 'BRL', 'USD')
          currencyAmount?: number,              // Para tipo 'currency'
          dateTime?: string,                    // Para tipo 'date_time' (ISO 8601)
          payload?: string,                     // Para tipo 'payload' (botões)
          
          // Campos alternativos (compatibilidade):
          value?: string,
          link?: string,
          imageUrl?: string,
          imageId?: string,
          documentUrl?: string,
          documentFilename?: string,
          videoUrl?: string,
          parameter_name?: string
        }

        ```


        ### **TemplateComponentSchema**

        ```typescript

        {
          type: 'header' | 'body' | 'button',
          sub_type?: 'quick_reply' | 'url' | 'phone_number',  // Apenas para buttons
          index?: string,                                       // Índice do botão (apenas para buttons)
          parameters?: TemplateParameter[]                      // Array de parâmetros
        }

        ```


        ### **SendBulkTemplateMessageDto**

        ```typescript

        {
          inboxId: string,                          // Obrigatório, mín. 1 caractere
          templateName: string,                     // Obrigatório, 3-512 caracteres, lowercase, sem espaços
          languageCode: string,                     // Obrigatório, formato: xx_XX
          components?: TemplateComponent[],         // Opcional
          contacts?: BulkContact[]                  // Opcional (se não enviar arquivo)
        }

        ```


        ---


        ## 👥 **Formatos de Contatos**


        ### **Opção 1: JSON (campo contacts)**

        ```json

        {
          "inboxId": "65f1a2b3c4d5e6f7g8h9i0j1",
          "templateName": "welcome_message",
          "languageCode": "pt_BR",
          "contacts": [
            { "name": "João Silva", "phone": "5511999999999" },
            { "name": "Maria Santos", "phone": "5511888888888" }
          ]
        }

        ```


        ### **Opção 2: Arquivo CSV**

        ```csv

        name,phone

        João Silva,5511999999999

        Maria Santos,5511888888888

        Pedro Costa,5511777777777

        ```


        ### **Opção 3: Arquivo XLSX**

        Arquivo Excel com colunas obrigatórias: **name** | **phone**


        ---


        ## 🎨 **Componentes de Template**


        Templates do WhatsApp são compostos por **componentes** que podem ter
        **parâmetros** dinâmicos.


        ### **Tipos de Componentes:**


        | Tipo | Descrição | Parâmetros Permitidos |

        |------|-----------|----------------------|

        | **header** | Cabeçalho do template | text, image, video, document |

        | **body** | Corpo principal | text, currency, date_time |

        | **button** | Botões interativos | text, payload |


        ### **Sub-tipos de Botão:**


        - `quick_reply`: Resposta rápida (payload)

        - `url`: Botão com link dinâmico (text para variável da URL)

        - `phone_number`: Botão de telefone


        ---


        ## 📝 **Exemplos Práticos**


        ### **1️⃣ Template Simples de Texto**


        **Template aprovado no WhatsApp:**

        ```

        Olá {{1}}! Bem-vindo à nossa loja.

        ```


        **Requisição:**

        ```json

        {
          "inboxId": "65f1a2b3c4d5e6f7g8h9i0j1",
          "templateName": "welcome_message",
          "languageCode": "pt_BR",
          "components": [
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "João" }
              ]
            }
          ],
          "contacts": [
            { "name": "João Silva", "phone": "5511999999999" }
          ]
        }

        ```


        **Resultado:** _"Olá João! Bem-vindo à nossa loja."_


        ---


        ### **2️⃣ Template com Header de Imagem**


        **Template aprovado:**

        ```

        [HEADER: IMAGEM]

        Olá {{1}}!

        Confira nossa promoção de {{2}}.

        ```


        **Requisição:**

        ```json

        {
          "inboxId": "...",
          "templateName": "promotion",
          "languageCode": "pt_BR",
          "components": [
            {
              "type": "header",
              "parameters": [
                {
                  "type": "image",
                  "image": { "link": "https://example.com/promo.jpg" }
                }
              ]
            },
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "João" },
                { "type": "text", "text": "Black Friday" }
              ]
            }
          ],
          "contacts": [...]
        }

        ```


        ---


        ### **3️⃣ Template com Botão URL Dinâmico**


        **Template aprovado:**

        ```

        Olá! Seu pedido #{{1}} foi confirmado.

        [BOTÃO URL: Rastrear Pedido - https://example.com/track/{{1}}]

        ```


        **Requisição:**

        ```json

        {
          "inboxId": "...",
          "templateName": "order_confirmation",
          "languageCode": "pt_BR",
          "components": [
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "12345" }
              ]
            },
            {
              "type": "button",
              "sub_type": "url",
              "index": "0",
              "parameters": [
                { "type": "text", "text": "12345" }
              ]
            }
          ],
          "contacts": [...]
        }

        ```


        ---


        ### **4️⃣ Template com Documento no Header**


        **Template aprovado:**

        ```

        [HEADER: DOCUMENTO]

        Olá {{1}}, segue seu boleto de cobrança.

        ```


        **Requisição:**

        ```json

        {
          "inboxId": "...",
          "templateName": "invoice",
          "languageCode": "pt_BR",
          "components": [
            {
              "type": "header",
              "parameters": [
                {
                  "type": "document",
                  "document": {
                    "link": "https://example.com/boleto.pdf",
                    "filename": "boleto_janeiro.pdf"
                  }
                }
              ]
            },
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "João Silva" }
              ]
            }
          ],
          "contacts": [...]
        }

        ```


        ---


        ### **5️⃣ Template com Moeda e Data**


        **Template aprovado:**

        ```

        Olá {{1}}!

        Sua fatura de {{2}} no valor de {{3}} vence em {{4}}.

        ```


        **Requisição:**

        ```json

        {
          "inboxId": "...",
          "templateName": "billing",
          "languageCode": "pt_BR",
          "components": [
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "João" },
                { "type": "text", "text": "Janeiro/2024" },
                {
                  "type": "currency",
                  "currencyCode": "BRL",
                  "currencyAmount": 150.50
                },
                {
                  "type": "date_time",
                  "dateTime": "2024-01-31T23:59:59Z"
                }
              ]
            }
          ],
          "contacts": [...]
        }

        ```


        **Resultado:** _"Olá João! Sua fatura de Janeiro/2024 no valor de R$
        150,50 vence em 31/01/2024."_


        ---


        ### **6️⃣ Template Carousel (Carrossel)**


        Templates tipo carrossel permitem enviar múltiplos cards deslizáveis.


        ```json

        {
          "inboxId": "...",
          "templateName": "product_catalog",
          "languageCode": "pt_BR",
          "isCarousel": true,
          "carouselCards": [
            {
              "card_index": 0,
              "components": [
                {
                  "type": "HEADER",
                  "parameters": [
                    {
                      "type": "image",
                      "image": { "link": "https://example.com/product1.jpg" }
                    }
                  ]
                },
                {
                  "type": "BODY",
                  "parameters": [
                    { "type": "text", "text": "Produto 1" },
                    { "type": "text", "text": "R$ 99,90" }
                  ]
                },
                {
                  "type": "BUTTON",
                  "sub_type": "quick_reply",
                  "index": 0,
                  "parameters": [
                    { "type": "payload", "payload": "product_1" }
                  ]
                }
              ]
            },
            {
              "card_index": 1,
              "components": [
                // Componentes do card 2...
              ]
            }
          ],
          "contacts": [...]
        }

        ```


        ---


        ## 📊 **Resposta da API**


        ### **Schema de Resposta:**

        ```typescript

        {
          totalProcessed: number,      // Total de contatos processados
          sentCount: number,            // Quantidade enviada com sucesso
          errorCount: number,           // Quantidade de erros
          sentContacts: [               // Contatos enviados com sucesso
            {
              conversationId: string,   // ID da conversa criada/utilizada
              phoneNumber: string       // Número de telefone formatado
            }
          ],
          errors: [                     // Erros detalhados
            {
              row: number,              // Linha do erro (arquivo ou índice)
              contact: string,          // Nome do contato
              error: string             // Descrição do erro
            }
          ]
        }

        ```


        ### **Exemplo de Resposta:**

        ```json

        {
          "totalProcessed": 100,
          "sentCount": 95,
          "errorCount": 5,
          "sentContacts": [
            {
              "conversationId": "65f1a2b3c4d5e6f7g8h9i0j1",
              "phoneNumber": "5511999999999"
            },
            {
              "conversationId": "65f1a2b3c4d5e6f7g8h9i0j2",
              "phoneNumber": "5511888888888"
            }
          ],
          "errors": [
            {
              "row": 5,
              "contact": "João Silva",
              "error": "Número de telefone inválido"
            },
            {
              "row": 23,
              "contact": "Maria Santos",
              "error": "Template não encontrado para este inbox"
            }
          ]
        }

        ```


        ---


        ## ⚠️ **Observações Importantes**


        ### **Validações e Restrições:**


        1. **✅ Templates Aprovados**: Só é possível enviar templates previamente
        aprovados pelo Meta/WhatsApp

        2. **⏱️ Limite de Taxa**: O WhatsApp possui limites de envio
        (tier-based):
           - Tier 1: até 1.000 conversas únicas/dia
           - Tier 2: até 10.000 conversas únicas/dia
           - Tier 3: até 100.000 conversas únicas/dia
        3. **📞 Validação de Números**: Números são validados automaticamente
        (formato internacional E.164)

        4. **🕐 Janela de 24h**: Templates podem ser enviados FORA da janela de
        24 horas

        5. **🎯 Parâmetros Corretos**: Número e tipo de parâmetros devem
        coincidir EXATAMENTE com o template

        6. **🔢 Índices de Botão**: Botões dinâmicos são indexados começando em
        `"0"` (string)

        7. **🖼️ Formato de Mídia**: Links de mídia devem ser URLs públicas
        HTTPS acessíveis

        8. **📦 Tamanho de Lote**: Recomenda-se enviar em lotes de até 1.000
        contatos por vez


        ### **Códigos de Idioma Aceitos:**


        | Código | Idioma |

        |--------|--------|

        | `pt_BR` | Português (Brasil) |

        | `pt_PT` | Português (Portugal) |

        | `en_US` | Inglês (EUA) |

        | `en_GB` | Inglês (Reino Unido) |

        | `es_ES` | Espanhol (Espanha) |

        | `es_MX` | Espanhol (México) |

        | `fr_FR` | Francês |

        | `de_DE` | Alemão |

        | `it_IT` | Italiano |


        ### **Limites do WhatsApp por Tipo de Mídia:**


        | Tipo | Tamanho Máximo | Formatos Aceitos |

        |------|----------------|------------------|

        | **Imagem** | 5 MB | JPG, JPEG, PNG |

        | **Vídeo** | 16 MB | MP4, 3GPP |

        | **Documento** | 100 MB | PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT |

        | **Áudio** | 16 MB | AAC, M4A, AMR, MP3, OGG |


        ---


        ## 🔗 **Tipos de Parâmetros Suportados**


        | Tipo | Uso | Campos Obrigatórios | Exemplo |

        |------|-----|---------------------|---------|

        | `text` | Texto simples | `text` | `{ "type": "text", "text": "João" }`
        |

        | `image` | Imagem (header) | `image.link` | `{ "type": "image",
        "image": { "link": "https://..." } }` |

        | `video` | Vídeo (header) | `video.link` | `{ "type": "video", "video":
        { "link": "https://..." } }` |

        | `document` | Documento (header) | `document.link`, `document.filename`
        | `{ "type": "document", "document": { "link": "https://...",
        "filename": "doc.pdf" } }` |

        | `currency` | Valor monetário | `currencyCode`, `currencyAmount` | `{
        "type": "currency", "currencyCode": "BRL", "currencyAmount": 99.90 }` |

        | `date_time` | Data/hora | `dateTime` (ISO 8601) | `{ "type":
        "date_time", "dateTime": "2024-01-15T10:30:00Z" }` |

        | `payload` | Dados para botão | `payload` | `{ "type": "payload",
        "payload": "button_data" }` |


        ---


        ## 🚀 **Boas Práticas**


        1. **Teste com poucos contatos** antes de enviar para uma lista grande

        2. **Valide seus números** no formato internacional (ex: 5511999999999)

        3. **Use templates específicos** para cada caso de uso

        4. **Monitore as estatísticas** de entrega na resposta da API

        5. **Respeite os limites** de taxa do WhatsApp

        6. **Mantenha templates atualizados** e aprovados

        7. **Use CSV/XLSX** para listas grandes (melhor performance)

        8. **Implemente retry** para contatos que falharam
      operationId: MessageController_sendBulkTemplate
      parameters:
        - name: x-company-id
          in: header
          description: >-
            Identificador da empresa-alvo. Obrigatório apenas para API Keys
            globais (type=global). Ignorado para API Keys de empresa e usuários
            humanos.
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/SendBulkTemplateMessageDto'
      responses:
        '201':
          description: >-
            Envio em massa executado com sucesso (retorna estatísticas
            detalhadas)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkTemplateResponseDto'
        '400':
          description: Dados inválidos
        '401':
          description: Token inválido ou expirado
        '403':
          description: Sem permissão para acessar este recurso
      security:
        - JWT-auth: []
components:
  schemas:
    SendBulkTemplateMessageDto:
      type: object
      properties:
        inboxId:
          type: string
          minLength: 1
          description: ID do inbox/conexão WhatsApp que será usado para enviar
        templateName:
          type: string
          minLength: 1
          description: Nome do template registrado no WhatsApp Business
        languageCode:
          type: string
          default: pt_BR
          description: 'Código de idioma do template (formato: pt_BR, en_US, en, etc)'
        components:
          type: array
          description: >-
            Lista de componentes do template com seus parâmetros/variáveis. Use
            para personalizar header, body e buttons com dados dinâmicos.
          items:
            type: object
            properties:
              type:
                type: string
                enum:
                  - header
                  - body
                  - button
                description: Tipo do componente (header, body, button)
              sub_type:
                description: Subtipo do componente (usado principalmente para botões)
                type: string
                enum:
                  - quick_reply
                  - url
                  - phone_number
              index:
                description: >-
                  Índice do componente (usado para identificar botões
                  específicos)
                anyOf:
                  - type: string
                  - type: number
              parameters:
                description: Lista de parâmetros/variáveis deste componente
                type: array
                items:
                  type: object
                  properties:
                    type:
                      type: string
                      enum:
                        - text
                        - image
                        - document
                        - video
                        - currency
                        - date_time
                        - payload
                      description: Tipo do parâmetro
                    image:
                      description: Configurações de imagem (quando type = "image")
                      type: object
                      properties:
                        link:
                          description: URL da imagem
                          type: string
                        id:
                          description: ID da imagem já carregada
                          type: string
                    document:
                      description: Configurações de documento (quando type = "document")
                      type: object
                      properties:
                        link:
                          description: URL do documento
                          type: string
                        filename:
                          description: Nome do arquivo do documento
                          type: string
                    video:
                      description: Configurações de vídeo (quando type = "video")
                      type: object
                      properties:
                        link:
                          description: URL do vídeo
                          type: string
                    text:
                      description: Texto do parâmetro
                      type: string
                    value:
                      description: Valor genérico do parâmetro (alias para text)
                      type: string
                    link:
                      description: Link genérico
                      type: string
                    imageUrl:
                      description: URL alternativa para imagem
                      type: string
                    imageId:
                      description: ID da imagem (quando já carregada)
                      type: string
                    documentUrl:
                      description: URL alternativa para documento
                      type: string
                    documentFilename:
                      description: Nome alternativo do arquivo
                      type: string
                    videoUrl:
                      description: URL alternativa para vídeo
                      type: string
                    currencyCode:
                      description: 'Código da moeda (ex: BRL, USD, EUR)'
                      type: string
                    currencyAmount:
                      description: Valor monetário
                      type: number
                    dateTime:
                      description: Data/hora no formato ISO 8601
                      type: string
                    payload:
                      description: Dados customizados em formato string
                      type: string
                    parameter_name:
                      description: Nome do parâmetro (para templates nomeados)
                      type: string
                    variable_ref:
                      description: >-
                        Referência a variável automática (ex: V_contact_name).
                        Se presente, o valor será resolvido automaticamente do
                        contact/business/conversation.
                      type: string
                    variable_type:
                      description: >-
                        Tipo da variável: "auto" = resolvida automaticamente,
                        "free" = input manual
                      type: string
                      enum:
                        - auto
                        - free
                  required:
                    - type
            required:
              - type
        contacts:
          type: array
          description: >-
            Lista de contatos que receberão o template. Opcional se você enviar
            um arquivo CSV/Excel com os contatos.
          items:
            type: object
            properties:
              name:
                type: string
                minLength: 1
                description: Nome completo do contato
              phone:
                type: string
                minLength: 8
                description: 'Número de telefone com código de país (ex: 5511999999999)'
            required:
              - name
              - phone
        who_will_answer:
          type: string
          default: AGENT
          description: >-
            Define quem responderá após o envio do template. Valores: AGENT
            (agente IA), HUMAN (atendente humano). Padrão: AGENT
          enum:
            - AGENT
            - HUMAN
            - UNASSIGNED
        agentToActivate:
          type: string
          description: >-
            ID do agente IA que será ativado para responder. Usado em conjunto
            com who_will_answer=AGENT
      required:
        - inboxId
        - templateName
    BulkTemplateResponseDto:
      type: object
      properties:
        totalProcessed:
          type: number
          description: Total de contatos processados
        sentCount:
          type: number
          description: Quantidade de mensagens enviadas com sucesso
        errorCount:
          type: number
          description: Quantidade de erros durante o envio
        errors:
          type: array
          items:
            type: object
            properties:
              row:
                type: number
                description: Linha do erro no arquivo/lista
              contact:
                type: string
                description: Contato que falhou
              error:
                type: string
                description: Descrição do erro
            required:
              - row
              - contact
              - error
          description: Lista detalhada de erros ocorridos
        sentContacts:
          type: array
          items:
            type: object
            properties:
              conversationId:
                type: string
                description: ID da conversa criada/utilizada
              phoneNumber:
                type: string
                description: Número de telefone do contato
            required:
              - conversationId
              - phoneNumber
          description: Lista de contatos que receberam a mensagem com sucesso
      required:
        - totalProcessed
        - sentCount
        - errorCount
        - errors
        - sentContacts
  securitySchemes:
    JWT-auth:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: Token JWT de autenticação

````