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

# Envío masivo

> Envía plantillas de forma masiva a múltiples destinatarios y consulta el estado de tus campañas

Utiliza esta función para enviar plantillas de forma masiva a tus clientes. La API se encargará de la entrega a los destinatarios desde un archivo basado en columnas.

Enviar plantillas de forma masiva te permite enviar una plantilla predefinida con diferentes valores relacionados con cada cliente, de manera que puedas seleccionar información dinámica desde una fuente como un archivo, para automatizar y enviar tu campaña fácilmente.

***

## Directrices para las plantillas

El archivo fuente debe ser creado siguiendo las siguientes especificaciones:

### Formato de archivo

Solo se admiten archivos con la extensión `.CSV`.

### Encabezado

La primera fila del archivo debe definir los nombres de las columnas (encabezado). Sigue estas reglas para el encabezado:

* Evita los **espacios en blanco** en los nombres de las columnas.
* No uses **caracteres especiales** ni **signos de puntuación** (por ejemplo, `!, $, %, &, *, etc.`).
* Usa solo **letras**, **números** y **guiones bajos** (`_`) si es necesario.

**Correcto:** `phone_number`, `customer_name`, `order_amount`

**Incorrecto:** `phone number`, `customer-name!`, `order#amount`

### Primera columna

La primera columna debe contener los números de teléfono de los destinatarios. Es obligatorio incluir el código internacional sin el símbolo `+` (por ejemplo, para un número en Ecuador, escribe `PHONE_NUMBER`).

### Columnas restantes

Las otras columnas se usarán para los valores dinámicos de los parámetros (personalización de la plantilla).

***

## Ejemplo

Si tu plantilla contiene el siguiente contenido:

```
Tu pedido {{1}} por un total de {{2}} está confirmado. La entrega esperada es {{3}}.
```

El archivo CSV sería:

| phone\_number    | param\_1 | param\_2 | param\_3       |
| ---------------- | -------- | -------- | -------------- |
| PHONE\_NUMBER    | A12345   | \$250.00 | 1 de diciembre |
| PHONE\_NUMBER\_2 | B67890   | \$100.50 | 2 de diciembre |
| PHONE\_NUMBER\_3 | C22345   | \$50.00  | 3 de diciembre |

<Note>
  El archivo CSV debe estar codificado en UTF-8.
</Note>

***

## Enviar HSM desde archivo

```
POST https://api.jelou.ai/v1/hsm/file
```

***

## Opciones de carga de archivo

Existen dos formas de proporcionar el archivo CSV con la información de los destinatarios:

1. **Usando una URL pública**: Puedes proporcionar la URL al archivo CSV que esté disponible públicamente. En este caso, el cuerpo de la solicitud debe estar en formato JSON.

2. **Subiendo el archivo**: Alternativamente, puedes adjuntar el archivo CSV directamente a la solicitud. En este caso, el cuerpo de la solicitud debe estar en formato `multipart/form-data`.

***

## Parámetros del cuerpo

| Propiedad          | Tipo   | Descripción                                                                                                                                           | Requerido   |
| ------------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| **campaignName**   | string | Nombre asignado a la campaña que se está enviando.                                                                                                    | Sí          |
| **elementName**    | string | Nombre de la plantilla. Debe tener estado **aprobado** por WhatsApp.                                                                                  | Sí          |
| **botId**          | string | Identificador único del bot que envía la plantilla.                                                                                                   | Sí          |
| **params**         | array  | Arreglo de objetos con el número de parámetro y la columna correspondiente del CSV. Si la plantilla no tiene parámetros, el arreglo debe estar vacío. | Sí          |
| **type**           | string | Tipo de plantilla: `text`, `image`, `document`, `video`. Por defecto es `text`.                                                                       | No          |
| **mediaUrl**       | string | URL pública del archivo multimedia. Necesario para plantillas de imagen, video o documento.                                                           | Condicional |
| **fileUrl**        | string | URL pública del archivo CSV. Requerido si no se sube el archivo directamente.                                                                         | Condicional |
| **file**           | file   | Archivo CSV adjunto. Requerido si no se usa `fileUrl`.                                                                                                | Condicional |
| **buttonPayloads** | array  | Arreglo de objetos para botones de respuesta rápida con workflows.                                                                                    | No          |
| **actions**        | object | Acciones relacionadas con la plantilla.                                                                                                               | No          |
| **scheduledAt**    | date   | Fecha y hora en UTC cuando se enviará la campaña.                                                                                                     | No          |

***

## Ejemplos de solicitud

<AccordionGroup>
  <Accordion title="Envío desde URL pública (JSON)">
    ```bash theme={null}
    curl --request POST \
      --url https://api.jelou.ai/v1/hsm/file \
      --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
      --header 'Content-Type: application/json' \
      --data '{
        "campaignName": "campaign_name",
        "botId": "BOT_ID",
        "elementName": "ELEMENT_NAME",
        "params": [
          {"param": 1, "column": "customer_name"}
        ],
        "mediaUrl": "https://cdn.ejemplo.com/imagen.png",
        "type": "image",
        "fileUrl": "https://cdn.ejemplo.com/campana.csv",
        "buttonPayloads": [
          {"type": "edge", "action": "Yes", "skillId": "1"}
        ]
      }'
    ```
  </Accordion>

  <Accordion title="Envío con archivo adjunto (multipart/form-data)">
    ```bash theme={null}
    curl --request POST \
      --url https://api.jelou.ai/v1/hsm/file \
      --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
      --form campaignName=campaign_name \
      --form botId=BOT_ID \
      --form elementName=ELEMENT_NAME \
      --form 'buttonPayloads=[{"type":"edge","action":"Yes","skillId":"1"},{"type":"edge","action":"Reschedule","skillId":"2"},{"type":"edge","action":"Cancel","skillId":"3"}]' \
      --form file=@/ruta/local/campana.csv \
      --form 'params=[]'
    ```
  </Accordion>
</AccordionGroup>

***

## Respuestas del envío

<AccordionGroup>
  <Accordion title="200 - Respuesta exitosa">
    ```json theme={null}
    {
      "message": ["Campaign has been created."],
      "status": "success"
    }
    ```
  </Accordion>

  <Accordion title="400 - Bad Request">
    ```json theme={null}
    {
      "message": ["Invalid CSV format"],
      "status": "failed"
    }
    ```
  </Accordion>

  <Accordion title="401 - Unauthorized">
    ```json theme={null}
    {
      "message": "Authentication failed"
    }
    ```
  </Accordion>

  <Accordion title="422 - Unprocessable Entity">
    ```json theme={null}
    {
      "message": ["Template not found or not approved"],
      "status": "failed"
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Estructura de params

Cada elemento en el arreglo `params` es un objeto que contiene:

```json theme={null}
[
  {"param": 1, "column": "customer_name"},
  {"param": 2, "column": "order_amount"}
]
```

* **param**: Número del parámetro en la plantilla (1, 2, 3...).
* **column**: Nombre de la columna en el archivo CSV de donde se extraerán los valores.

***

## Estructura de buttonPayloads

Para plantillas con botones de respuesta rápida que activan workflows:

```json theme={null}
[
  {"type": "edge", "action": "Yes", "skillId": "1"},
  {"type": "edge", "action": "Reschedule", "skillId": "2"},
  {"type": "edge", "action": "Cancel", "skillId": "3"}
]
```


## OpenAPI

````yaml POST /v1/hsm/file
openapi: 3.1.0
info:
  title: Jelou API
  description: >-
    API for the Jelou platform. Send messages, manage campaigns, handle
    conversations, users, databases, and widgets.
  version: 1.0.0
servers:
  - url: https://api.jelou.ai
    description: Production server
security:
  - basicAuth: []
tags:
  - name: Messages
    description: Send messages to users
  - name: Campaigns
    description: HSM campaigns and templates
  - name: Conversations
    description: Chat history and metrics
  - name: Users
    description: User state and cache management
  - name: Resources
    description: Media resource management
  - name: Datum
    description: Database CRUD operations
  - name: Widget
    description: Widget and room management
  - name: PMA Custom
    description: External support panel integration
paths:
  /v1/hsm/file:
    post:
      tags:
        - Campaigns
      summary: Send Bulk HSM
      description: Send HSM templates in bulk to multiple recipients using a CSV file.
      operationId: sendBulkHSM
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkHSMJsonRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BulkHSMFormRequest'
      responses:
        '200':
          description: Campaign created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkHSMResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
components:
  schemas:
    BulkHSMJsonRequest:
      type: object
      required:
        - campaignName
        - elementName
        - botId
        - params
      properties:
        campaignName:
          type: string
        elementName:
          type: string
        botId:
          type: string
        params:
          type: array
          items:
            $ref: '#/components/schemas/CSVParam'
        type:
          type: string
          enum:
            - text
            - image
            - document
            - video
          default: text
        mediaUrl:
          type: string
          format: uri
        fileUrl:
          type: string
          format: uri
        buttonPayloads:
          type: array
          items:
            type: object
        actions:
          type: object
        scheduledAt:
          type: string
          format: date-time
    BulkHSMFormRequest:
      type: object
      required:
        - campaignName
        - elementName
        - botId
        - params
        - file
      properties:
        campaignName:
          type: string
        elementName:
          type: string
        botId:
          type: string
        params:
          type: string
          description: JSON string of params array
        file:
          type: string
          format: binary
        buttonPayloads:
          type: string
          description: JSON string
    BulkHSMResponse:
      type: object
      properties:
        message:
          type: array
          items:
            type: string
        status:
          type: string
    CSVParam:
      type: object
      properties:
        param:
          type: integer
        column:
          type: string
    Error:
      type: object
      properties:
        message:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
        statusMessage:
          type: string
        status:
          type: integer
        error:
          type: object
          properties:
            code:
              type: string
            key:
              type: string
            description:
              type: string
            developerMessages:
              type: object
            clientMessages:
              type: object
        validationError:
          type: object
  responses:
    BadRequest:
      description: Bad request - Invalid format or missing required fields
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized - Invalid authentication credentials
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    UnprocessableEntity:
      description: Unprocessable entity - Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Basic authentication using Base64 encoded clientId:clientSecret

````