Supresiones
Una supresión es una dirección que tu espacio de trabajo no contactará, registrada con un alcance. Bird bloquea un envío a una dirección suprimida antes de que llegue a WhatsApp.
Abre la página Suppressions para gestionar la lista, o usa la API a continuación. Los registros declarados por el destinatario se encuentran en la pestaña Preferences de la misma página y siguen reglas diferentes.

Suprimir una cuenta de negocio
Desde la pestaña Suppressions, crea una supresión para un número de teléfono y elige la cuenta de negocio a la que se aplica. Bird bloquea los mensajes de esa cuenta y tus demás cuentas pueden seguir contactando el número. La columna Business account de la lista indica la cuenta a la que está limitada la supresión, o muestra All accounts cuando cubre todo tu espacio de trabajo.
POST /v1/whatsapp/suppressions registra lo mismo desde código. waba es la cuenta a la que se limita; omítelo para bloquear la dirección en todo tu espacio de trabajo, incluidas las cuentas que conectes después:
// Omit waba to block the address for the whole workspace, whichever account
// sends. With it, your other accounts keep reaching them, and the same
// address for two accounts is two records.
const suppression = await bird.whatsapp.suppressions.add({
address: "+15550001234",
waba: "102290129340398",
});
console.log(suppression.id, suppression.applies_to);# Omit waba to block the address for the whole workspace, whichever account
# sends. With it, your other accounts keep reaching them, and the same
# address for two accounts is two records.
suppression = client.whatsapp.suppressions.add(
address="+15550001234",
waba="102290129340398",
)
print(suppression.id, suppression.applies_to)suppression, err := client.Whatsapp.Suppressions.Add(context.Background(), bird.WhatsappSuppressionsAddParams{
Address: "+15550001234",
// Omit Waba to block the address for the whole workspace, whichever account
// sends. With it, your other accounts keep reaching them, and the same
// address for two accounts is two records.
Waba: &waba,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(suppression.Id, suppression.AppliesTo)// Omit setWaba to block the address for the whole workspace, whichever account
// sends. With it, your other accounts keep reaching them, and the same address
// for two accounts is two records.
$suppression = $bird->whatsapp->suppressions->add(
(new WhatsAppSuppressionCreate())
->setAddress('+15550001234')
->setWaba('102290129340398'),
);
echo $suppression->getId(), ' ', $suppression->getAppliesTo();bird whatsapp suppressions add --address +5511977670804curl -X POST https://us1.platform.bird.com/v1/whatsapp/suppressions \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"address":"+15550001234","waba":"102290129340398"}'
Un alcance, un registro
Una supresión lleva un solo alcance, así que la misma dirección bloqueada para dos cuentas son dos registros en vez de uno. Para cubrir todo el espacio de trabajo, haz una llamada sin waba.
Añadir una dirección que ya está suprimida para ese alcance devuelve 200 con el registro existente en lugar de crear un segundo. Un registro nuevo devuelve 201.
Una supresión se identifica por la dirección que registras. Un destinatario al que contactas por número de teléfono y el mismo destinatario al que contactas por un ID de usuario con alcance de negocio son dos claves distintas, así que suprimir una no suprime la otra. Registra ambas si te diriges a la misma persona de las dos formas.
Consultar tu lista de supresiones
GET /v1/whatsapp/suppressions devuelve las supresiones vigentes, de la más reciente a la más antigua, como una página de cursor. address filtra por prefijo e ignora mayúsculas: un valor parcial coincide con todas las direcciones que lo contengan, y un valor completo coincide solo con esa dirección. reason limita a una categoría, como manual para las que añadiste tú:
// address is a prefix, so a partial value matches every address under it.
const suppressions = await bird.whatsapp.suppressions.list({ address: "+1555" });
for (const suppression of suppressions.data ?? []) {
console.log(suppression.address, suppression.waba ?? "every account");
}# address is a prefix, so a partial value matches every address under it.
suppressions = client.whatsapp.suppressions.list(address="+1555")
for suppression in suppressions.data or []:
print(suppression.address, suppression.waba or "every account")for suppression, err := range client.Whatsapp.Suppressions.List(context.Background(), bird.WhatsappSuppressionsListParams{
Address: "+1555", // a prefix, so a partial value matches every address under it
}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(suppression.Address, suppression.Reason)
}// address is a prefix, so a partial value matches every address under it.
foreach ($bird->whatsapp->suppressions->list(['address' => '+1555']) as $suppression) {
echo $suppression->getAddress(), ' ', $suppression->getWaba() ?? 'every account', PHP_EOL;
}bird whatsapp suppressions listcurl "https://us1.platform.bird.com/v1/whatsapp/suppressions?address=%2B1555" \
-H "Authorization: Bearer $BIRD_API_KEY"La lista muestra lo que está vigente; los registros finalizados quedan fuera. Que una dirección no aparezca no demuestra que el espacio de trabajo nunca la suprimió: el registro puede haber finalizado. Consúltalo por ID para confirmarlo.
Consultar un registro
GET /v1/whatsapp/suppressions/{suppression_id} resuelve tanto un registro finalizado como uno vigente, e informa cuándo finalizó y qué lo finalizó:
// Resolves a record that has already ended, which the list leaves out.
const suppression = await bird.whatsapp.suppressions.get("was_01krdgeqcxet5s7t44vh8rt9mg");
console.log(suppression.reason, suppression.ended_at ?? "still in force");# Resolves a record that has already ended, which the list leaves out.
suppression = client.whatsapp.suppressions.get("was_01krdgeqcxet5s7t44vh8rt9mg")
print(suppression.reason, suppression.ended_at or "still in force")suppression, err := client.Whatsapp.Suppressions.Get(context.Background(), "was_01krdgeqcxet5s7t44vh8rt9mg")
if err != nil {
log.Fatal(err)
}
fmt.Println(suppression.Reason, suppression.EndedAt)// Resolves a record that has already ended, which the list leaves out.
$suppression = $bird->whatsapp->suppressions->get('was_01krdgeqcxet5s7t44vh8rt9mg');
echo $suppression->getReason(), ' ', $suppression->getEndedAt()?->format(DATE_ATOM) ?? 'still in force';bird whatsapp suppressions get <suppression-id>curl https://us1.platform.bird.com/v1/whatsapp/suppressions/was_01krdgeqcxet5s7t44vh8rt9mg \
-H "Authorization: Bearer $BIRD_API_KEY"Finalizar una supresión
La acción Delete en una fila de supresión finaliza la supresión en lugar de eliminarla. El bloqueo se detiene. El registro sigue siendo consultable y muestra cuándo finalizó y quién lo finalizó. DELETE /v1/whatsapp/suppressions/{suppression_id} hace lo mismo y devuelve 204:
// Only a manual suppression can be ended; a recipient's own opt-out is
// theirs to reverse. The record is kept and still reads back by id.
await bird.whatsapp.suppressions.remove("was_01krdgeqcxet5s7t44vh8rt9mg");# Only a manual suppression can be ended; a recipient's own opt-out is
# theirs to reverse. The record is kept and still reads back by id.
client.whatsapp.suppressions.remove("was_01krdgeqcxet5s7t44vh8rt9mg")if err := client.Whatsapp.Suppressions.Remove(context.Background(), "was_01krdgeqcxet5s7t44vh8rt9mg"); err != nil {
log.Fatal(err)
}// Only a manual suppression can be ended; a recipient's own opt-out is theirs
// to reverse. The record is kept and still reads back by id.
$bird->whatsapp->suppressions->remove('was_01krdgeqcxet5s7t44vh8rt9mg');bird whatsapp suppressions remove <suppression-id> --yescurl -X DELETE https://us1.platform.bird.com/v1/whatsapp/suppressions/was_01krdgeqcxet5s7t44vh8rt9mg \
-H "Authorization: Bearer $BIRD_API_KEY"Una supresión que añadiste tú lleva la razón manual y puede finalizarse. La exclusión voluntaria de un destinatario solo él puede revertirla, y el intento devuelve 422. Llamar de nuevo a una supresión ya finalizada tiene éxito sin cambiar nada, y un ID que el espacio de trabajo no posee devuelve 404.
Finalizar una supresión requiere su ID, así que búscala primero en la lista.
Detectar nuevas supresiones
whatsapp_suppression.created se dispara cuando se registra una supresión, para que tu sistema detecte nuevos bloqueos sin hacer polling. Su payload incluye:
- suppression_id, el identificador del registro.
- address, el número suprimido en formato E.164.
- waba, la cuenta a la que se limita el bloqueo, o null cuando cubre todo el espacio de trabajo.
- reason y workspace_id.
No se dispara ningún evento cuando una supresión finaliza, así que vuelve a consultar la lista antes de confiar en una copia que tengas. Consulta eventos de WhatsApp para ver el payload completo.
Próximos pasos
- Preferencias: los registros que declaran los destinatarios y cuáles puedes revertir.
- Eventos de WhatsApp: el payload de whatsapp.rejected que genera un envío bloqueado.
- Enviar mensajes WhatsApp: la API de envío y su modelo de entrega asíncrono.
Recursos relacionados
Continúa con la documentación, guías y ejemplos sobre este tema. Los recursos están en inglés.
Ver la guíaConnecting WhatsApp to Bird: from buying a number to a live channelComprender el conceptoWhat is the 24-hour customer service window on WhatsApp?Usar la herramientaWhatsApp message builderExplorar la funcionalidadWhatsApp
Prueba el ejercicio y obtén un resumen de implementación