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

# Llamadas con mensaje

> Realiza una o varias llamadas desde una línea existente y lee un mensaje personalizado en cada una.

El paso `voice.message` realiza hasta 100 llamadas salientes desde una línea de voz existente. Cada llamada tiene su propio número destino y su propio texto para leer.

> [!NOTE]
>
> Este paso no crea ni compra líneas. Antes de usarlo necesitas el identificador de una línea activa que ya pertenezca a tu cuenta y tenga habilitadas las llamadas.

### Antes de empezar

Pide estos valores al administrador de tu cuenta:

* `phoneLineId`: identificador de la línea desde la que saldrán las llamadas.
* `voice`, si quieres elegir una voz: identificador habilitado para tu cuenta.

La API de automatizaciones no crea líneas ni enumera voces. Si omites `voice`, se usa la voz predeterminada de tu cuenta.

## Ejemplo mínimo

```json theme={null}
{
  "name": "Recordar cita",
  "actionKey": "voice.message",
  "input": {
    "phoneLineId": "<phone-line-id>",
    "calls": [
      {
        "to": "+525512345678",
        "script": "Hola María. Te recordamos que tu cita es mañana a las diez."
      }
    ]
  }
}
```

`script` es texto plano, no JavaScript. El servicio lo convierte a voz durante la llamada. Usa puntuación para producir pausas naturales.

## Campos de entrada

### `input`

| Campo | Tipo | Requerido | Descripción |
| - | - | - | - |
| `phoneLineId` | `string` | Sí | Identificador de una línea existente, activa y habilitada para llamadas. |
| `calls` | `array` o plantilla | Sí | Entre 1 y 100 llamadas, o una plantilla completa que resuelva a ese arreglo. |
| `defaults` | `object` | No | Configuración común. Cada llamada puede sobrescribir voz, idioma, pausa y tiempo de timbrado. |

### Cada elemento de `calls`

| Campo | Tipo | Requerido | Descripción |
| - | - | - | - |
| `to` | `string` | Sí | Número destino. Se recomienda E.164, por ejemplo `+525512345678`. |
| `script` | `string` | Sí | Texto que se leerá. De 1 a 3,000 caracteres; acepta plantillas `{{...}}`. |
| `voice` | `string` | No | Identificador de voz habilitado para tu cuenta. |
| `language` | `string` | No | Idioma y región, por ejemplo `es-MX`. |
| `pauseAfterMessageSeconds` | `integer` | No | Silencio antes de colgar, de 0 a 60 segundos. |
| `ringTimeoutSeconds` | `integer` | No | Tiempo máximo de timbrado, de 5 a 600 segundos. |

### `defaults`

| Campo | Tipo | Predeterminado | Rango |
| - | - | - | - |
| `voice` | `string` | Voz predeterminada de la cuenta | Identificador válido de voz |
| `language` | `string` | `es-MX` | Código como `es-MX` o `en-US` |
| `pauseAfterMessageSeconds` | `integer` | `2` | 0–60 |
| `ringTimeoutSeconds` | `integer` | `30` | 5–600 |
| `pollIntervalSeconds` | `integer` | `5` | 2–300 |
| `completionTimeoutSeconds` | `integer` | `3600` | 30–86400 |

> [!TIP]
>
> Define la configuración común en `defaults` y agrega campos dentro de una llamada solo cuando esa llamada necesite un valor diferente.

## Personalizar cada llamada

Las plantillas se resuelven antes de marcar. Puedes combinar texto fijo con datos del trigger o de pasos anteriores:

```json theme={null}
{
  "name": "Avisar a clientes",
  "actionKey": "voice.message",
  "input": {
    "phoneLineId": "<phone-line-id>",
    "defaults": {
      "language": "es-MX",
      "voice": "<voice-id>",
      "pauseAfterMessageSeconds": 3,
      "ringTimeoutSeconds": 25
    },
    "calls": [
      {
        "to": "{{trigger.body.primaryPhone}}",
        "script": "Hola {{trigger.body.primaryName}}. Tu póliza {{trigger.body.policyNumber}} está lista."
      },
      {
        "to": "{{trigger.body.secondaryPhone}}",
        "script": "Hola {{trigger.body.secondaryName}}. Tenemos una actualización sobre la póliza {{trigger.body.policyNumber}}.",
        "voice": "<alternate-voice-id>"
      }
    ]
  }
}
```

No repitas el mismo número dentro del paso. Los destinos literales duplicados se rechazan al guardar la definición. Si los números provienen de plantillas, se comprueban al ejecutar, después de normalizarlos.

## Usar una lista creada por otro paso

Si un paso anterior devuelve el arreglo completo, asigna una **plantilla completa** a `calls`. No la mezcles con texto adicional:

```json theme={null}
{
  "name": "Llamar a la lista preparada",
  "actionKey": "voice.message",
  "input": {
    "phoneLineId": "<phone-line-id>",
    "calls": "{{steps.0.output.calls}}",
    "defaults": {
      "language": "es-MX"
    }
  }
}
```

El valor de `steps.0.output.calls` debe tener esta forma:

```json theme={null}
[
  {
    "to": "+525512345678",
    "script": "Hola María. Tu pago vence mañana."
  },
  {
    "to": "+525587654321",
    "script": "Hola Luis. Tu pago vence el viernes."
  }
]
```

## Qué ocurre durante la ejecución

El paso continúa activo mientras las llamadas se procesan. La automatización avanza al siguiente paso cuando todas llegan a un estado final o cuando se alcanza `completionTimeoutSeconds`.

`pollIntervalSeconds` controla cada cuánto se consultan estados y se programan llamadas pendientes. Para listas grandes, configura `completionTimeoutSeconds` con margen para programar todas las llamadas, esperar el timbrado y reproducir los mensajes.

Cada llamada también aparece en la sección **Llamadas** de la plataforma, asociada con la línea elegida. Desde ahí puedes consultar su destino, estado y duración disponible.

> [!WARNING]
>
> Publicar o ejecutar el mismo workflow de nuevo crea un nuevo grupo de llamadas. Usa tus propios controles de negocio si un evento no debe notificar dos veces al mismo contacto.

## Salida

```json theme={null}
{
  "total": 3,
  "completed": 1,
  "failed": 2,
  "calls": [
    {
      "to": "+525512345678",
      "callSid": "<call-id>",
      "status": "completed",
      "durationSeconds": 18
    },
    {
      "to": "+525587654321",
      "callSid": "<call-id>",
      "status": "busy"
    },
    {
      "to": "+525500000000",
      "status": "dispatch-failed",
      "error": "Descripción del error"
    }
  ]
}
```

| Campo | Descripción |
| - | - |
| `total` | Número de llamadas solicitadas. |
| `completed` | Llamadas que terminaron con estado `completed`. |
| `failed` | Todas las llamadas que no terminaron como `completed`. |
| `calls[].to` | Destino normalizado a E.164. |
| `calls[].callSid` | Identificador de la llamada, cuando llegó a crearse. |
| `calls[].status` | Resultado final o estado operativo de esa llamada. |
| `calls[].durationSeconds` | Duración reportada, cuando está disponible. |
| `calls[].error` | Explicación cuando la llamada no pudo despacharse o terminó por timeout. |

Una llamada ocupada o sin respuesta no hace fallar por sí sola la ejecución del workflow. Revisa `calls[].status` o `failed` en el siguiente paso para decidir qué hacer.

### Guardar un resumen en `context`

Agrega `capture` al mismo paso si varios pasos posteriores necesitan los contadores:

```json theme={null}
{
  "name": "Recordar citas",
  "actionKey": "voice.message",
  "input": {
    "phoneLineId": "<phone-line-id>",
    "calls": "{{steps.0.output.calls}}"
  },
  "capture": {
    "completedCalls": {
      "from": "response.body",
      "path": "completed"
    },
    "failedCalls": {
      "from": "response.body",
      "path": "failed"
    }
  }
}
```

Después puedes usar `{{context.completedCalls}}` y `{{context.failedCalls}}`.

### Estados habituales

| Estado | Significado |
| - | - |
| `completed` | La llamada terminó después de reproducir las instrucciones. |
| `busy` | El destino estaba ocupado. |
| `no-answer` | Nadie contestó dentro del tiempo configurado. |
| `failed` | El servicio de voz no pudo completar la llamada. |
| `canceled` | La llamada se canceló antes de completarse. |
| `dispatch-failed` | No fue posible solicitar la llamada. Consulta `error`. |
| `dispatch-unknown` | No se repitió una solicitud cuyo resultado era incierto, para evitar marcar dos veces. |
| `timed-out` | El workflow dejó de esperar antes de recibir un estado final. La llamada puede actualizarse después en **Llamadas**. |

Mientras el paso sigue activo, la sección **Llamadas** también puede mostrar estados intermedios como `queued`, `ringing` o `in-progress`.

> [!NOTE]
>
> `calls[].error` es texto diagnóstico y puede estar en inglés. No automatices decisiones comparando ese texto; usa `calls[].status`.

## Usar la salida en el siguiente paso

```json theme={null}
{
  "name": "Reportar resultado",
  "actionKey": "http.request",
  "input": {
    "method": "POST",
    "url": "https://ejemplo.com/hooks/resultado-llamadas",
    "headers": {
      "Content-Type": "application/json"
    },
    "body": {
      "total": "{{steps.1.output.total}}",
      "completadas": "{{steps.1.output.completed}}",
      "fallidas": "{{steps.1.output.failed}}",
      "llamadas": "{{steps.1.output.calls}}"
    }
  }
}
```

En este ejemplo `steps.1` supone que `voice.message` ocupa la posición 1 del arreglo `steps`. Ajusta el índice a la posición real de tu paso.

## Errores frecuentes

| Situación | Qué revisar |
| - | - |
| `VOICE_MESSAGE_INVALID_DESTINATION` | Incluye el código de país y usa E.164. |
| `VOICE_MESSAGE_DUPLICATE_DESTINATION` | Elimina números repetidos del arreglo. |
| `Phone line not found` | Confirma que `phoneLineId` existe y pertenece a tu cuenta. |
| `VOICE_MESSAGE_PHONE_LINE_UNAVAILABLE` | Confirma que la línea está activa y permite llamadas. |
| `VOICE_MESSAGE_TWIML_TOO_LARGE` | Reduce `script`; el límite aplica a las instrucciones generadas y los caracteres especiales pueden ocupar más espacio. |
| `Invalid voice.message step ... duplicate literal destinations` | Elimina números literales repetidos antes de guardar la automatización. |
| Voz o idioma inválidos | Usa una combinación de `voice` y `language` habilitada para tu cuenta. |
| Todas quedan en `timed-out` | Aumenta `completionTimeoutSeconds` si tu lista tarda en procesarse. |

## Relacionado

* [Crear automatización](/automatizaciones/crear-automatizacion)
* [Tipos de paso](/automatizaciones/tipos-de-paso)
* [Variables y contexto](/automatizaciones/variables-y-contexto)
* [Consultar una ejecución](/automatizaciones/consultar-ejecucion)
* [Listar pasos de una ejecución](/automatizaciones/listar-pasos-ejecucion)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.