Volver al blog
Desarrolladores

Asignar y cerrar un chat de WhatsApp por API: PATCH /conversations en Waspy

PATCH /api/v2/conversations/:id asigna el chat (assignedTo) o lo cierra (status closed). El servidor solo acepta open y closed. pending y resolved dan 400. Marcar leído y el typing no asignan.

· 12 min
Asignar y cerrar un chat de WhatsApp por API: PATCH /conversations en Waspy

Respuesta corta: para asignar o cerrar un chat hacés PATCH https://api.waspytech.com/api/v2/conversations/:id con scope conversations:write. status es open o closed. assignedTo es el UUID de un usuario de esa cuenta, o null para soltarlo. pending y resolved no existen en el servidor: responden 400 VALIDATION_ERROR.

La referencia está en conversations. Donde esa página y el código no coinciden, manda el handler de apps/api/src/routes/v2/conversations.ts. El listado, el leído y el «escribiendo…» están en conversaciones por API. Cómo llegar al id desde un teléfono está en abrir el chat desde el CRM. La clave pública entra en Scale y Enterprise: Planes y la API.

Donde la doc y el servidor no dicen lo mismo

TemaPágina de docsLo que hace el servidor
status del PATCH y del listadoopen, pending, resolved, closedSolo open y closed. Otro valor: 400 VALIDATION_ERROR
Filtro assignedTo en el GETNo está en la página de v2Tampoco en el handler. El query se ignora
NotasNo las documenta en esta páginaNo hay rutas /notes en /api/v2
Default de limit en el listado5020 (máximo 100)
La columna status de la base también es solo open o closed. El schema zod (ConversationUpdateBody y ConversationListQuery) frena el body y el query antes del handler.

Asignar y cerrar

Los dos campos son opcionales. Podés mandar uno solo.

curl -sS -X PATCH "https://api.waspytech.com/api/v2/conversations/CONV_ID" \
  -H "Authorization: Bearer $WASPY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "open", "assignedTo": "USER_UUID" }'

Para cerrar y soltar al mismo tiempo:

curl -sS -X PATCH "https://api.waspytech.com/api/v2/conversations/CONV_ID" \
  -H "Authorization: Bearer $WASPY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "closed", "assignedTo": null }'

El 200 trae data con el chat (id, status, assignedTo, contactId, phoneNumberId, lastMessageAt, serviceWindowExpiresAt, entre otros) y meta.requestId.

RespuestaCuándo
200Se guardó status, assignedTo, o los dos
400 VALIDATION_ERRORstatus no es open ni closed, assignedTo no es un UUID, o ese usuario no está activo en la cuenta
404 CONVERSATION_NOT_FOUNDEl id no es de esta cuenta, o el token no puede ver ni gestionar ese chat
403A la clave le falta conversations:write
assignedTo tiene que ser un usuario de esa cuenta y no dado de baja. No hay un GET /api/v2/users para listarlos: el UUID lo tenés del panel o de tu propio directorio. Un id de otra cuenta responde assignedTo user not found in this tenant.

Cerrar no borra el hilo y no le escribe al cliente. Si esa persona vuelve a mandar un WhatsApp, el mensaje entra igual. Para contestarle, el pedido es POST /api/v2/messages, como está en la API para desarrolladores.

El listado no asigna, y tampoco filtra por responsable

GET /api/v2/conversations?status=open (scope conversations:read) devuelve cada chat con su assignedTo ya puesto. El filtro status acepta open o closed. ?status=resolved es el mismo 400. ?assignedTo= no filtra: el handler no lee ese parámetro.

curl -sS "https://api.waspytech.com/api/v2/conversations?status=open&limit=20" \
  -H "Authorization: Bearer $WASPY_API_KEY"

Cada ítem trae assignedTo (null si nadie lo tiene). Para saber quién lo tiene después del PATCH, leé GET /api/v2/conversations/:id. No esperes un webhook: los eventos públicos son message.received, message.status_changed, conversation.created y contact.created. No hay conversation.updated. El catálogo está en eventos.

Leer y «escribiendo…» no cambian al responsable

PedidoScopeQué haceQué no hace
PATCH /conversations/:idconversations:writestatus y assignedToNo manda un WhatsApp
POST /conversations/:id/readconversations:writeNo leído en cero y doble tildeNo asigna ni cierra
POST /conversations/:id/typingconversations:write«Escribiendo…»No asigna ni cierra
GET /conversations/:id/messagesmessages:readLista los mensajesNo cambia el chat
El detalle de los dos POST está en marcar leído y typing. El Idempotency-Key es de POST /messages, no de este PATCH.

Del webhook al vendedor

message.received ya trae data.conversationId. Si lo tenés, el PATCH va directo a ese id. No hace falta volver a buscar el teléfono.

Si el CRM solo guardó el número (un ticket que nació afuera, sin el UUID), primero resolvés:

curl -sS "https://api.waspytech.com/api/v2/conversations/resolve?phone=5491126032641&channel=whatsapp" \
  -H "Authorization: Bearer $WASPY_API_KEY"

Scope: conversations:read. Si hay chat, data.conversationId es el UUID del PATCH. Si no hay, es null: este GET no crea la conversación. GET /conversations/by-phone/:phone es el atajo de solo WhatsApp: 200 con data: null cuando no hay match, y no trae assignedTo. El contrato de las dos lecturas está en resolver por teléfono.

Orden típico de un CRM:

  1. Llega message.received (o resolvés el teléfono).
  2. PATCH con el UUID del vendedor del ticket y status: "open".
  3. Si tu sistema deja una nota para el equipo, no es un POST de la v2. Es la herramienta MCP add_note (conversationId y body, tope 5000 caracteres en el schema de la herramienta, scope conversations:write). La ve el equipo en el panel y no sale al cliente. Está en conectar MCP.

Qué no existe

  • status: "pending" o "resolved", ni en el PATCH ni en el filtro del listado.
  • POST /api/v2/conversations/:id/notes, ni un GET de notas en la v2.
  • Un webhook público de “se asignó” o “se cerró”.
  • GET /api/v2/users para descubrir el UUID del vendedor.
  • Un PATCH que impida que el cliente vuelva a escribir.

El PATCH no es un mensaje de Meta. No gasta el cupo de 1.000 mensajes de servicio por número y por mes. Lo que cobra Meta es el texto o la plantilla que después mandás. En Argentina, desde el 1 de octubre de 2026, marketing alrededor de ARS 89,56 (US$0,0618) y, pasado ese cupo, el servicio alrededor de ARS 37,68 (US$0,026). La rate card es la fuente. Los planes de Waspy arrancan en US$70 por mes, sin un recargo sobre Meta: Planes. 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.