Pular para o conteúdo
JetSend

Enviar e-mail

Um POST em /v1/messages com JSON. O corpo precisa de destinatário, assunto e pelo menos um de html ou text.

Dois caminhos para enviar

API RESTvocê está aqui

Para código que você escreve.

Devolve o id da mensagem na hora e aceita idempotência, duas coisas que o SMTP não tem.

Gateway SMTP

Para software que não é seu e só fala SMTP.

Logto, Postfix, msmtp, sendmail, ou o backend de e-mail padrão do Laravel, do Django e do WordPress.

Os dois usam a mesma chave de API, respeitam os mesmos limites do plano e aparecem no mesmo painel, com a mesma linha do tempo de eventos. O que sai por SMTP vem marcado com via=smtp.

O caminho da mensagem

Quatro partes participam de um envio, e cada uma responde por um trecho. Quando uma mensagem não chega, a primeira pergunta é em qual faixa ela parou: o que você controla, o que nós controlamos, e o que nenhum dos dois controla.

Quem responde por cada trecho

Você

Até a chamada sair do seu servidor.

  1. Publica o DNS

    Os registros que provam o domínio e assinam a mensagem. Sem eles, o envio é recusado.

  2. Monta a chamada

    Destinatário, assunto e html ou text.

  3. Guarda a chave

    Ela aparece uma vez. Perdida, cria-se outra.

JetSend

Da chamada até a AWS aceitar, e o registro do que voltar.

  1. Valida e aceita

    Confere a chave, o domínio e a lista de bloqueio. Devolve um id.

  2. Entrega à AWS

    Na região de São Paulo, com a reputação isolada por conta.

  3. Registra o desfecho

    Entregue, devolvida ou reclamada, no painel e no seu webhook.

AWS SES

Do aceite até o servidor do destinatário responder.

  1. Faz a entrega

    Conversa com o servidor do outro lado e aguarda a resposta dele.

  2. Devolve o evento

    Aceite, devolução ou reclamação, que é o que vira o seu registro.

Destinatário

Fora do alcance de todos os anteriores.

  1. Aceita ou recusa

    Caixa cheia, endereço inexistente e regra de spam própria decidem aqui.

  2. Marca como spam

    Vira reclamação, e é o evento mais caro para a reputação do seu domínio.

O caminho acima termina no destinatário. O que acontece depois, e como você fica sabendo, está em Webhooks e eventos.

Exemplo completo

shell
curl -X POST https://api.jetsend.com.br/v1/messages \  -H "Authorization: Bearer $JETSEND_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "from": "faturas@suaempresa.com.br",    "fromName": "Sua Empresa",    "to": "cliente@exemplo.com",    "replyTo": "financeiro@suaempresa.com.br",    "subject": "Sua fatura de setembro",    "html": "<p>Segue a fatura.</p>",    "text": "Segue a fatura."  }'

Campos

CampoTipoObservação
tostringObrigatório. Um endereço.
subjectstringObrigatório, até 998 caracteres.
html / textstringPelo menos um dos dois. Pode mandar os dois.
fromstringPrecisa pertencer a um domínio verificado seu. Sem ele, usamos o remetente padrão da conta.
fromNamestringNome de exibição, até 120 caracteres. Não aceita quebra de linha, aspas, barra invertida nem < >.
replyTostringPara onde vai a resposta, se for diferente do remetente.
cc / bccarrayAté 50 endereços em cada.
headersobjetoCabeçalhos seus. Os reservados são recusados, ver abaixo.
idempotencyKeystringAté 255 caracteres. Ver abaixo.
enableTrackingbooleanLigado por padrão. false desliga abertura e clique nesta mensagem.
scheduledAtstringData e hora ISO 8601 com fuso, até 30 dias à frente. O e-mail sai nessa hora, e não agora. Ver abaixo.
templateIdstringId de um template salvo no painel. Assunto e corpo saem dele, e aí html e text não vão. Ver abaixo.
variablesobjetoValores dos {{nome}} do template. Texto, número ou booleano.
listUnsubscribebooleanDesligado por padrão. true põe o botão "Cancelar inscrição" do Gmail. Ver abaixo.

Cabeçalhos reservados

headers não aceita From, Sender, Reply-To, To, Cc, Bcc, Subject, Date, Message-ID, Return-Path, DKIM-Signature nem Received. Cada um deles tem campo próprio, ou é assinatura que o provedor precisa controlar. A rota recusa em vez de ignorar em silêncio: cabeçalho aceito e descartado é pior, porque o envio parece ter funcionado.

Agendar o envio

Com scheduledAt, a API responde 202 com status: "scheduled" e guarda o e-mail até a hora marcada, com uma tolerância de até 30 segundos. Mande a hora com fuso: 2026-10-20T09:00:00-03:00 sai às 9h de Brasília. Sem fuso, a API recusa, para 9h não virar 6h.

json
{  "from": "contato@suaempresa.com.br",  "to": "cliente@exemplo.com",  "subject": "Sua fatura vence amanhã",  "text": "...",  "scheduledAt": "2026-10-20T09:00:00-03:00"}

Remetente, template e cota são conferidos na hora do pedido, quando você ainda vê a recusa. Na hora de sair, o JetSend confere de novo se a conta está ativa e se o destinatário não entrou na lista de bloqueio nesse meio tempo. Se entrou, o e-mail fica failed e não sai.

Para desistir antes da hora:

shell
curl -X POST https://api.jetsend.com.br/v1/messages/ID_DA_MENSAGEM/cancel \  -H "Authorization: Bearer $JETSEND_API_KEY"

Se o e-mail já começou a sair, a resposta é 409: daí em diante não dá mais para segurar.

Enviar em lote

POST /v1/messages/batch recebe até 100 e-mails numa chamada, cada um com os mesmos campos do envio avulso, inclusive templateId e idempotencyKey:

json
{  "emails": [    { "from": "contato@suaempresa.com.br", "to": "ana@exemplo.com", "subject": "Seu pedido saiu", "text": "..." },    { "from": "contato@suaempresa.com.br", "to": "bruno@exemplo.com", "subject": "Seu pedido saiu", "text": "..." }  ]}

Cada item volta com o próprio status, na mesma ordem do pedido: um endereço bloqueado no meio não segura os outros. A resposta é 200 quando o lote foi processado, então confira recusados antes de dar o lote por enviado.

json
{  "data": [    { "index": 0, "status": 202, "message": { "id": "...", "status": "sent" } },    { "index": 1, "status": 422, "error": { "code": "recipient_suppressed", "message": "..." } }  ],  "aceitos": 1,  "recusados": 1}

O lote conta como um envio por e-mail na cota do plano e no limite por minuto. Se não couber inteiro, nada sai e a API responde 429, com restantes dizendo quantos ainda cabem. O corpo inteiro vai até 10 MB.

Enviar por template

Em Templates, no painel, você guarda assunto e corpo com variáveis no formato {{nome}}. O envio passa só o id e os valores:

json
{  "from": "contato@suaempresa.com.br",  "to": "cliente@exemplo.com",  "templateId": "0b6c9a52-7f1e-4d3a-9c8b-2a1e5f4d3c2b",  "variables": { "nome": "Ana", "plano": "Pro" }}

Faltou uma variável que o template usa? A API responde 422 com variaveis_faltando e a lista delas, em vez de mandar "Olá, !" para o cliente. No HTML o valor é escapado: um nome com < não vira código no e-mail. Mandar subject junto troca só o assunto do template.

Descadastro de um clique

Gmail e Yahoo exigem, de quem envia newsletter e aviso em volume, um jeito de sair da lista com um clique. Com "listUnsubscribe": true, o JetSend põe os cabeçalhos List-Unsubscribe e List-Unsubscribe-Post, e o Gmail mostra o botão "Cancelar inscrição" ao lado do remetente.

Quem clica entra na lista de bloqueio da sua conta, com origem list-unsubscribe, e os próximos envios para o endereço são recusados. Por isso o campo vem desligado: em e-mail de senha, de pagamento ou de nota fiscal, a pessoa precisa continuar recebendo.

O link vale para o destinatário de to, então a API recusa listUnsubscribe junto com cc ou bcc: quem estivesse em cópia tiraria outra pessoa da lista. Os dois cabeçalhos são da plataforma e não podem ir em headers.

Não mandar duas vezes

Se a sua chamada cair na rede depois que a API já aceitou, repetir a requisição manda o e-mail de novo. O campo idempotencyKey resolve: com a mesma chave, a segunda chamada devolve a mesma mensagem em vez de criar outra.

json
{  "to": "cliente@exemplo.com",  "subject": "Pagamento confirmado",  "html": "<p>Recebemos seu pagamento.</p>",  "idempotencyKey": "pagamento-8421"}

Use um identificador do seu domínio de negócio, como o id do pedido ou do pagamento, e não um valor aleatório novo a cada tentativa.

Listar o que saiu

shell
curl "https://api.jetsend.com.br/v1/messages?limit=20" \  -H "Authorization: Bearer $JETSEND_API_KEY"

Devolve as mensagens da conta, da mais recente para a mais antiga, com id, destinatário, assunto e status.

Para mandar de novo uma que já saiu, POST /v1/messages/ID/resend. É um envio novo, com outro id, e passa pelas mesmas checagens: quem entrou na lista de bloqueio desde o original não recebe, e o reenvio conta na cota.

Erros

CódigoO que houve
400Corpo inválido. A resposta diz qual campo e por quê.
401Chave ausente, malformada ou revogada.
402Cota do plano estourada, ou assinatura em aberto.
403Papel sem permissão de envio, ou chave de envio chamando outra rota.
413html ou text acima do teto de bytes.
422O from não pertence a um domínio verificado seu.
503descadastro_indisponivel: o descadastro de um clique não está ligado no ambiente. O e-mail não sai sem o cabeçalho que você pediu.

Para exercitar o seu tratamento de devolução e de reclamação sem sujar a sua reputação, use os apelidos de teste.

Cookies neste site

Os essenciais fazem o site funcionar. Os outros, medição de audiência e atribuição de campanha, só com a sua permissão.

Você pode recusar sem perder nada do site. Detalhes na Política de Privacidade.