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

# Chatbots y conversaciones de texto

> Envía conversaciones de chat web, SMS, WhatsApp y otros canales de texto al mismo endpoint de Zelto que utilizan las llamadas de voz, sin necesidad de audio.

Zelto ingiere conversaciones de texto —de chatbots, agentes de mensajería o
cualquier asistente basado en texto, como chat web, SMS, WhatsApp o chat dentro
de la aplicación— mediante el **mismo endpoint** que las llamadas de voz:
`POST https://ingest.zelto.ai/webhooks/calls`. Una conversación de texto es una
llamada con transcripción y sin audio. Como la transcripción ya existe, Zelto
omite ese paso; todo lo demás —resúmenes, [hallazgos](/es/docs/findings),
revisiones e informes— funciona igual que con una llamada de voz.

La creación de claves, la idempotencia y la gestión de errores se comparten con
[Proveedores personalizados y otros](/es/docs/integrations/api-call-upload).
Esta página explica únicamente lo específico de las conversaciones de texto.

<Tip>
  ¿Tu agente está construido sobre **Kapso**? Usa la
  [integración nativa de Kapso](/es/docs/integrations/kapso): conecta la clave de
  API del proyecto y Zelto importa tus números de WhatsApp y sus conversaciones sin
  código de carga.
</Tip>

## Crear una clave

Las cargas de texto utilizan la misma clave de API que cualquier otra carga
personalizada. Sigue los pasos de
[Proveedores personalizados y otros → Crear una clave](/es/docs/integrations/api-call-upload#crear-una-clave)
en **Configuración → Integraciones → Carga de llamadas por API** y expón la clave
como `ZELTO_API_KEY`.

## Subir una conversación de chat

Envía los mensajes en `transcript.turns`: utiliza `role: "user"` para la persona
y `role: "assistant"` para el agente. Omite los campos de audio y telefonía.
Solo son obligatorios `call.externalId` y una referencia al agente.

```bash theme={null}
curl -X POST https://ingest.zelto.ai/webhooks/calls \
  -H "Authorization: Bearer $ZELTO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Zelto-Provider: zelto" \
  -d @chat.json
```

```json title="chat.json" theme={null}
{
  "agent": { "externalId": "support-chatbot", "name": "Support Chatbot" },
  "call": {
    "externalId": "chat_01HXYZ",
    "startedAt": "2026-05-29T15:00:00Z",
    "endedAt": "2026-05-29T15:04:12Z"
  },
  "transcript": {
    "turns": [
      { "role": "user", "content": "Hi, I need to reschedule my appointment." },
      { "role": "assistant", "content": "Happy to help — what day works for you?" }
    ]
  },
  "metadata": { "channel": "web-chat" }
}
```

Una carga correcta devuelve HTTP `200` con `{ "received": true }`.

**Campos que debes enviar:**

* `agent.externalId`, para que Zelto busque o cree el agente, o `agentId`, el
  UUID de un agente existente. Utiliza un identificador estable por agente, no
  por conversación.
* `call.externalId`, un identificador único y estable para la conversación y la
  clave de idempotencia.
* `transcript.turns[]`, los mensajes en orden como turnos `user` y `assistant`.
* `call.startedAt` y `call.endedAt`, las horas de inicio y fin en ISO 8601. Son
  opcionales, pero permiten ordenar y filtrar por hora.
* `metadata.channel`, para guardar el canal (`web-chat`, `sms`, `whatsapp` o
  `in-app`) y poder filtrarlo después. No existe un campo específico para el
  canal.

**Campos que debes omitir:**

* `recordingUrl` y `recordingUploadId`, porque no hay audio que volver a alojar.
* `startSeconds`, `endSeconds` y `words[]` por turno, ya que solo se utilizan para
  reproducir una transcripción sincronizada con audio.
* `durationSeconds` y `customer.number` cuando no tengan un equivalente útil en
  la conversación de texto.

<Note>
  Una entrega **sin transcripción ni grabación** se considera una llamada vacía.
  Zelto responde con `200`, pero no crea una conversación porque no hay nada que
  analizar. Una conversación de texto debe incluir al menos un elemento en
  `transcript.turns`.
</Note>

### Invocaciones de herramientas

Si el chatbot invoca herramientas durante la conversación, por ejemplo para
consultar disponibilidad o buscar un pedido, envía cada invocación como un turno
`tool` con un objeto `toolCall`, igual que para un agente de voz. Zelto la muestra
en la transcripción y la incluye en el análisis. Consulta
[Invocaciones de herramientas](/es/docs/integrations/api-call-upload#invocaciones-de-herramientas)
para ver los campos y un ejemplo.

### Cargas repetidas idempotentes

`call.externalId` es la clave de idempotencia. Si vuelves a enviar el mismo
identificador, Zelto **actualiza** la conversación existente y nunca la duplica.
Por eso, tanto los reintentos como los reenvíos posteriores de enriquecimiento
son seguros. Consulta
[Cargas repetidas idempotentes](/es/docs/integrations/api-call-upload#cargas-repetidas-idempotentes).

## Conversaciones representadas como llamadas

Zelto ingiere y analiza completamente las conversaciones de texto, pero su modelo
y su interfaz todavía utilizan terminología de voz. Una conversación ingerida se
etiqueta como una «llamada» y, si no proporcionas un nombre más descriptivo para
el agente, recibe el nombre `Call <externalId>`. Tampoco existe todavía un campo
de modalidad o canal de primer nivel: el valor de `metadata` se guarda y se puede
consultar, pero la interfaz no identifica la conversación como chat. Todas las
funciones de análisis siguen disponibles; solo cambia la terminología visible.

## Contenido relacionado

* [Proveedores personalizados y otros](/es/docs/integrations/api-call-upload) — contrato compartido de carga, claves, errores y cargas nativas de Vapi y Retell.
* [Conversaciones](/es/docs/conversations) — dónde aparecen las conversaciones cargadas.
* [Referencia de API](/es/api-reference/agents/list-agents) — convenciones REST, formato completo y área de pruebas.
* [MCP](/es/docs/mcp) — utiliza la misma clave para ofrecer acceso de lectura y escritura a editores conectados.
