Volver al blog
Desarrolladores

Resolver una conversación de WhatsApp por teléfono con la API de Waspy

GET /api/v2/conversations/resolve acepta un celular argentino en +549 o en 5411. No trae serviceWindowExpiresAt: esa fecha está en GET /conversations/:id. by-phone devuelve solo el chat más reciente.

· 12 min
Resolver una conversación de WhatsApp por teléfono con la API de Waspy

Respuesta corta: el ERP tiene +54911… y no tiene el UUID del chat. GET https://api.waspytech.com/api/v2/conversations/resolve?phone= lo busca dentro de tu cuenta. El scope es conversations:read. Esa respuesta no trae serviceWindowExpiresAt. Para saber si la ventana de 24 horas sigue abierta, el paso siguiente es GET /api/v2/conversations/:id.

La referencia está en conversations. El deep link del panel, el PATCH (open / closed) y el caso del 15 en el medio están en abrir el chat desde el CRM. Esta nota es el teléfono argentino y la ventana. El listado de la bandeja está en conversaciones por API.

Qué pedido, según lo que tenés

TenésPedidoQué vuelve
Teléfono, y puede haber Instagram o más de una líneaGET /conversations/resolveconversationId, match, alternatives, phoneHasWhatsApp
Solo el celular, un chat de WhatsAppGET /conversations/by-phone/:phoneconversationId, contactName, contactPhone, o data: null
El UUIDGET /conversations/:idEl chat, incluido serviceWindowExpiresAt
Los tres piden conversations:read. Ninguno crea el hilo. La API pública está en Scale y Enterprise: Planes y la API.

El +549

Un celular de Argentina, para WhatsApp, va en E.164 con el 9 móvil: +549 + código de área + abonado, sin el 0 y sin el 15. El ejemplo de la documentación es +5491126032641.

resolve tolera espacios, guiones y el +. Arma la familia 54 / 549:

MandásTambién busca
+5491140796637 o 5491140796637La variante sin el 9 (541140796637), con + y sin +
+541126032641 (sin el 9)La variante con 9 (5491126032641)
Un local de 8 dígitos o más, sin 5454 + dígitos y 549 + dígitos
Además, si el número guardado no coincide exacto, resolve puede matchear los últimos 8 dígitos. Eso atrapa un alta vieja. También puede juntar dos abonados distintos que terminan igual: mirá match.contactPhone antes de escribirle a esa persona.
curl -sS --get "https://api.waspytech.com/api/v2/conversations/resolve" \
  --data-urlencode "phone=+5491140796637" \
  --data-urlencode "channel=whatsapp" \
  --data-urlencode "line=28392709" \
  -H "Authorization: Bearer $WASPY_API_KEY"

line y channel no filtran. Si la persona tiene un chat de WhatsApp y otro de Instagram, ordenan cuál vuelve en conversationId. El resto queda en alternatives. line acepta los últimos dígitos de la línea de la tienda, el id de Meta o el UUID del número en Waspy. Menos de 6 dígitos no se usa como línea.

La respuesta 200:

{
  "data": {
    "conversationId": "64ed37aa-5506-44a6-b8d6-f25a2936255d",
    "match": {
      "conversationId": "64ed37aa-5506-44a6-b8d6-f25a2936255d",
      "channel": "whatsapp",
      "contactName": "María",
      "contactPhone": "+5491140796637",
      "contactUsername": null,
      "contactEmail": null,
      "lastMessageAt": "2026-04-14T14:32:00.000Z",
      "lineLabel": "Ventas"
    },
    "alternatives": [],
    "phoneHasWhatsApp": true
  },
  "meta": { "requestId": "..." }
}

El ejemplo de la página de docs no muestra phoneHasWhatsApp. El schema de la ruta lo exige. Es true solo si algún chat devuelto es de WhatsApp y el teléfono del contacto es una variante 54/549 del parámetro. Un match por Instagram, por email o por los últimos 8 dígitos de otro número no alcanza.

Si no hay ninguno, conversationId y match son null y alternatives es []. Sigue siendo 200. En el CRM mostrá “todavía no hay chat”. El primer mensaje, si corresponde, es un POST /api/v2/messages con plantilla, como en enviar una plantilla.

Sin phone, sin ig y sin email, es 400 BAD_REQUEST. channel distinto de whatsapp, instagram o email también. Una clave con scopes y sin conversations:read es 403 FORBIDDEN.

by-phone es más chico. El + en el path va como %2B. No busca Instagram, no trae alternatives y, si no hay chat, data es null con 200.

curl -sS "https://api.waspytech.com/api/v2/conversations/by-phone/%2B5491140796637" \
  -H "Authorization: Bearer $WASPY_API_KEY"

El 15 viejo, metido después del código de área (11 15 …), no se recorta en esa ruta. Pasá el +549 canónico. El detalle del 15 está en la nota del CRM.

La ventana: el segundo GET

serviceWindowExpiresAt no está en resolve ni en by-phone. Está en el detalle:

curl -sS "https://api.waspytech.com/api/v2/conversations/CONV_ID" \
  -H "Authorization: Bearer $WASPY_API_KEY"

El 200 incluye serviceWindowExpiresAt (fecha ISO o null), lastMessageAt, status, phoneNumberId y contact (name, phoneNumber, email). El mismo campo viene en cada ítem de GET /api/v2/conversations.

serviceWindowExpiresAtQué podés mandar
Una fecha en el futuroTexto, foto, audio o documento: es mensaje de servicio
Una fecha ya pasada, o nullNo cuentes con texto libre. El POST de texto responde 403 SERVICE_WINDOW_EXPIRED
La ventana la abre el mensaje del cliente y dura 24 horas. La regla está en la ventana de 24 horas. Desde el 1 de octubre de 2026 cada número tiene 1.000 mensajes de servicio gratis por mes. Desde el 1.001, en Argentina, alrededor de ARS 37,68 (~US$0,026). Una plantilla de utilidad se cobra desde el primer envío, también con la ventana abierta. La rate card es la fuente.

Este GET no manda nada y no gasta ese cupo. Lo que gasta es el mensaje que después encolás.

Lo que el teléfono no alcanza a decir

  • No uses phoneHasWhatsApp para “ver si el número existe en WhatsApp”. Dice si en tu cuenta ya hay un chat.
  • Una API key limitada a ciertas líneas solo ve esas líneas. Un token de usuario respeta la visibilidad del inbox: si esa persona no puede abrir el chat, no aparece.
  • La página de scopes lista GET /conversations y GET /conversations/:id para conversations:read. No nombra resolve ni by-phone. Las dos rutas igual exigen ese scope.
  • Leer y resolver no es un mensaje entregado. Meta no lo cobra.

Diez días sin tarjeta, en el registro.

Tu equipo atendiendo por WhatsApp en minutos

CRM facil pero potente. En 10 minutos tenes a tu equipo trabajando — no necesitas hablar con nadie.