MillionSend Docs
Conceitos

Transmissões

Crie, agende e envie um e-mail para muitos contatos.

Uma transmissão (/broadcasts na API) é um e-mail enviado a muitos contatos: todos eles, um segmento ou um tópico. Escreva no editor de blocos do painel ou direto em HTML no modo código, com campos de mesclagem por contato, ou crie transmissões pela API.

Ciclo de vida

draft → scheduled → sending → sent
              ↘ canceled
  • Transmissões são criadas como rascunhos (draft). Só rascunhos podem ser editados ou apagados.
  • POST /broadcasts/{id}/send agenda o envio — imediatamente, ou em um timestamp scheduled_at.
  • Uma transmissão na fila — agendada, ou já saindo — pode ser cancelada com POST /broadcasts/{id}/cancel. Os e-mails já enviados não voltam; o canceled_remaining da resposta diz quantos foram parados, e o sent_count de uma leitura diz quantos já tinham saído.
  • Na API, scheduled e sending aparecem ambos como queued (correspondendo à união de status do SDK do Resend); canceled é uma extensão do MillionSend. Uma transmissão aparece como queued com sent_at nulo até o último e-mail sair, leve o tempo que levar.

Editor de blocos e HTML

O editor da transmissão tem dois modos para o corpo. No editor de blocos, você monta o e-mail com blocos. No modo código, você edita o HTML direto, com uma pré-visualização ao vivo ao lado. Os dois modos usam os mesmos campos de mesclagem por contato.

Uma transmissão criada com html (pela API, pelo MCP ou por uma migração) ou a partir de um template em HTML é escrita em HTML. O painel abre essa transmissão na pré-visualização, e você edita o HTML no modo código. O HTML fica exatamente como foi escrito: o editor de blocos nunca mexe nele sozinho, porque, ao virar blocos, um layout de tabelas e CSS inline é simplificado e perde o que os blocos não expressam.

A transmissão só vira blocos se você escolher Converter em blocos, e o HTML armazenado só muda quando você salvar. Os templates seguem a mesma regra.

O caminho inverso também existe. Editar como HTML passa uma transmissão de blocos para o modo código. A troca acontece sempre na própria transmissão, já que não dá para duplicar transmissões. Os blocos viram o HTML que eles geram, e esse HTML deixa de fora os blocos com a condição Show if.

Até você salvar, Voltar para blocos traz os blocos de volta exatamente como estavam. Depois de salvar, converter de volta em blocos perde parte do layout. Com o corpo vazio, a troca acontece na hora, então uma transmissão nova pode começar direto em HTML. Uma transmissão salva com o corpo vazio volta a abrir no editor de blocos.

No modo código, a parte em texto puro gerada a partir do HTML acompanha o HTML conforme você edita. O texto puro enviado pela API é mantido como está.

O que o fan-out faz

Cada e-mail de destinatário passa pelo mesmo pipeline de um envio transacional, mais o tratamento específico de transmissão:

  • Resolução de audiência — contatos descadastrados globalmente são sempre excluídos; filtros de segmento e inscrições em tópicos são avaliados no momento do envio.
  • Checagens de supressão — endereços na lista de supressão são pulados.
  • Campos de mesclagem — valores por contato (nome, propriedades personalizadas) são substituídos no template.
  • Links de descadastro — headers List-Unsubscribe de um clique (RFC 8058) e um link de descadastro hospedado são adicionados a cada mensagem. Para colocar o link no corpo, escreva {{{UNSUBSCRIBE_URL}}} — ele é substituído por destinatário pela URL de descadastro hospedada. {{{RESEND_UNSUBSCRIBE_URL}}} é um alias suportado, então templates escritos para o Resend continuam funcionando sem mudança (e voltam sem mudança).
  • Cabeçalhos de lista: toda mensagem leva List-Id, Precedence: bulk e Auto-Submitted: auto-generated, para os provedores de e-mail tratarem a mensagem como e-mail de lista. O List-Id nomeia a lista, não o envio: <{topic_id}.example.com> para uma transmissão a um tópico e <broadcasts.example.com> para as outras, onde example.com é o seu domínio de envio. Toda transmissão para a mesma lista constrói a reputação da mesma lista.

Os e-mails de transmissão entram na fila de envio abaixo dos transacionais: um e-mail transacional aceito enquanto uma transmissão está saindo é enviado antes dos destinatários restantes. Os envios rodam em paralelo, no ritmo da taxa de envio do SES da instância.

Em uma instância auto-hospedada, os links de descadastro são construídos a partir de APP_BASE_URL, então o envio de transmissões é rejeitado até que ela esteja configurada — veja Auto-hospedagem. Na Nuvem isso é automático.

Ritmo de envio

A plataforma envia uma quantidade limitada de e-mails por dia. Uma transmissão que cabe no que está disponível sai de uma vez, na taxa de envio. Uma maior sai em levas: a primeira agora, o restante conforme a capacidade libera nos dias seguintes. E-mails transacionais nunca ficam esperando atrás das levas de uma transmissão.

O envio avisa de antemão:

{
  "id": "8c1f0b8e-…",
  "finishes_at": "2026-09-18T13:26:05Z",
  "estimated": true,
  "warning": {
    "code": "paced",
    "days": 3,
    "message": "170,000 recipients exceed the broadcast capacity available now; sending is paced and finishes about 2026-09-18T13:30:00Z. Transactional email is unaffected."
  }
}
  • finishes_at é o instante estimado em que o último e-mail sai; null quando não há estimativa. É uma estimativa: outros envios a movem.
  • warning só aparece quando o envio leva mais de uma leva: paced quando a audiência passa da capacidade disponível agora, queued_behind quando outros envios estão na frente (a mensagem diz quando este começa). Um domínio em aquecimento responde warming_up no lugar (veja Aquecimento).
  • De um domínio sob o limite de domínio novo, a estimativa segue o calendário do limite, e o warning é new_domain_limit quando o limite distribui o envio ao longo de vários dias. O limite sozinho nunca deixa um envio grande demais: quando não dá para estimar o fim, finishes_at é null.
  • No plano Free, os e-mails para provedores que informam reclamações saem para 10 destinatários de uma vez e depois 10 por hora, somando todas as equipes Free que você criou, cada e-mail na sua vez: um e-mail transacional enviado depois de uma transmissão espera atrás dela. E-mails só para Gmail, Apple Mail, t-online ou o simulador de caixas do SES nunca esperam. O finishes_at não conta essa espera.
  • Enquanto uma transmissão está saindo, GET /broadcasts/{id} e a lista trazem finishes_at ao vivo e sent_count.
  • Uma audiência que precisaria de mais de 24 dias de capacidade — da plataforma, ou do limite do seu plano — é recusada com 422 broadcast_too_large em vez de aceita e deixada esperando. Divida em segmentos menores ou fale com o suporte.

Aquecimento

Quando o aquecimento do domínio de envio está ligado, uma transmissão sai ao longo de dias: cada dia envia até o volume daquele dia, com os contatos mais ativos primeiro, e os contatos inativos há 90 dias ou mais ficam de fora, a não ser que o aquecimento os envie por último. A janela Enviar transmissão mostra o plano dia a dia antes do envio. Para um domínio sem aquecimento, ela oferece o aquecimento quando a transmissão é bem maior que tudo o que o domínio já enviou em um dia.

A resposta do envio traz warning.code warming_up:

{
  "id": "8c1f0b8e-…",
  "finishes_at": "2026-10-24T19:45:00Z",
  "estimated": true,
  "warning": {
    "code": "warming_up",
    "days": 6,
    "message": "This domain is warming up, so this broadcast goes out over about 6 days, most active contacts first."
  }
}
  • O finishes_at vem do plano do aquecimento, que conta com todos os dias saudáveis. Um dia que mantém ou reduz o volume deixa o fim para mais tarde.
  • Com o aquecimento pausado, days é 0 e finishes_at é null. A transmissão espera até o aquecimento ser retomado.
  • Como no ritmo de envio, uma transmissão que o aquecimento levaria mais de 24 dias para enviar é recusada com 422 broadcast_too_large. Aumente a meta diária ou envie para um segmento menor.

A página da transmissão mostra o ritmo do aquecimento dia a dia, quantos contatos inativos ficaram de fora e, quando um dia teve um sinal fora do limite, por que o volume foi mantido ou reduzido. Os e-mails esperando pelo aquecimento aparecem como Aguardando.

Por provedor de e-mail

A página da transmissão divide os e-mails dela por provedor: Gmail, Microsoft, Yahoo, Apple e Outros, cada um com quantos e-mails foram enviados, entregues, abertos, clicados, deram bounce, receberam reclamação e atrasaram. O agrupamento é pelo endereço do destinatário, então um domínio de empresa com e-mail hospedado no Google ou na Microsoft entra em Outros. As aberturas contam só pessoas, nunca um pré-carregamento feito por máquina, e os bounces contam só os permanentes. A taxa de reclamações é calculada sobre os e-mails para provedores que avisam sobre spam, a mesma base das proteções; o Gmail e a Apple nunca avisam, então a célula deles mostra um traço.

Proteções

  • Somente um domínio verificado da sua equipe pode aparecer em from. O subdomínio compartilhado da sua equipe também aparece como verified, mas enviar uma transmissão por ele responde 403 inbox_send_policy.
  • Se sua taxa recente de bounce ou reclamação cruzou o limite de pausa do SES, novos envios de transmissão são bloqueados com um erro 403 sending_paused, contendo o estrago antes que o SES pause o envio por completo. Cada reclamação conta no dia (UTC) em que o e-mail foi enviado, a mesma data que o SES usa na própria taxa, então a pausa considera as reclamações sobre os e-mails enviados nos últimos dois dias, e o alerta, sobre os enviados nos últimos sete. A taxa de reclamação conta só os e-mails para provedores que informam reclamações (Gmail, Apple Mail e t-online nunca informam), e as reclamações só contam para um alerta ou para essa pausa a partir de 100 desses envios. No plano Free, elas contam desde o primeiro e-mail e são julgadas juntas em todas as equipes Free que você criou, inclusive as excluídas, e uma pausa vale para todas elas.
  • Depois de uma análise, um operador pode retirar uma pausa por bounces antes da hora (no MillionSend Cloud, peça ao suporte; no plano Free, a pausa sai sozinha em até dois dias). Os bounces depois da retirada contam normalmente, e uma pausa por reclamações nunca é retirada antes da hora.
  • Se a taxa agregada de bounce da plataforma na região SES do seu remetente se aproxima do limite em que o SES age sobre a conta, envios de transmissão nessa região são recusados com 403 broadcasts_paused até a taxa se recuperar. Quando é a taxa de reclamações, só as equipes cuja própria taxa de reclamações nos últimos 30 dias chega à linha de revisão do SES, de 0,1%, têm o envio recusado; a pausa não recusa as transmissões de nenhuma outra equipe. O e-mail transacional continua saindo, e a pausa termina sozinha. No MillionSend Cloud, cada equipe Free cujos e-mails receberam uma reclamação na região também fica em pausa para revisão.

Veja a referência da API para todos os endpoints de transmissões.

Mudanças recentes

  • Agora, depois de uma análise, um operador pode retirar uma pausa por bounces antes da hora (no MillionSend Cloud, peça ao suporte; no plano Free, a pausa sai sozinha em até dois dias). Os bounces depois da retirada contam normalmente, e uma pausa por reclamações nunca é retirada antes da hora.
  • As reclamações contam no dia em que o e-mail foi enviado, a mesma data que o SES usa na própria taxa, e não no dia em que chegam: na proteção de envio, na nota da conta e na taxa de reclamação da página de Métricas. Uma reclamação atrasada sobre e-mails antigos não pausa mais uma equipe que está enviando bem hoje.
  • Uma pausa pela taxa de reclamações da plataforma em uma região do SES recusa transmissões com 403 broadcasts_paused só para as equipes cuja própria taxa de reclamações nos últimos 30 dias é de 0,1% ou mais; antes, recusava todas as equipes da região.
  • No plano Free, os e-mails para provedores que informam reclamações saem para 10 destinatários de uma vez e depois 10 por hora, somando todas as equipes Free que você criou. Veja Ritmo de envio.
  • No plano Free, as reclamações contam para um alerta ou para o 403 sending_paused desde o primeiro e-mail, julgadas juntas em todas as equipes Free que você criou. Bounces e reclamações do simulador de caixas do SES nunca contam.
  • Editar como HTML no editor passa uma transmissão de blocos para o modo código. Voltar para blocos desfaz a troca até você salvar. Veja Editor de blocos e HTML.
  • Uma transmissão de um domínio em aquecimento sai ao longo de dias. A resposta do envio traz warning.code warming_up, e uma que o aquecimento levaria mais de 24 dias para enviar é recusada com 422 broadcast_too_large.
  • O List-Id nomeia o tópico, ou o domínio de envio, em vez de cada transmissão, então toda transmissão para a mesma lista leva o mesmo.
  • A página da transmissão divide a entrega por provedor de e-mail.
  • A taxa de reclamação por trás do 403 sending_paused conta só os e-mails para provedores que informam reclamações, e só a partir de 100 desses envios.
  • Uma transmissão com e-mails ainda esperando — por capacidade, ou pela virada do limite do plano — aparece como queued com sent_at nulo até o último e-mail sair. Antes aparecia como sent assim que todos os e-mails eram gravados.
  • Uma audiência cujo limite do plano precisaria de mais de 24 dias é recusada com 422 broadcast_too_large em vez de aceita e deixada esperando.
  • POST /broadcasts/{id}/cancel funciona em uma transmissão que já está saindo; a resposta traz canceled_remaining.

Nesta página