WhatsApp APIAPI

WhatsApp: enviar mensajes por la API

Envía texto, imagen, video, audio, documento, sticker, ubicación, botones y lista en WhatsApp por la API de XBASE, en la ventana de 24 horas.

Actualizado el

POST /whatsapp/messages envía un mensaje libre a un contacto, dentro de la ventana de 24 horas. Fuera de ella, envía una plantilla.

Enviar un mensaje

POST https://api.xbase.app/api/external/v1/whatsapp/messages
CampoTipoObligatorioRegla
numberIdtextosíNúmero que envía (listar los números)
totextosíTeléfono del contacto con el código de país, de 8 a 15 dígitos. Se quitan +, espacios, guiones y paréntesis
typetextosítext, image, video, audio, document, sticker, location, buttons, list o flow
objeto del tipoobjetosíUn campo con el mismo nombre del type, como "text": { "body": "…" }. Mira cada tipo abajo
curl -X POST https://api.xbase.app/api/external/v1/whatsapp/messages \
  -H "Authorization: Bearer $XBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "numberId": "6d1f3c2a-4b5e-4f60-9a7b-8c9d0e1f2a3b",
    "to": "5491155550100",
    "type": "text",
    "text": { "body": "Tu pedido salió para entrega y llega hoy antes de las 18 h." }
  }'

La respuesta está en Respuesta. Un campo de más en el cuerpo se rechaza con 400.

Texto

{
  "numberId": "6d1f3c2a-4b5e-4f60-9a7b-8c9d0e1f2a3b",
  "to": "5491155550100",
  "type": "text",
  "text": { "body": "¡Hola, María! ¿En qué te puedo ayudar?" }
}

text.body tiene de 1 a 4096 caracteres. Los enlaces del texto aparecen clicables en WhatsApp.

Multimedia

Imagen, video, audio, documento y sticker van por URL https pública: Meta descarga el archivo de ella. Una URL http, con usuario y contraseña, o de una dirección interna o de red privada responde 400.

{
  "numberId": "6d1f3c2a-4b5e-4f60-9a7b-8c9d0e1f2a3b",
  "to": "5491155550100",
  "type": "image",
  "image": {
    "link": "https://cdn.miempresa.com/catalogo/zapatillas-azules.jpg",
    "caption": "Zapatillas azules, talles 38 a 44"
  }
}
typeObjetoReglas de Meta
imagelink, captionJPEG o PNG, hasta 5 MB
videolink, captionMP4 o 3GP, hasta 16 MB
audiolink, voiceAAC, MP3, MP4 u OGG, hasta 16 MB. "voice": true lo muestra como nota de voz, y el archivo tiene que ser OGG con el códec Opus
documentlink, filename, captionCualquier archivo, hasta 100 MB. filename (hasta 240 caracteres) es el nombre que ve el contacto
stickerlinkWebP de 512 × 512 píxeles

caption es opcional, con hasta 1024 caracteres.

Ubicación

{
  "numberId": "6d1f3c2a-4b5e-4f60-9a7b-8c9d0e1f2a3b",
  "to": "5491155550100",
  "type": "location",
  "location": {
    "latitude": -34.6037,
    "longitude": -58.3816,
    "name": "Tienda Centro",
    "address": "Av. Corrientes 1000, Buenos Aires"
  }
}
CampoRegla
location.latitudeDe −90 a 90
location.longitudeDe −180 a 180
location.name · location.addressOpcionales, hasta 1000 caracteres

Botones

{
  "numberId": "6d1f3c2a-4b5e-4f60-9a7b-8c9d0e1f2a3b",
  "to": "5491155550100",
  "type": "buttons",
  "buttons": {
    "header": "Pedido 12345",
    "body": "¿Confirmamos la entrega para mañana?",
    "footer": "Toca una opción",
    "buttons": [
      { "id": "confirmar", "title": "Confirmar" },
      { "id": "reprogramar", "title": "Reprogramar" }
    ]
  }
}
CampoRegla
buttons.bodyTexto del mensaje, hasta 1024 caracteres
buttons.header · buttons.footerOpcionales, hasta 60 caracteres
buttons.buttonsDe 1 a 3 botones. id (hasta 256 caracteres, sin repetir) vuelve cuando el contacto toca; title tiene hasta 20 caracteres

Lista

{
  "numberId": "6d1f3c2a-4b5e-4f60-9a7b-8c9d0e1f2a3b",
  "to": "5491155550100",
  "type": "list",
  "list": {
    "body": "Elige el horario de entrega.",
    "button": "Ver horarios",
    "rows": [
      { "id": "manana", "title": "Mañana", "description": "De 8 a 12 h" },
      { "id": "tarde", "title": "Tarde", "description": "De 13 a 18 h" }
    ]
  }
}
CampoRegla
list.bodyTexto del mensaje, hasta 1024 caracteres
list.buttonTexto del botón que abre la lista, hasta 20 caracteres
list.rowsDe 1 a 10 filas. id (hasta 200 caracteres, sin repetir) vuelve cuando el contacto elige; title hasta 24 caracteres; description opcional, hasta 72
list.header · list.footerOpcionales, hasta 60 caracteres

El botón tocado o la fila elegida llega como whatsapp.message.received en los webhooks del workspace, con el id que enviaste.

Flow

Para abrir un WhatsApp Flow (un formulario dentro de WhatsApp), usa "type": "flow". Los campos y un ejemplo están en Flows.

Respuesta

Respuesta 200:

{
  "status": "accepted",
  "messageId": "wamid.HBgNNTUyMTk5OTk5MDAwMBUCABEYEjQ1QzM1RkQ2RDhGNjZBMDQ3MwA=",
  "threadId": "c1d7f0b2-5a4e-4f3d-9c2b-1a0e9d8c7b6a",
  "dialogId": "5a0e4c31-7b2d-4e8f-a1c3-9d6b5e4f3a21"
}
CampoDescripción
statusaccepted: Meta aceptó el envío. La entrega y la lectura llegan después, en los eventos de webhook
messageIdId del mensaje en Meta (wamid.…). Va en la reacción y aparece en los eventos
threadIdConversación del contacto en XBASE
dialogIdMensaje en la conversación

Errores

EstadocodeCuándo
400(sin code)Campo inválido: teléfono, type desconocido, texto vacío o demasiado largo, URL http o interna, campo de más. El message dice cuál
404NUMBER_NOT_FOUNDEl número no existe en este workspace
422NUMBER_DISCONNECTEDEl número está desconectado
422WINDOW_CLOSEDFuera de la ventana de 24 horas. Envía una plantilla
422SEND_REJECTEDXBASE rechazó antes de enviar. El message dice el motivo
422META_ERRORMeta rechazó, por ejemplo, un archivo que no pudo descargar. details.metaCode trae el código de Meta

En WINDOW_CLOSED, details.reason dice por qué la ventana está cerrada: no_contact_message (el contacto nunca escribió a este número), window_expired (su último mensaje tiene más de 24 horas) o awaiting_template_reply (el último envío fue una plantilla y el contacto todavía no respondió). details.lastContactMessageAt trae la fecha del último mensaje del contacto.

{
  "statusCode": 422,
  "message": "Janela de atendimento de 24h expirada. Envie apenas templates aprovados pelo WhatsApp.",
  "code": "WINDOW_CLOSED",
  "details": { "reason": "window_expired", "lastContactMessageAt": "2026-11-03T14:02:11.000Z" }
}

Preguntas frecuentes

Ver también

En esta página