Grupos de WhatsApp
Un grupo es un grupo o una comunidad de WhatsApp de la que tu agente es miembro y que elegiste seguir en el dashboard. La API expone los grupos seguidos en solo lectura: el grupo en sí, sus miembros, sus mensajes y sus eventos de pertenencia.
Endpoints
Sección titulada «Endpoints»| Método | Ruta | Scope |
|---|---|---|
| GET | /groups |
groups:read |
| GET | /groups/{id} |
groups:read |
| GET | /groups/{id}/members |
groups:read |
| GET | /groups/{id}/messages |
groups:read |
| GET | /groups/{id}/events |
groups:read |
Qué significa «seguido»
Sección titulada «Qué significa «seguido»»WhatSetter solo guarda lo que pasa en los grupos que sigues desde la página de grupos del dashboard. Un grupo seguido es un grupo con estado active: sus mensajes se registran, sus miembros se sincronizan y el agente puede responder en él según su modo. Los grupos pausados, archivados o abandonados conservan su historial pero dejan de contar.
Un espacio de trabajo puede seguir hasta 500 grupos activos. Seguir más desde el dashboard se rechaza hasta que pauses o archives algunos.
Listar grupos
Sección titulada «Listar grupos»curl "https://app.whatsetter.com/api/v1/groups?status=active&limit=25" \ -H "Authorization: Bearer ws_live_…"const res = await fetch('https://app.whatsetter.com/api/v1/groups?status=active&limit=25', { headers: { Authorization: 'Bearer ws_live_…' },});const { data: groups, pagination } = await res.json();import requests
r = requests.get( "https://app.whatsetter.com/api/v1/groups", params={"status": "active", "limit": 25}, headers={"Authorization": "Bearer ws_live_…"},)groups = r.json()["data"]{ "data": [ { "id": "66f1a2b3c4d5e6f7a8b9c101", "whatsapp_id": "120363012345678901@g.us", "name": "Webinar 24 sept", "description": "Preguntas antes del directo", "participants_count": 148, "messages_count": 912, "status": "active", "ai_enabled": true, "invite_url": "https://chat.whatsapp.com/…", "campaign_id": "acme-community-1-cd34", "created_at": "2026-09-01T09:00:00.000Z" } ], "pagination": { "has_more": false, "next_cursor": "66f1a2b3c4d5e6f7a8b9c101" }}Filtros: status (active, paused, archived, left) y community_id (solo los grupos de una comunidad de WhatsApp, el community.id de un grupo). Los más recientes primero.
Leer un grupo
Sección titulada «Leer un grupo»GET /groups/{id} devuelve los mismos campos más los detalles:
{ "data": { "id": "66f1a2b3c4d5e6f7a8b9c101", "whatsapp_id": "120363012345678901@g.us", "name": "Webinar 24 sept", "description": "Preguntas antes del directo", "participants_count": 148, "messages_count": 912, "status": "active", "ai_enabled": true, "invite_url": "https://chat.whatsapp.com/…", "campaign_id": "acme-community-1-cd34", "created_at": "2026-09-01T09:00:00.000Z", "is_admin": true, "ai_reply_mode": "mentions_only", "intent": "webinar", "community": { "id": "120363098765432101@g.us", "name": "Comunidad Acme", "role": "sub" }, "sync_status": "ready", "synced_at": "2026-09-18T22:00:00.000Z", "picture_url": "https://pps.whatsapp.net/…", "updated_at": "2026-09-18T22:00:00.000Z" }}| Campo | Significado |
|---|---|
is_admin |
Si el número conectado es administrador del grupo. |
ai_reply_mode |
mentions_only o all_messages. |
intent |
community, webinar o broadcast. |
community |
La comunidad de WhatsApp a la que pertenece el grupo, null para un grupo independiente. role: "announce" es el grupo de anuncios de la comunidad, sub un subgrupo normal. |
sync_status |
Estado de la importación del historial: idle, pending, syncing, ready, error. |
picture_url |
Un enlace CDN de WhatsApp de duración limitada a la foto del grupo. Recupéralo cuando lo necesites, no lo guardes. |
Miembros
Sección titulada «Miembros»curl "https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/members?status=active&limit=100" \ -H "Authorization: Bearer ws_live_…"const res = await fetch( 'https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/members?status=active&limit=100', { headers: { Authorization: 'Bearer ws_live_…' } },);const { data: members, pagination } = await res.json();import requests
r = requests.get( "https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/members", params={"status": "active", "limit": 100}, headers={"Authorization": "Bearer ws_live_…"},)members = r.json()["data"]{ "data": [ { "id": "66f1a2b3c4d5e6f7a8b9c111", "phone": "34612345678", "name": "Julien", "role": "member", "status": "active", "joined_at": "2026-09-02T10:15:00.000Z", "left_at": null, "joined_source": "event", "messages_count": 12 } ], "pagination": { "has_more": false, "next_cursor": "66f1a2b3c4d5e6f7a8b9c111" }}role es superadmin, admin o member. status pasa a left cuando la persona abandona el grupo. phone es null cuando WhatsApp solo expuso un identificador anónimo para ese miembro.
Mensajes
Sección titulada «Mensajes»La transcripción del grupo, del más reciente al más antiguo. since y until acotan la ventana, sender conserva los mensajes de un solo miembro (dígitos internacionales), from_agent=true conserva lo que WhatSetter envió por el número conectado, from_agent=false conserva solo los mensajes de los miembros.
curl "https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/messages?since=2026-09-18T00:00:00Z&from_agent=false" \ -H "Authorization: Bearer ws_live_…"const res = await fetch( 'https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/messages?since=2026-09-18T00:00:00Z&from_agent=false', { headers: { Authorization: 'Bearer ws_live_…' } },);const { data: messages, pagination } = await res.json();import requests
r = requests.get( "https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/messages", params={"since": "2026-09-18T00:00:00Z", "from_agent": "false"}, headers={"Authorization": "Bearer ws_live_…"},)messages = r.json()["data"]{ "data": [ { "id": "66f1a2b3c4d5e6f7a8b9c121", "whatsapp_message_id": "false_120363012345678901@g.us_3EB0C8F2A1D4B5E6F7A8", "sender": { "phone": "34612345678", "name": "Julien" }, "from_agent": false, "ai_generated": false, "text": "¿Estará disponible la grabación?", "type": "USER_MESSAGE", "is_mention": true, "has_media": false, "media_type": null, "sent_at": "2026-09-18T18:02:11.000Z" } ], "pagination": { "has_more": false, "next_cursor": "66f1a2b3c4d5e6f7a8b9c121" }}sender es null cuando no se conoce ni teléfono ni nombre. ai_generated es un subconjunto de from_agent: true solo para las respuestas de la IA, false para las respuestas manuales enviadas desde el dashboard. Los archivos se señalan con has_media y media_type (image, video, audio, document…) pero nunca se enlazan.
Eventos
Sección titulada «Eventos»Entradas y salidas, observadas desde los eventos de WhatsApp en directo y las pasadas de sincronización. Filtros: type (join, leave), since, until.
curl "https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/events?type=join&since=2026-09-18T00:00:00Z" \ -H "Authorization: Bearer ws_live_…"const res = await fetch( 'https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/events?type=join&since=2026-09-18T00:00:00Z', { headers: { Authorization: 'Bearer ws_live_…' } },);const { data: events, pagination } = await res.json();import requests
r = requests.get( "https://app.whatsetter.com/api/v1/groups/66f1a2b3c4d5e6f7a8b9c101/events", params={"type": "join", "since": "2026-09-18T00:00:00Z"}, headers={"Authorization": "Bearer ws_live_…"},)events = r.json()["data"]{ "data": [ { "id": "66f1a2b3c4d5e6f7a8b9c131", "type": "join", "phone": "34612345678", "name": "Julien", "occurred_at": "2026-09-18T09:30:00.000Z", "source": "event", "actor_phone": "34698765432" } ], "pagination": { "has_more": false, "next_cursor": "66f1a2b3c4d5e6f7a8b9c131" }}source indica cómo se observó el evento: event (en directo), sync_detected, backfill o webhook_replay. actor_phone es el administrador que añadió o quitó al miembro, cuando WhatsApp lo comunicó.
Errores que encontrarás
Sección titulada «Errores que encontrarás»| HTTP | code |
Cuándo |
|---|---|---|
| 401 | missing_api_key, invalid_api_key |
Clave ausente, desconocida o revocada. |
| 403 | insufficient_scope |
La clave no tiene groups:read. |
| 404 | not_found |
Grupo desconocido, o grupo de otro espacio de trabajo. |
| 422 | validation_error |
status o type desconocido, since o until inválido, sender que no es un teléfono, from_agent distinto de true o false, cursor inválido. |
| 429 | rate_limited |
Demasiadas peticiones este minuto. Respeta Retry-After. |

