---
title: "Referencia de la API de mensajería"
description: "Lee conversaciones y envía texto, archivos y plantillas de WhatsApp en WhatsApp, Instagram, Facebook, TikTok y el widget del sitio web con la Public API."
canonical_url: https://chatfuel.com/es/docs/public-api/messaging
markdown_url: https://chatfuel.com/es/docs/public-api/messaging.md
last_updated: 2026-10-06
lang: es
site: https://chatfuel.com/docs
llms_txt: https://chatfuel.com/llms.txt
---

# Referencia de la API de mensajería

Lee conversaciones y envía texto, archivos y plantillas de WhatsApp en WhatsApp, Instagram, Facebook, TikTok y el widget del sitio web con la Public API.

La parte de mensajería de la Public API de Chatfuel cubre la bandeja de entrada: leer conversaciones y sus mensajes, enviar texto, archivos y plantillas de WhatsApp a contactos en todos los canales, tomar un chat como humano y devolverlo a un flow, y escuchar mensajes nuevos en tiempo real. Todo funciona para usuarios virtuales **Agent**, así que una integración de soporte o de CRM no necesita el rol Editor.

Una conversación pertenece a un contacto, y su `id` es el mismo valor que el ID del contacto. Siempre que una operación pida un `conversationID`, puedes pasar el ID del contacto de la [API de contactos](https://chatfuel.com/es/docs/public-api/contacts).

## Cómo leer conversaciones y mensajes [#cómo-leer-conversaciones-y-mensajes]

```graphql
type Bot {
  # Agent. The conversation with one contact.
  conversation(conversationID: ConversationID!): Conversation!
  # Agent. Number of conversations per status: open, closed, automated.
  conversationCount: [ConversationCountEntry!]!
  # Agent. Open conversations nobody has looked at yet.
  unseenOpenDialogsCount: Int!
  # Agent. The inbox list: contacts with conversations, filtered like the dashboard inbox.
  contactChatsConnection(
    first: Int!, before: ContactSearchCursor, after: ContactSearchCursor,
    assigneeFilter: ContactAssigneeFilter!, unreadOnly: Boolean!,
    salesStageV2Filter: [SalesStageV2!]!, textInputFilter: String
  ): ContactConnection!
}
```

```graphql
query Chat($botID: BotID!, $contactID: ConversationID!) {
  bot(id: $botID) {
    conversation(conversationID: $contactID) {
      id
      platform          # whatsapp, instagram, facebook, tiktok, widget
      status            # open, closed, automated
      read
      messages(first: 20) {
        edges {
          node {
            id
            sentTime
            sender { name }
            errors { code originalErrMessage }
            ... on WhatsAppInTextMessage { text }
            ... on WhatsAppOutTextMessage { text whatsappStatus }
          }
        }
        pageInfo { hasNextPage endCursor }
      }
    }
  }
}
```

`Message` es una interfaz con un tipo por canal, dirección y contenido, por ejemplo `WhatsAppInTextMessage`, `InstagramInStoryReplyMessage` o `FacebookOutAttachment`. Selecciona los campos de los tipos que manejas y omite el resto; pueden aparecer nuevos tipos de mensaje en cualquier momento.

## Cómo enviar mensajes [#cómo-enviar-mensajes]

Cada canal tiene una mutación de texto y una de archivo adjunto. Todas reciben el ID del bot y el ID de la conversación (el ID del contacto) y funcionan para **Agent**:

```graphql
type Mutation {
  whatsAppTextMessageSend(botID: BotID!, conversationID: ConversationID!, message: WhatsAppTextMessageSendInput): WhatsAppOutTextMessage
  whatsappAttachmentMessageSend(botID: BotID!, conversationID: ConversationID!, message: WhatsAppAttachmentMessageSendInput!): WhatsAppOutAttachment
  instagramTextMessageSend(botID: BotID!, conversationID: ConversationID!, message: InstagramTextMessageSendInput!): InstagramOutTextMessage!
  instagramAttachmentMessageSend(botID: BotID!, conversationID: ConversationID!, message: InstagramAttachmentMessageSendInput!): InstagramOutAttachment
  facebookTextMessageSend(botID: BotID!, conversationID: ConversationID!, message: FacebookTextMessageSendInput!): FacebookOutTextMessage!
  facebookAttachmentMessageSend(botID: BotID!, conversationID: ConversationID!, message: FacebookAttachmentMessageSendInput!): FacebookOutAttachment
  tiktokTextMessageSend(botID: BotID!, conversationID: ConversationID!, message: TikTokTextMessageSendInput!): TikTokOutTextMessage!
  tiktokAttachmentMessageSend(botID: BotID!, conversationID: ConversationID!, message: TikTokAttachmentMessageSendInput!): TikTokOutAttachment
  widgetTextMessageSend(botID: BotID!, conversationID: ConversationID!, message: WidgetTextMessageSendInput): WebWidgetTextMessage
  widgetAttachmentMessageSend(botID: BotID!, conversationID: ConversationID!, message: WidgetAttachmentMessageSendInput): WebWidgetAttachmentMessage
}
```

```graphql
mutation Reply($botID: BotID!, $contactID: ConversationID!) {
  whatsAppTextMessageSend(
    botID: $botID
    conversationID: $contactID
    message: { text: "Hi! Your order has shipped.", clientId: "order-1042-shipped" }
  ) {
    id
    whatsappStatus
    errors { code originalErrMessage }
  }
}
```

`clientId` es un ID opcional que eliges tú; vuelve en el mensaje y en los eventos de suscripción, así puedes vincular tus propios registros con los mensajes de Chatfuel. Para los archivos adjuntos, sube el archivo al endpoint de carga del chat descrito en [cómo hacer solicitudes](https://chatfuel.com/es/docs/public-api/requests) y pasa su ID. En WhatsApp, `attachmentType` es `image`, `document` o `audio`. Las mutaciones de archivos adjuntos pueden fallar con `FileContentTypeNotSupported`, `FileTooBig` o `FileDoesNotExist`.

Las reglas de cada canal siguen vigentes. En WhatsApp, un mensaje libre llega al contacto solo dentro de la [ventana de mensajería de 24 horas](https://chatfuel.com/es/docs/whatsapp/24-hour-messaging-window) después del último mensaje del contacto; pasado ese plazo, envía una plantilla aprobada. Instagram y Facebook tienen ventanas de mensajería similares. Los problemas de entrega aparecen en los `errors` del mensaje.

## Cómo enviar una plantilla de WhatsApp [#cómo-enviar-una-plantilla-de-whatsapp]

Enviar una plantilla lleva tres pasos: elegir una plantilla aprobada, completar sus parámetros y enviar la plantilla completada. Todos los pasos funcionan para **Agent**.

```graphql
type Bot {
  # Agent. The bot's WhatsApp templates with their status, language, category and components.
  whatsAppTemplates(first: Int, after: WhatsAppTemplateCursor, before: WhatsAppTemplateCursor): WhatsappTemplates
  filledWhatsAppTemplate(id: FilledWhatsAppTemplateID!): FilledWhatsAppTemplate!
}

type Mutation {
  # 1. Create a one-time filled copy of a template.
  filledWhatsAppTemplateCreateTemporary(botID: BotID!, templateID: WhatsAppTemplateID!): FilledWhatsAppTemplate!
  # 2. Fill in variables and media.
  filledWhatsAppTemplateSetHeaderTextParamValue(templateID: FilledWhatsAppTemplateID!, name: WhatsAppTemplateTextParamName!, value: String!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetBodyTextParamValue(templateID: FilledWhatsAppTemplateID!, name: WhatsAppTemplateTextParamName!, value: String!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetFooterTextParamValue(templateID: FilledWhatsAppTemplateID!, name: WhatsAppTemplateTextParamName!, value: String!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetHeaderImageFile(templateID: FilledWhatsAppTemplateID!, fileID: FileID!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetHeaderVideoFile(templateID: FilledWhatsAppTemplateID!, fileID: FileID!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetHeaderDocumentFile(templateID: FilledWhatsAppTemplateID!, fileID: FileID!, fileName: String!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetURLButtonParamValue(templateID: FilledWhatsAppTemplateID!, buttonID: ComponentHandleID!, name: WhatsAppTemplateTextParamName!, value: String!): FilledWhatsAppTemplate!
  filledWhatsAppTemplateSetCopyCodeButtonCodeValue(templateID: FilledWhatsAppTemplateID!, buttonID: ComponentHandleID!, codeValue: String!): FilledWhatsAppTemplate!
  # 3. Send it to the contact.
  whatsAppTemplateSend(botID: BotID!, conversationID: ConversationID!, template: WhatsAppTemplateSendInput): WhatsAppOutTemplateMessage
}
```

Las imágenes, videos y documentos del encabezado se suben al endpoint de carga de plantillas descrito en [archivos y tareas](https://chatfuel.com/es/docs/public-api/files-and-tasks). Revisa `FilledWhatsAppTemplate.errors` antes de enviar: lista los parámetros que siguen vacíos o no son válidos. Usa solo plantillas cuyo `IsSupportedInLivechat` sea `true`. [Cómo crear plantillas de WhatsApp](https://chatfuel.com/es/docs/whatsapp/how-to-create-whatsapp-templates) explica cómo se crean y aprueban las plantillas.

## Cómo tomar un chat y devolverlo [#cómo-tomar-un-chat-y-devolverlo]

```graphql
type Mutation {
  # Agent. Returns the conversation with a contact, creating it if the contact has none yet.
  conversationCreate(contactID: ContactID!): Conversation!
  # Agent. Opens a live chat with the contact (status open), like a teammate taking over the chat in the inbox.
  conversationStart(botID: BotID!, conversationID: ConversationID!): Conversation!
  # Agent. Closes the live chat and sends the contact to a flow.
  conversationFinishSendToFlow(botID: BotID!, conversationID: ConversationID!, flowID: FlowID!): Conversation!
  # Agent. Marks messages up to the given one as read.
  conversationReadMessages(botID: BotID!, conversationID: ConversationID!, before: MessageID!): Conversation!
}
```

Los chats en vivo pueden cerrarse automáticamente tras un periodo sin mensajes. `bot.livechatAutoClosingConfig` muestra esta configuración a cualquier usuario virtual; cambiarla con `botSetLivechatAutoClosingConfig(botID, cfg: { enabled, delay })`, donde `delay` va de `Minutes10` a `Days7`, es **Personal token only** (solo con token personal) y requiere el rol Admin.

## Suscripciones de mensajería [#suscripciones-de-mensajería]

```graphql
type Subscription {
  # Agent. A new message in one conversation, incoming or outgoing.
  messageAdded(botID: BotID!, conversationID: ConversationID!): Message
  # Agent. A message changed, for example its WhatsApp delivery status.
  messageUpdated(botID: BotID!, conversationID: ConversationID!): Message
  # Agent. Changes in the inbox list for the given filters.
  contactsChatUpdates(
    botID: BotID!, assigneeFilter: ContactAssigneeFilter!, unreadOnly: Boolean!,
    salesStageV2Filter: [SalesStageV2!]!, textInputFilter: String
  ): ContactsChatUpdate
  # Agent. The number of unseen open conversations changed.
  unseenOpenDialogsCountChanged(botID: BotID!): Int
}
```

Para seguir toda la bandeja de entrada, suscríbete a `contactsChatUpdates` con `assigneeFilter: { type: Any }` y luego abre `messageAdded` para las conversaciones que te interesan.

## Problemas comunes [#problemas-comunes]

### Un mensaje de WhatsApp se acepta pero nunca se entrega [#un-mensaje-de-whatsapp-se-acepta-pero-nunca-se-entrega]

Probablemente la ventana de 24 horas está cerrada. Lee `errors` en el mensaje devuelto o espera `messageUpdated`; para llegar al contacto, envía una plantilla aprobada con `whatsAppTemplateSend`.

### "NotEnoughPermissions" al enviar un mensaje [#notenoughpermissions-al-enviar-un-mensaje]

La conversación pertenece a otro bot, o la configuración de roles del bot limita al usuario virtual a los contactos asignados a él. Asigna el contacto al usuario virtual con `contactSetAssignee` o cambia la configuración de roles, como se describe en [equipo y roles](https://chatfuel.com/es/docs/public-api/team-and-roles).

### "FileContentTypeNotSupported" [#filecontenttypenotsupported]

El canal no acepta este tipo de archivo, o el `fileType` usado al subirlo no coincide con `attachmentType`. Vuelve a subir el archivo con el tipo correcto.
