Supressões
Seu espaço de trabalho possui uma lista de supressão: um conjunto de endereços de e-mail para os quais não fazemos entregas. Hard bounces e reclamações de spam entram nela automaticamente, e você também pode adicionar endereços manualmente. Enviar repetidamente para endereços que retornam bounce ou reportam spam pode fazer seu domínio ser bloqueado por provedores de caixa de entrada, por isso interrompemos esses envios antes que saiam da plataforma.
Um novo cancelamento de inscrição não adiciona um registro de supressão. Ele registra a preferência declarada pelo próprio destinatário, e não um fato de entregabilidade, por isso fica na aba Preferences em vez disso. Consulte Links de cancelamento de inscrição para saber como isso funciona.
Gerencie a lista em Email > Suppressions, pela API de supressões ou com bird email suppressions.

Os três motivos e o que eles bloqueiam
Cada registro tem um reason indicando por que o endereço está na lista e uma política applies_to que controla quais categorias ele bloqueia:
| Motivo | applies_to | Categoria marketing | Categoria transacional |
|---|---|---|---|
| hard_bounce | all | Bloqueada | Bloqueada |
| complaint | non_transactional | Bloqueada | Permitida |
| manual | all | Bloqueada | Bloqueada |
A divisão decorre do significado de cada motivo:
- hard_bounce: o endereço não existe. Enviar é inútil em qualquer categoria, então bloqueia tudo.
- complaint: uma declaração sobre e-mails indesejados. Alguém que reportou sua newsletter como spam ainda pode precisar de uma redefinição de senha ou de uma confirmação de pedido, então bloqueia apenas envios não transacionais.
- manual: uma decisão deliberada sua ou da sua equipe. Não a questionamos, então uma supressão manual bloqueia todas as categorias, incluindo transacional.
Um endereço pode ter um registro por motivo, então um hard bounce e uma reclamação anterior ficam lado a lado como registros separados, e a entrega permanece bloqueada enquanto qualquer registro bloqueante existir. Adotamos a postura mais restritiva para tudo que não reconhecemos: se um registro retornar com um applies_to que sua integração nunca viu, trate-o como bloqueando todas as categorias, que é como nós mesmos o tratamos.
Note: reason: unsubscribe is deprecated on the suppressions API. New unsubscribes record a preference instead of a suppression. The deprecated ?reason=unsubscribe filter still returns legacy suppression records with origin: unsubscribe_link or origin: unsubscribe_event until those records are removed.
Como endereços são adicionados automaticamente
Adicionamos supressões em resposta a sinais do destinatário, então um bounce ou reclamação não exige nenhuma ação sua:
| Gatilho | Supressão resultante |
|---|---|
| Hard bounce (email.bounced) | reason: hard_bounce, origin: bounce_event, applies_to: all |
| Hard bounce fora de banda (email.out_of_band_bounce) | reason: hard_bounce, origin: bounce_event, applies_to: all |
| Reclamação de spam (email.complained) | reason: complaint, origin: complaint_event, applies_to: non_transactional |
Um cancelamento de inscrição, seja pelo link no corpo do e-mail ou pelo botão de um clique, não aparece aqui: ele registra uma preferência na aba Preferences em vez de adicionar uma linha a esta lista.
Apenas bounces da classe hard geram supressão, e a tabela de classificação mostra quais valores de bounce_class contam como hard. Dois resultados que parecem falhas mantêm o endereço enviável:
- Soft bounces e adiamentos (email.deferred, ou email.bounced com bounce_type: "soft"): falhas temporárias como caixa de entrada cheia. Tentamos novamente.
- Rejeições do lado do envio: falhas de geração e rejeições de política são problemas com o envio, não com o endereço. Elas produzem eventos email.rejected e nenhuma supressão.
Sinais repetidos para um endereço que já está suprimido pelo mesmo motivo mantêm o registro original inalterado, incluindo seu created_at. O registro mantém source_email_id e source_recipient_id, que vinculam uma supressão automática à mensagem e ao destinatário exatos que a causaram. Esses dois campos respondem à pergunta de suporte "why did this person stop getting our email" e são null em adições manuais.
Toda adição, automática ou manual, dispara um evento email_suppression.created para seu endpoint de webhook com o suppression_id, o email suprimido, o reason e o workspace_id, para que seu próprio sistema possa espelhar a lista sem polling:
Exemplo de código
{
"type": "email_suppression.created",
"timestamp": "2026-07-23T14:52:03.192524705Z",
"data": {
"email": "user@example.com",
"reason": "manual",
"suppression_id": "sup_01ky7qckqrf06r38g49b9kxdbc",
"workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
}
}Gerenciando supressões pela API
A API adiciona, lista, consulta e exclui registros individuais. Os endereços são convertidos para minúsculas antes do armazenamento e da consulta e nunca aparecem em um caminho de URL, porque caminhos vão para logs de acesso e um endereço de e-mail é dado pessoal. Para encontrar o registro de um endereço, filtre a lista com ?email=.
Cada SDK expõe essas operações como métodos tipados no recurso suppressions.
Adicionar um endereço
const suppression = await bird.suppressions.add({ email: "user@example.com" });
console.log(suppression.id);suppression = client.suppressions.add(email="user@example.com")
print(suppression.id)suppression, err := client.Suppressions.Add(context.Background(), bird.SuppressionsAddParams{
Email: "user@example.com",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(suppression.Id)$suppression = $bird->suppressions->add(
(new SuppressionCreate())->setEmail('user@example.com'),
);
echo $suppression->getId();bird email suppressions add --email user@example.comcurl -X POST https://us1.platform.bird.com/v1/email/suppressions \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "email": "user@example.com" }'Adições manuais recebem reason: manual e applies_to: all, então bloqueiam todas as categorias. A chamada é idempotente: uma nova supressão retorna 201 Created, e um endereço já suprimido manualmente retorna 200 OK com o registro existente em vez de um conflito. Em ambos os casos, o corpo é o objeto de supressão:
Exemplo de código
{
"applies_to": "all",
"created_at": "2026-07-23T14:52:03.192524705Z",
"email": "user@example.com",
"id": "sup_01ky7qckqrf06r38g49b9kxdbc",
"origin": "api_key",
"reason": "manual",
"scope": {
"id": "ws_01ky7m21hjffh9s8kq76gyb1xf",
"type": "workspace"
}
}O campo origin registra como o registro passou a existir. Adições manuais recebem api_key ou user, dependendo se o chamador se autenticou com uma chave API ou uma sessão do dashboard. Adições automáticas recebem bounce_event ou complaint_event, dependendo de qual sinal as criou.
Listar e consultar
Essas chamadas retornam a primeira página. Em Go, o terceiro argumento vazio inicia a paginação; passe o NextCursor da página anterior para ler a próxima página.
const page = await bird.suppressions.list({ limit: 25 });
console.log(page.data.length);page = client.suppressions.list(limit=25)
print(len(page.data))page, err := client.Suppressions.ListPage(context.Background(), bird.SuppressionsListParams{Limit: 25}, "")
if err != nil {
log.Fatal(err)
}
fmt.Println(len(page.Data))$page = $bird->suppressions->list(['limit' => 25])->fetch();
echo count($page->data);bird email suppressions list --limit 25curl "https://us1.platform.bird.com/v1/email/suppressions?limit=25" \
-H "Authorization: Bearer $BIRD_API_KEY"A lista é paginada por cursor, do mais recente para o mais antigo, e filtrável por reason. Para verificar um endereço, passe-o como o parâmetro de consulta email:
const page = await bird.suppressions.list({ email: "user@example.com" });
console.log(page.data.length);page = client.suppressions.list(email="user@example.com")
print(len(page.data))page, err := client.Suppressions.ListPage(context.Background(), bird.SuppressionsListParams{
Email: "user@example.com",
}, "")
if err != nil {
log.Fatal(err)
}
fmt.Println(len(page.Data))$page = $bird->suppressions->list(['email' => 'user@example.com'])->fetch();
echo count($page->data);bird email suppressions list --email user@example.comcurl "https://us1.platform.bird.com/v1/email/suppressions?email=user@example.com" \
-H "Authorization: Bearer $BIRD_API_KEY"O filtro email faz correspondência por prefixo sem diferenciar maiúsculas e minúsculas: user@example.com também corresponde a user@example.com.au. Compare cada endereço retornado com o endereço completo que você solicitou e percorra next_cursor em todas as páginas antes de decidir se existe um registro correspondente. Vários registros podem se aplicar a um mesmo endereço. Chamadores MCP podem usar email_suppressions_check para essa busca exata por endereço.
Quando você tiver um ID de supressão, GET /v1/email/suppressions/{suppression_id} retorna esse único registro: suppressions.get nos SDKs, ou bird email suppressions get <id> na CLI.
Remover um endereço
await bird.suppressions.remove("sup_01ky7qckqrf06r38g49b9kxdbc");client.suppressions.remove("sup_01ky7qckqrf06r38g49b9kxdbc")if err := client.Suppressions.Remove(context.Background(), "sup_01ky7qckqrf06r38g49b9kxdbc"); err != nil {
log.Fatal(err)
}$bird->suppressions->remove('sup_01ky7qckqrf06r38g49b9kxdbc');bird email suppressions remove sup_01ky7qckqrf06r38g49b9kxdbc --yescurl -X DELETE https://us1.platform.bird.com/v1/email/suppressions/sup_01ky7qckqrf06r38g49b9kxdbc \
-H "Authorization: Bearer $BIRD_API_KEY"Um motivo não pode ser removido dessa forma. Um registro complaint é removido apenas por um usuário autenticado no dashboard; uma chave API recebe 422 SuppressionNotRemovableByAPIKey. Registros hard_bounce e manual podem ser removidos de qualquer forma.
Retorna 204 No Content e remove permanentemente esse registro. Outros registros para o mesmo endereço permanecem, e o envio continua bloqueado enquanto qualquer registro restante bloquear a categoria da mensagem. Para remover registros por endereço, pagine a busca ?email=, selecione apenas correspondências exatas de endereço e exclua cada registro desejado por ID. Seja cuidadoso ao remover um registro hard_bounce, porque um endereço que ainda não existe gera bounce no próximo envio e se suprime novamente.
O que acontece quando você envia para um endereço suprimido
Rejeitamos o destinatário de forma visível para você. O destinatário recebe um recipient_id e aparece na lista de destinatários da mensagem com status rejected. Os eventos API e seus webhooks registram um evento email.rejected com rejection_reason: "recipient_suppressed". Os demais destinatários são entregues normalmente.
A mensagem em si ainda é aceita com um 202, mesmo quando todos os seus destinatários estão suprimidos. Resolvemos a supressão após aceitar o envio, enquanto processamos a mensagem, então um endereço que você adicionar agora entra em vigor em poucos minutos e nunca interrompe um envio já em andamento.
Testando com o sandbox
O sandbox de testes exercita o tratamento de supressão de forma determinística. Enviar para suppressed@messagebird.dev se comporta como se o endereço estivesse na sua lista: o destinatário é rejeitado com rejection_reason: "recipient_suppressed" e nunca chega à entrega. Os endereços de bounce e reclamação do sandbox (bounce@messagebird.dev, complaint@messagebird.dev) executam seus resultados pelo pipeline real de eventos sem gravar nada na sua lista de supressão, então os mesmos endereços de teste permanecem reutilizáveis entre execuções.
Próximos passos
- Categorias: transactional versus marketing, e como a categoria interage com a política de supressão
- Links de cancelamento de inscrição: como opt-outs registram uma preferência declarada em vez de uma supressão
- Eventos e webhooks: o payload email.rejected e os eventos de ciclo de vida que geram supressão automática
- Sandbox de testes: endereços mágicos para simular todos os resultados de entrega
- Referência API: Suppressions: schemas completos de solicitação e resposta
- O que acontece quando alguém cancela a subscrição: um vídeo que acompanha um destinatário desde a página de cancelamento até um envio rejeitado
Recursos relacionados
Continue com a documentação, guias e exemplos sobre este tópico. Os recursos estão em inglês.
Entenda o conceitoWhat is one-click unsubscribe, and how do I implement List-Unsubscribe?Explore a funcionalidadeEmail opt-outsSiga o percurso de aprendizagemOperate messaging reliably
Obtenha um resumo de implementação