Your AI Connector Docs

Mensajes y conversaciones

La API de Mensajes le permite enviar un mensaje a cualquier contacto, leer una conversación, corregir o eliminar un mensaje que ya envió, reaccionar a uno, extraer un hilo completo de sesión de chat, exportar una transcripción y marcar chats como leídos o no leídos, todo sin abrir la bandeja de entrada.

Todas las rutas en esta página son relativas a la URL base https://api.youraiconnector.com/v1. Cada solicitud requiere su clave de API; consulte Autenticación para ver la lista completa de formas de enviarla. Los ejemplos a continuación utilizan el encabezado X-API-Key, y un ejemplo de cURL muestra también el formato de consulta ?apiKey=.

Cómo funciona la entrega: El envío de un mensaje no espera a que llegue. La API acepta su mensaje, responde inmediatamente con un ID de mensaje y luego lo entrega en segundo plano a través del canal del contacto (WhatsApp, SMS, Instagram, etc.). Para realizar un seguimiento de si un mensaje se entregó o leyó realmente, escuche las actualizaciones de estado con Webhooks; no realice sondeos (polling). La respuesta de envío solo confirma que el mensaje fue aceptado.


Enviar un mensaje

Hay dos formas de enviar. Elija la que mejor se adapte a cómo identifica actualmente al contacto:

  • Enviar por ID de contacto: usted ya conoce el ID del contacto (por ejemplo, creó el contacto a través de la API u lo obtuvo de un webhook). Use POST /contacts/{contactId}/send-message.
  • Enviar por identidad de contacto: usted conoce el número de teléfono, el ID de Instagram, etc., del contacto, pero no su ID interno. Use POST /contacts/send y deje que la plataforma encuentre el contacto correcto.

Ambos ponen el mensaje en cola de la misma manera y lo entregan en el canal en el que se encuentre el contacto. Usted no elige el transporte; la plataforma enruta los contactos de WhatsApp a través de WhatsApp, los contactos de SMS a través de SMS, y así sucesivamente.

Enviar por ID de contacto

POST /contacts/{contactId}/send-message

Campo Obligatorio Descripción
body El texto del mensaje a enviar.
mediaUrl No URL de un archivo multimedia (imagen, documento, etc.) para adjuntar.
mediaContentType No Tipo MIME del archivo multimedia adjunto, p. ej. image/jpeg.
pauseBot No true pausa la IA para este contacto a medida que se envía el mensaje, para cuando un humano toma el control. Consulta Pausar o reanudar la IA.
clearIncompleteReply No true descarta una respuesta del bot a medio terminar para que no se reanude después de tu mensaje.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      body: "Hi! Your appointment is confirmed for tomorrow at 10:00.",
    }),
  }
);
const data = await res.json();
console.log(data.messageId);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])

Respuesta (200 OK):

{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}

Enviar por identidad de contacto

POST /contacts/send

Utilice esto cuando no tenga el ID interno del contacto. Proporcione el body del mensaje más o bien un contact_id, o bien un channel junto con el campo de identidad que coincida con ese canal.

Campo Obligatorio Descripción
body El texto del mensaje a enviar.
contact_id No ID de un contacto existente. Cuando se establece, los campos de identidad a continuación no son necesarios.
channel No Canal a través del cual enviar. Obligatorio cuando no se proporciona contact_id. Uno de los 14 canales de envío saliente: whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber.
phone_number No Número de teléfono del contacto en formato internacional. Se utiliza con whatsapp, whatsapp_web y sms.
instagram_id No ID de usuario de Instagram del contacto. Se utiliza con instagram.
messenger_id No ID de usuario de Messenger del contacto. Se utiliza con messenger.
telegram_user_id No ID de usuario de Telegram del contacto. Se utiliza con telegram.
media_url No URL de un archivo multimedia para adjuntar.
media_content_type No Tipo MIME del archivo multimedia adjunto, p. ej., image/jpeg.

Qué canales pueden resolverse mediante identidad. Solo seis de los 14 aceptan un campo de identidad en lugar de un contact_id: whatsapp, whatsapp_web y sms se buscan mediante phone_number, instagram mediante instagram_id, messenger mediante messenger_id, y telegram mediante telegram_user_id. Los otros ocho — instagram_private, chat-widget, custom, email, line, imessage, linkedin y viber — no tienen una identidad pública que buscar, por lo que enviar a través de esos canales requiere contact_id; pasar solo channel devuelve un 400 indicando que se requiere contact_id.

cURL (usando el formato de consulta ?apiKey=)

curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number": "+31612345678",
    "body": "Hi! Your appointment is confirmed."
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    channel: "whatsapp",
    phone_number: "+31612345678",
    body: "Hi! Your appointment is confirmed.",
  }),
});
const data = await res.json();
console.log(data.message_id, data.channel);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/send",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "channel": "whatsapp",
        "phone_number": "+31612345678",
        "body": "Hi! Your appointment is confirmed.",
    },
)
data = res.json()
print(data["message_id"], data["channel"])

Respuesta (201 Created):

{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp"
}

Por qué un mensaje podría ser rechazado: Un contacto con el modo “no molestar” o privado activado no puede recibir mensajes salientes; la solicitud falla con un 422. Si ningún contacto coincide con el ID o la identidad que proporcionó, obtendrá un 404.


Listar los mensajes de un contacto

GET /contacts/{contactId}/messages

Devuelve los mensajes de un contacto, del más reciente al más antiguo, con paginación basada en cursor.

Parámetro de consulta Obligatorio Descripción
limit No Tamaño de página. Predeterminado 50, máximo 100.
cursor No El valor next_cursor de una respuesta anterior. Devuelve mensajes anteriores al cursor.
filter No Filtrar por tipo de contenido: all (predeterminado), text, media o tool_use.
direction No Filtrar por dirección: all (predeterminado), inbound (recibido del contacto) o outbound (enviado por usted).

Nota sobre el filtrado y la paginación: Los filtros filter y direction se aplican a cada página después de ser leída, por lo que una página filtrada puede contener menos elementos que limit. El next_cursor sigue avanzando a través de la conversación completa, así que continúe paginando hasta que next_cursor sea null.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
  `https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T10:00:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ],
  "next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}

Campos del mensaje

Campo Descripción
id ID único del mensaje.
body Contenido de texto del mensaje.
direction inbound (recibido del contacto) o outbound (enviado por su cuenta).
channel Canal por el que se envió o recibió el mensaje (p. ej., whatsapp, sms, instagram).
status Estado de entrega actual, p. ej., Created, sent, delivered, read, failed.
type Tipo de mensaje. Los mensajes de texto sin formato tienen un tipo null; la actividad de la herramienta de asistente automatizado se marca como tool_use.
timestamp Hora ISO 8601 en la que se creó el mensaje.
media_url URL de un archivo multimedia adjunto, si existe.
media_content_type Tipo MIME del archivo multimedia adjunto, si existe.
bot_reply true cuando el mensaje fue generado por el asistente de IA.
score Su calificación del mensaje: 1 pulgar arriba, -1 pulgar abajo, 0 cuando no ha sido calificado. Consulte Calificar o destacar un mensaje.
is_important true cuando el mensaje ha sido destacado.
is_deleted true cuando el mensaje ha sido eliminado. Los mensajes eliminados permanecen en la lista pero su body y media_url están vacíos.
reactions Reacciones con emojis en el mensaje, de ambas partes. Siempre es una matriz; vacía cuando no hay ninguna. Cada entrada tiene emoji, from_phone_number, from_me (true cuando la reacción es suya) y reacted_at.

Listar sesiones de chat

Una sesión de chat es una ventana de conversación con un contacto: se abre cuando empiezan a hablar y se cierra cuando la conversación concluye. Las sesiones son la forma en que usted pagina un historial largo en conversaciones legibles en lugar de una lista interminable.

Sesiones recientes de todos los contactos

GET /chat-sessions/recent

Devuelve las sesiones que comenzaron en las últimas X horas, de la más reciente a la más antigua, en todos los contactos de la cuenta.

Parámetro de consulta Requerido Descripción
hours Cuántas horas mirar hacia atrás. Debe ser un número entero positivo.
status No Solo devolver sesiones con este estado: ChatSessionOpened o ChatSessionClosed.
limit No Número máximo de sesiones a devolver. Predeterminado 100, máximo 100.
includeMessages No true añade una matriz messages a cada sesión. Desactivado por defecto porque hace que la respuesta sea mucho más grande.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-sessions/recent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])

Respuesta (200 OK):

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_sessions": 2,
    "sessions": [
      {
        "session_id": "session456",
        "contact_id": "contact123",
        "contact_name": "Jane Doe",
        "contact_phone": "+31612345678",
        "contact_email": "jane@example.com",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Todas las sesiones de un contacto

GET /chat-sessions/{contactId}

Devuelve todas las sesiones de chat de un solo contacto. Los mismos parámetros status, limit y includeMessages que arriba; hours no se aplica aquí.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

Respuesta (200 OK):

{
  "success": true,
  "data": {
    "contact_id": "contact123",
    "contact_name": "Jane Doe",
    "total_sessions": 2,
    "sessions": [
      {
        "id": "session456",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Los nombres de los campos de ID de sesión difieren entre los dos endpoints. La lista de sesiones recientes lo llama session_id (también contiene los detalles del contacto, ya que las sesiones provienen de muchos contactos); la lista por contacto lo llama id. Cualquiera de los dos valores es lo que usted pasa como {sessionId} al recuperar el hilo completo a continuación.

Cuando includeMessages=true, cada sesión obtiene una matriz messages cuyas entradas contienen id, body, direction, timestamp, type, channel y status.


Obtener un hilo de sesión de chat

GET /contacts/{contactId}/chat-sessions/{sessionId}/messages

Una sesión de chat agrupa los mensajes de un contacto en una única ventana de conversación. Este endpoint devuelve el hilo completo de una sola sesión, del más antiguo al más reciente, junto con los metadatos de la sesión. Puede encontrar los ID de sesión de un contacto a través de los endpoints de sesiones de chat.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "session": {
    "id": "session456",
    "status": "ChatSessionClosed",
    "start_date_time": "2026-06-01T09:55:00.000Z",
    "end_date_time": "2026-06-01T10:20:00.000Z",
    "tag": "Booking enquiry"
  },
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T09:55:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ]
}

El objeto session informa sobre status (ChatSessionOpened mientras está activa, ChatSessionClosed una vez finalizada), start_date_time, end_date_time y un tag legible por humanos. La matriz messages utiliza los mismos campos de mensaje que el endpoint de lista.


Editar, eliminar y reaccionar a mensajes

Estos endpoints cambian un mensaje después de haber sido enviado. Dos de ellos se comunican con el canal del contacto además de con su propia copia, así que lea la introducción de la sección antes de configurarlos; lo que es posible depende totalmente del canal en el que se encuentre la conversación.

Qué permite cada canal

Acción Canales que pueden cambiar la copia del contacto Límite de tiempo
Editar un mensaje enviado Widget de chat, WhatsApp Web, Telegram, LinkedIn Ninguno en el widget de chat, 15 minutos en WhatsApp Web, 48 horas en Telegram, 60 minutos en LinkedIn
Eliminar para todos Widget de chat, WhatsApp Web, Telegram, LinkedIn 60 minutos en LinkedIn; los demás no tienen un límite publicado
Reaccionar con un emoji WhatsApp Web, Telegram Ninguno

En cualquier otro canal —la API de WhatsApp Business, SMS, Instagram, Messenger, correo electrónico, LINE, canales personalizados—, una eliminación sigue quitando el mensaje de su bandeja de entrada, pero el contacto conserva su copia, y editar o reaccionar no es posible en absoluto.

Editar un mensaje

POST /contacts/{contactId}/messages/{messageId}/edit

Reescribe un mensaje que ya envió, tanto en el dispositivo del contacto como en su copia.

Campo Obligatorio Descripción
body El nuevo texto del mensaje. No debe estar vacío y puede tener un máximo de 4096 caracteres.

A diferencia de la eliminación, esto falla de forma notoria cuando el canal lo rechaza: obtiene un 409 y su copia se queda exactamente igual a como la tiene el contacto, porque mostrar una edición que nunca recibieron desincronizaría ambas partes. El campo edit_reason le indica el motivo: la ventana de edición del canal ha expirado, el canal está desconectado o algo salió mal.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Sorry - I meant Thursday at 3pm." }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
  }
);
const data = await res.json();
console.log(data.edited, data.edit_reason);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "edited": true,
  "edit_reason": "edit_dispatched"
}

Si el canal no acepta la edición, obtendrá un 409 en su lugar y nada habrá cambiado:

{
  "success": false,
  "error": "The message could not be edited",
  "edit_reason": "channel_disconnected"
}

Un mensaje que ya ha sido eliminado, un canal que no permite editar en absoluto y un mensaje demasiado antiguo para su canal devuelven 400: la solicitud nunca llega al canal.

Eliminar un mensaje

DELETE /contacts/{contactId}/messages/{messageId}

Elimina el mensaje de su conversación y, cuando el canal lo permite, también retira la copia del contacto. No requiere cuerpo de solicitud.

Esto siempre responde 200 cuando el mensaje existía, incluso si la copia del contacto no pudo ser retirada; su copia ha desaparecido, por lo que un error sería engañoso. Lea los tres campos en la respuesta para informar al usuario de lo que realmente sucedió:

Campo Descripción
revoke_supported Si este canal puede retirar mensajes en absoluto.
revoked Si se eliminó la copia en el dispositivo del contacto.
revoke_reason Por qué no se eliminó, cuando revoked es false; por ejemplo, revoke_window_closed o already_deleted.

cURL

curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);

Python

import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "revoke_supported": true,
  "revoked": true,
  "revoke_reason": "revoke_dispatched"
}

Los mensajes eliminados no se borran del historial de la conversación. Permanecen en GET /contacts/{contactId}/messages con is_deleted: true y un body y media_url vacíos.

Eliminar varios mensajes a la vez

POST /contacts/{contactId}/messages/bulk-delete

Borra un lote de mensajes solo de tu lado. Los cuerpos y archivos adjuntos se vacían, pero no se retira nada en el dispositivo del contacto; para retirar también un mensaje, elimínalo uno a uno con el endpoint de mensaje único anterior.

Campo Requerido Descripción
message_ids Una matriz no vacía de IDs de mensaje, hasta 500 por solicitud. messageIds se acepta como alias.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message_ids": ["msg_1", "msg_2"] }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
  }
);
console.log((await res.json()).deleted);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "deleted": 2
}

Reaccionar a un mensaje

POST /contacts/{contactId}/messages/{messageId}/react

Coloca tu propia reacción con emoji en un mensaje, o retírala enviando una cadena vacía. Las reacciones del propio contacto nunca se ven afectadas.

Campo Requerido Descripción
emoji El emoji con el que reaccionar, o "" para eliminar tu reacción. Debe ser una cadena única sin espacios, de máximo 16 caracteres.

Al igual que la edición, esto falla en lugar de mostrar una reacción que el contacto nunca recibió, y el error te indica si vale la pena reintentarlo:

  • 422 — nunca se puede entregar en esta conversación: el canal no admite reacciones, el mensaje no tiene un ID del lado del canal, o el emoji está fuera del conjunto permitido por ese canal.
  • 409 — el canal no estuvo disponible momentáneamente. Un reintento podría funcionar.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "emoji": "👍" }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emoji: "👍" }),
  }
);
const data = await res.json();
console.log(data.reactions);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"emoji": "👍"},
)
print(res.json()["reactions"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "reaction_supported": true,
  "reaction_reason": "reaction_dispatched",
  "reactions": [
    {
      "emoji": "👍",
      "from_phone_number": "+31612345678",
      "from_me": true,
      "reacted_at": "2026-06-01T10:05:00.000Z"
    }
  ]
}

La matriz reactions es el conjunto completo de reacciones que hay ahora en el mensaje, las tuyas y las del contacto. En un 409 o 422 se devuelve sin cambios, por lo que un cliente que renderice directamente desde ella nunca mostrará una reacción que no se haya entregado.

Calificar o destacar un mensaje

PATCH /contacts/{contactId}/messages/{messageId}

Califica un mensaje con pulgar arriba o pulgar abajo y/o lo marca como importante. Esto es contabilidad solo de tu lado; no se envía nada al contacto.

Campo Obligatorio Descripción
score No 1 pulgar hacia arriba, -1 pulgar hacia abajo, 0 borra la calificación.
is_important No true marca el mensaje con una estrella, false le quita la estrella. Debe ser un booleano real, no la cadena "true".

Envíe al menos uno de los dos, o recibirá un 400. Solo se escribe lo que usted envía, por lo que marcar un mensaje con estrella nunca borra su calificación y viceversa; además, la respuesta solo devuelve los campos que usted envió.

cURL

curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "score": 1, "is_important": true }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
  method: "PATCH",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ score: 1, is_important: true }),
});

Python

import requests

requests.patch(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"score": 1, "is_important": True},
)

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "score": 1,
  "is_important": true
}

Marcar mensajes como leídos

Puede borrar el estado de no leído ya sea para mensajes específicos o para toda la conversación.

Marcar mensajes específicos como leídos

POST /contacts/{contactId}/messages/mark-read

Pase los ID de los mensajes que desea marcar como leídos.

Campo Requerido Descripción
message_ids Una matriz no vacía de ID de mensajes (hasta 500 por solicitud).

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
    }),
  }
);
const data = await res.json();
console.log(data.marked_read);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "marked_read": 2
}

Marcar todo el chat como leído

POST /contacts/{contactId}/mark-read

Borra el distintivo de no leído de toda la conversación del contacto en la bandeja de entrada. No se requiere cuerpo de solicitud.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123"
}

Marcar todo el chat como no leído

POST /contacts/{contactId}/mark-unread

Vuelve a colocar la insignia de no leído en la conversación; es útil cuando alguien de su equipo abrió un chat pero lo está devolviendo. No se requiere cuerpo de solicitud.

Este es un indicador exclusivo de la bandeja de entrada: no cambia cuándo se leyó la conversación por última vez, por lo que no se envía ningún recibo de lectura al contacto en los canales que los admiten.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
  -H "X-API-Key: YOUR_API_KEY"

Respuesta (200 OK):

{
  "success": true,
  "contact_id": "contact123"
}

Exportar una conversación

Las exportaciones le ofrecen una conversación completa como una transcripción legible, en lugar de pasar páginas de mensajes. Cada punto final de exportación acepta un filter de all (predeterminado), text, media o tool_use, que coincide con el filtro de la lista de mensajes.

Exportar el chat de un contacto

GET /chat-exports/{contactId}

Parámetro de consulta Obligatorio Descripción
format No txt (predeterminado) devuelve un enlace de descarga a una transcripción en texto plano. json devuelve los mensajes como datos estructurados en la respuesta.
filter No all (predeterminado), text, media o tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
  -H "X-API-Key: YOUR_API_KEY"

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-exports/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"format": "json"},
)
print(res.json()["data"]["messages"])

Respuesta con format=json (200 OK):

{
  "success": true,
  "data": {
    "contact": {
      "id": "contact123",
      "name": "Jane Doe",
      "phone": "+31612345678",
      "email": "jane@example.com"
    },
    "messages": [
      {
        "body": "Hi! I have a question about my order.",
        "direction": "inbound",
        "timestamp": "2026-06-01T09:55:00.000Z",
        "type": "text",
        "media_url": null,
        "media_content_type": null,
        "name": null,
        "args": null
      }
    ]
  }
}

Con format=txt (el predeterminado), data es en su lugar un enlace de descarga al archivo de transcripción generado:

{
  "success": true,
  "data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}

El enlace de descarga tiene una duración limitada. Obtenga el archivo tan pronto como reciba el enlace en lugar de almacenarlo; solicite una nueva exportación cuando necesite la transcripción nuevamente.

Exportar todas las conversaciones recientes

GET /chat-exports/recent

Exporta las conversaciones de todos los contactos que estuvieron activos en las últimas X horas, en una sola llamada.

Parámetro de consulta Obligatorio Descripción
hours Cuántas horas de actividad revisar hacia atrás. Debe ser un número entero positivo.
format No json (predeterminado) devuelve una entrada por contacto. txt devuelve un único archivo de texto descargable con todas las conversaciones.
limit No Número máximo de contactos a exportar. Predeterminado 50, máximo 100.
filter No all (predeterminado), text, media o tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
  -H "X-API-Key: YOUR_API_KEY"

Respuesta (200 OK):

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_contacts": 2,
    "exports": [
      {
        "contactId": "contact123",
        "contactName": "Jane Doe",
        "phoneNumber": "+31612345678",
        "email": "jane@example.com",
        "messageCount": 12,
        "chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
      }
    ]
  }
}

Con format=txt la respuesta es el archivo de texto en sí, enviado como una descarga en lugar de JSON.

Esta llamada obtiene el historial completo de cada contacto coincidente, así que mantenga hours y limit moderados en cuentas con mucha actividad.

Enviar una transcripción por correo electrónico al contacto

POST /chat-exports/{contactId}/email

Envía al contacto su propia transcripción de la conversación por correo electrónico: el flujo “enviarme este chat por correo”, gestionado desde su propio sistema.

Campo Obligatorio Descripción
recipient_email No Dónde enviarlo. De forma predeterminada, utiliza la dirección de correo electrónico almacenada del contacto.
via No auto (predeterminado) elige la mejor ruta, transactional lo envía como un correo electrónico del sistema, email_channel lo envía desde su canal de correo electrónico conectado.
note No Una breve línea suya que se muestra sobre la transcripción. Hasta 1000 caracteres.

cURL

curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Here is a copy of our chat, as promised." }'

Respuesta (200 OK):

{
  "success": true,
  "data": {
    "via": "transactional",
    "recipientEmail": "jane@example.com",
    "messageCount": 42,
    "omittedCount": 0
  }
}

omittedCount le indica cuántos de los mensajes más antiguos se omitieron para mantener el correo electrónico con una longitud razonable. Un 200 significa que la transcripción se generó y se puso en cola para su envío, no que haya llegado a la bandeja de entrada todavía.


Pausar o reanudar la IA para un contacto

PUT /contacts/{contactId}

Establece is_bot_active en false para detener las respuestas de la IA a un contacto, y vuelve a true para devolver la conversación. Este es el interruptor de control que necesitas cuando un humano interviene en una conversación: los mensajes salientes que envías con la API se siguen entregando mientras el bot está pausado.

cURL

curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_bot_active": false }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ is_bot_active: false }),
});

Python

import requests

requests.put(
    "https://api.youraiconnector.com/v1/contacts/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"is_bot_active": False},
)

Respuesta

{
  "success": true,
  "contact_id": "contact123"
}

Pausar como parte de la respuesta

Si un humano toma el control enviando una respuesta, puedes pausar el bot en la misma solicitud en lugar de realizar una segunda llamada. POST /contacts/{contactId}/send-message acepta dos indicadores opcionales:

Campo Descripción
pauseBot true pausa la IA para este contacto a medida que se envía el mensaje.
clearIncompleteReply true descarta una respuesta del bot a medio terminar para que no se reanude después.
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi, Sarah here - taking over from the assistant.",
    "pauseBot": true,
    "clearIncompleteReply": true
  }'

La respuesta incluye "botPaused": true cuando se aplicó la pausa.

Marcar un contacto como privado con POST /contacts/bulk-flag también pausa el bot para él. Consulta Contactos para ver la lista completa de campos.


Construyendo tu propia bandeja de entrada

Todo lo que necesita una bandeja de entrada está en esta página y en Contactos:

Lo que necesita Endpoint
Listar conversaciones GET /contacts
Leer una conversación GET /contacts/{contactId}/messages
Listar las sesiones de chat de un contacto GET /chat-sessions/{contactId}
Ver lo que ha llegado recientemente GET /chat-sessions/recent
Leer una sesión de chat GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Enviar una respuesta manual POST /contacts/{contactId}/send-message
Corregir una respuesta que acaba de enviar POST /contacts/{contactId}/messages/{messageId}/edit
Eliminar un mensaje DELETE /contacts/{contactId}/messages/{messageId}
Borrar varios mensajes POST /contacts/{contactId}/messages/bulk-delete
Reaccionar con un emoji POST /contacts/{contactId}/messages/{messageId}/react
Calificar o marcar un mensaje PATCH /contacts/{contactId}/messages/{messageId}
Marcar como leído POST /contacts/{contactId}/mark-read
Devolver un chat al equipo POST /contacts/{contactId}/mark-unread
Exportar una transcripción GET /chat-exports/{contactId}
Pausar o reanudar la IA PUT /contacts/{contactId} con is_bot_active

Para actualizaciones en tiempo real, suscríbete a los eventos New Message, Replies, Human Alerted y Chat Concluded con Webhooks en lugar de consultar esta API mediante un temporizador.


Errores de la API de mensajes

Los endpoints de mensajes devuelven el sobre de error estándar:

{
  "success": false,
  "error": "Contact not found"
}
Estado Cuándo ocurre en un endpoint de mensaje
400 Falta un campo obligatorio o un parámetro no es válido (un limit, hours, filter, direction, status incorrecto, una matriz message_ids vacía o de más de 500 elementos, un cursor no válido, una edición body vacía o demasiado larga, un score fuera de -1/0/1, o un emoji con espacios o más de 16 caracteres). También se devuelve cuando un mensaje no se puede editar en absoluto: fue eliminado, su canal no permite ediciones o ha pasado el periodo de edición de ese canal.
404 No se encontró el contacto, la sesión de chat o uno de los IDs de mensaje proporcionados.
409 El canal no aceptaría el cambio en este momento. No se escribió nada: en una edición, edit_reason explica por qué; en una reacción, el canal estaba momentáneamente inaccesible y un reintento podría funcionar.
422 El contacto no puede recibir mensajes salientes (no molestar, privado o un canal no compatible), o una reacción nunca se puede entregar en esta conversación (reaction_reason indica cuál).

Los códigos compartidos que puede devolver cualquier endpoint — 401, 403 (su plan no incluye acceso a la API), 429 (límite de tasa) y 500 — se enumeran con orientación sobre reintentos en Errores y paginación.


Próximos pasos

  • Webhooks: reciba actualizaciones del estado de entrega en lugar de realizar sondeos.
  • Contactos: cree y busque los contactos a los que envía mensajes.
  • Citas: reserve y gestione citas para sus contactos.