¡Guau! Crea tu integración de WhatsApp. Empieza gratis. Regístrate ahora
Moderación de entrada al grupo · caso de uso WhatsApp API

Gestiona solicitudes de entrada a grupos de WhatsApp desde tu backend

Clubes de pago y comunidades privadas dejan de perder solicitantes cuando las colas viven en un teléfono. Cuando alguien pide acceso a un grupo solo con aprobación, tu backend puede reaccionar a un webhook groups.put, listar solicitudes pendientes y admitir o rechazar cada una con Whapi.Cloud. Este caso de uso muestra a integradores cómo implementar ese flujo con la WhatsApp API.

Webhook groups.put con action request GET solicitudes pendientes, luego POST o DELETE por id
Portátil con diagrama de integración junto a un teléfono con vista de admin de grupo WhatsApp y una cola corta de solicitudes pendientes.
Caso de uso

Cuándo usar este flujo

El grupo exige aprobación antes de entrar

Usa este flujo cuando el grupo de WhatsApp no es de entrada libre: alguien pulsa el enlace de invitación y crea una solicitud que un admin aprobaría o denegaría en la app.

Las reglas de moderación viven en tu backend

Usa este flujo cuando own_backend decide quién entra (lista de pago, código de referido, allowlist manual) y necesitas una ruta HTTP estable en lugar de copiar toques del teléfono.

Gestionas varios grupos solo con aprobación

Usa este flujo cuando las solicitudes se acumulan en varios grupos o fuera de horario y quieres un patrón único de listar, aprobar y rechazar.

Pantalla de info de grupo WhatsApp en un teléfono con una solicitud resuelta: el miembro aparece en la lista o la solicitud pendiente desaparece tras un rechazo.
Experiencia del cliente

Los solicitantes saben pronto si entran o no

Sin automatización, una solicitud puede quedar pendiente hasta que alguien abre WhatsApp en un teléfono y pulsa aprobar o rechazar.

Tras tus reglas, quien es aprobado puede entrar al grupo por la misma invitación, y una solicitud rechazada ya no bloquea la cola. Los integradores construyen este resultado con la WhatsApp API.

Flujo de trabajo

De solicitud pendiente a aprobar o rechazar

1

Alguien solicita unirse al grupo

Una persona usa el enlace de invitación mientras el grupo está en modo solo con aprobación. Con el webhook de canal groups.put activo, Whapi publica un payload donde groups_participants[].action es request, event.type es groups y event.event es put: la señal para que own_backend liste solicitudes y decida aprobar o rechazar.

2

Listar solicitudes de entrada pendientes

GET /groups/{GroupID}/applications

GET /groups/{GroupID}/applications para el GroupID configurado. Lee cada id de solicitud (y campos relacionados) de la respuesta para el siguiente paso.

3

Aprobar una solicitud

POST /groups/{GroupID}/applications

Si pasan las reglas de own_backend, POST /groups/{GroupID}/applications con el id de solicitud en el cuerpo. OpenAPI indica un id por llamada: itera cuando hay varias solicitudes.

4

Rechazar una solicitud

DELETE /groups/{GroupID}/applications

Si fallan las reglas, DELETE /groups/{GroupID}/applications con la misma forma de id. Una llamada por solicitud rechazada, separada de aprobar.

¿Necesitas la forma completa del webhook? El callback de solicitud de entrada está en la sección de entrega abajo, no en acks de mensajes. Ver el payload groups.put →

Requisitos previos

Antes de ejecutar el flujo

Conecta la cuenta de WhatsApp que administra el grupo a Whapi.Cloud, activa el webhook de canal groups.put y usa el token API de ese canal en los endpoints de solicitudes del grupo. Guarda el GroupID objetivo y tus reglas de moderación en own_backend antes de procesar solicitudes.

Opcional — profundizar en este flujo

Implementación de API

Llamadas de solicitudes de grupo en orden

Tres pasos HTTP reflejan la cadena del catálogo: obtener la cola, admitir solicitantes permitidos, rechazar el resto. Whapi expone listar, aprobar y rechazar en la misma ruta de solicitudes del grupo para cablear moderación sin toques manuales de admin.

Obtén tu token API gratis tras registrarte en whapi.cloud y úsalo en el código en lugar de Your_Token de los ejemplos.

Listar solicitudes de entrada pendientes

Devuelve solicitudes de entrada en espera en el grupo para que own_backend empareje cada solicitud con tu allowlist o estado de pago.

curl --request GET \
     --url https://gate.whapi.cloud/groups/[email protected]/applications \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/groups/[email protected]/applications",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/groups/[email protected]/applications"
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
}
response = requests.get(url, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/groups/[email protected]/applications', {
  method: 'GET',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
  },
});
console.log(await response.text());
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/groups/[email protected]/applications")
  .get()
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .build();
Response response = client.newCall(request).execute();
using RestSharp;
var options = new RestClientOptions("https://gate.whapi.cloud/groups/[email protected]/applications");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", "Bearer Your_Token");
var response = await client.GetAsync(request);
Console.WriteLine("{0}", response.Content);
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://gate.whapi.cloud/groups/[email protected]/applications", nil)
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}

Aprobar una solicitud

Acepta una solicitud pendiente para que esa persona acceda al grupo por la ruta de invitación normal tras una aprobación exitosa.

curl --request POST \
     --url https://gate.whapi.cloud/groups/[email protected]/applications \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token' \
     --header 'content-type: application/json' \
     --data '
{
  "application": "61371989850@..."
}
'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/groups/[email protected]/applications",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"application\": \"61371989850@...\"}",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/groups/[email protected]/applications"
payload = {
    "application": "61371989850@..."
}
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
    "content-type": "application/json",
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/groups/[email protected]/applications', {
  method: 'POST',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
    'content-type': 'application/json',
  },
  body: JSON.stringify({
  "application": "61371989850@..."
}),
});
console.log(await response.text());
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"application\": \"61371989850@...\"}");
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/groups/[email protected]/applications")
  .post(body)
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .addHeader("content-type", "application/json")
  .build();
Response response = client.newCall(request).execute();
using RestSharp;
var options = new RestClientOptions("https://gate.whapi.cloud/groups/[email protected]/applications");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", "Bearer Your_Token");
request.AddJsonBody(new { application = "61371989850@..." });
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"application": "61371989850@..."}`)
	req, _ := http.NewRequest("POST", "https://gate.whapi.cloud/groups/[email protected]/applications", bytes.NewReader(body))
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	req.Header.Set("content-type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}

Rechazar una solicitud

Declina una solicitud pendiente para que salga de la cola sin admitir a esa persona.

curl --request DELETE \
     --url https://gate.whapi.cloud/groups/[email protected]/applications \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token' \
     --header 'content-type: application/json' \
     --data '
{
  "application": "61371989850@..."
}
'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/groups/[email protected]/applications",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_POSTFIELDS => "{\"application\": \"61371989850@...\"}",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/groups/[email protected]/applications"
payload = {
    "application": "61371989850@..."
}
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
    "content-type": "application/json",
}
response = requests.delete(url, json=payload, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/groups/[email protected]/applications', {
  method: 'DELETE',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
    'content-type': 'application/json',
  },
  body: JSON.stringify({
  "application": "61371989850@..."
}),
});
console.log(await response.text());
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"application\": \"61371989850@...\"}");
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/groups/[email protected]/applications")
  .delete(body)
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .addHeader("content-type", "application/json")
  .build();
Response response = client.newCall(request).execute();
using RestSharp;
var options = new RestClientOptions("https://gate.whapi.cloud/groups/[email protected]/applications");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", "Bearer Your_Token");
request.AddJsonBody(new { application = "61371989850@..." });
var response = await client.DeleteAsync(request);
Console.WriteLine("{0}", response.Content);
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"application": "61371989850@..."}`)
	req, _ := http.NewRequest("DELETE", "https://gate.whapi.cloud/groups/[email protected]/applications", bytes.NewReader(body))
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	req.Header.Set("content-type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}
Evento entrante

Solicitudes de entrada en groups.put

Usa el ajuste de webhook de canal para groups.put para recibir eventos de solicitud de entrada. Whapi envía un JSON con groups_participants (cada ítem tiene group_id, participants y action), más event.type groups, event.event put y channel_id. Cuando action es request, alguien pidió unirse: llama a getGroupApplicationsList para el group_id correspondiente y luego aprueba o rechaza. Esto es distinto del seguimiento de entrega statuses.post de mensajes.

  • Forma de ejemplo confirmada por el operador: groups_participants con action request, event groups/put y channel_id en el mismo payload que Whapi publica en tu URL.

  • Mapea groups_participants[].group_id al GroupID en GET /groups/{GroupID}/applications antes de aprobar o rechazar.

  • Los ids de participantes en el webhook identifican quién pidió acceso; combínalos con la respuesta de listado al rellenar ApplicationRequest.

  • Hacer polling de getGroupApplicationsList por horario sigue funcionando si no usas el webhook; solo cambia el disparador.

Qué leer sobre entrega y webhooks

Contacta a nuestro soporte si algo salió mal
Cuando algo falla

Gestiona fallos en cada paso

Si falla el listado de solicitudes o las llamadas de aprobar y rechazar, las solicitudes siguen pendientes: reintenta, omite ids obsoletos o alerta a ops en lugar de asumir que alguien entró.

Cuando las solicitudes nunca se aclaran

Un GroupID incorrecto, un grupo inexistente o respuestas 400 repetidas dejan solicitantes en pendiente. Corrige el parámetro de ruta, confirma que el canal aún administra ese grupo y reintenta aprobar o rechazar solo el id de solicitud actual; no asumas que un id anterior sigue válido. Si los errores persisten tras un reintento, contacta al soporte de Whapi con el GroupID y el cuerpo fallido.

Contacta a nuestro soporte si algo salió mal

Diagnóstico por paso de API

Estado Qué significa Qué hacer
400 Wrong request parameters Corrige parámetros de consulta como count u offset según OpenAPI antes de reintentar el listado.
404 Specified group not found Confirma que GroupID coincide con un grupo que este canal puede gestionar; actualiza la configuración de own_backend.
Estado Qué significa Qué hacer
400 Wrong request parameters Envía un id de solicitud válido en el cuerpo; aprueba un id por llamada como describe OpenAPI.
404 Specified group not found Vuelve a listar solicitudes: el id puede estar ya aprobado, rechazado o retirado.
Estado Qué significa Qué hacer
400 Wrong request parameters Iguala la forma del cuerpo DELETE a OpenAPI y pasa el id de solicitud que quieres rechazar.
404 Specified group not found Vuelve a obtener la cola; la solicitud puede ya no existir en el servidor.
Preguntas frecuentes

Solicitudes de entrada e ids de solicitud

Activa groups.put en el webhook del canal. Whapi publica event.type groups y event.event put con groups_participants donde action es request, group_id es el JID del grupo y participants lista el id del solicitante; luego tu worker llama a getGroupApplicationsList y approveGroupApplicationsList o rejectGroupApplicationsList.
OpenAPI describe un id de solicitud por llamada a approveGroupApplicationsList y uno por rejectGroupApplicationsList. Itera en own_backend cuando hay varias personas en espera.
Usa el identificador de solicitud de la respuesta de getGroupApplicationsList (el campo application que espera ApplicationRequest). Si una llamada devuelve 404, lista de nuevo antes de reintentar: la cola puede haber cambiado.
Trátalo como tu failure_mode del catálogo: confirma que el grupo sigue siendo solo con aprobación, que el enlace de invitación es válido y que no rechazaste el mismo id en otro sitio. Alerta a ops en lugar de dejar intentos de aprobar duplicados para siempre.
Funciones compatibles de WhatsApp

Todo lo que necesitas para crear automatizaciones en WhatsApp

Whapi.Cloud te da acceso a un conjunto completo de funciones de WhatsApp — mensajería, multimedia, grupos, canales, webhooks y más. Crea bots, automatizaciones e integraciones sin limitaciones de funciones.

Elegido por desarrolladores

Confiado por más de 3.300 desarrolladores y equipos SaaS

Desarrolladores de todo el mundo confían en Whapi.Cloud para crear automatizaciones, bots, integraciones con CRM, herramientas de mensajería masiva y flujos avanzados de WhatsApp. Nuestra infraestructura procesa millones de solicitudes API con alta estabilidad, y este número crece cada mes.

Icono de característica

5,5K+

canales API activos

Icono de característica

21M+

solicitudes API al mes

“Todo es simple, intuitivo y fácil de usar. La documentación es clara y toda la información está justo donde la necesito. Excelente trabajo.”

Roberto K. / Desarrollador Web

“Conectamos WhatsApp a nuestros flujos en n8n en solo unos minutos. Sin código, sin complicaciones — todo funcionó a la primera.”

Martin P. / Desarrollador

“Whapi.Cloud se convirtió en una parte clave de nuestra comunicación con clientes. Automatizamos actualizaciones de productos, notificaciones de pedidos y mensajes de soporte — sin plantillas ni aprobaciones de Meta.”

Oscar T. / CTO

Burbuja decorativa