Pular para o conteúdo
Docs

Tutorial

Envie e-mails do ASP.NET Core e do .NET com o pacote NuGet do Emailit, com MailKit ou com System.Net.Mail por SMTP, e verifique os webhooks do Emailit.

Atualizado em 1 de out. de 2026

Este guia mostra como enviar e-mails de uma aplicação .NET com o pacote NuGet oficial Emailit, como usar MailKit ou System.Net.Mail por SMTP como alternativa e como verificar webhooks em uma minimal API do ASP.NET Core.

Pré-requisitos

Instalar o SDK

Terminal
dotnet add package Emailit

Configurar a chave de API

O ASP.NET Core lê a configuração de variáveis de ambiente, em que __ separa as seções. Defina Emailit__ApiKey em produção:

Terminal
export Emailit__ApiKey=secret_••••••••••••••••••••••••••••••••

Durante o desenvolvimento, guarde a chave nos user secrets em vez de no appsettings.json:

Terminal
dotnet user-secrets init
dotnet user-secrets set "Emailit:ApiKey" "secret_••••••••••••••••••••••••••••••••"

Enviar um e-mail

Registre um único cliente e injete-o nos seus endpoints:

Program.cs
using Emailit;
using Emailit.Options;
using Emailit.Resources;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton(new EmailitClient(builder.Configuration["Emailit:ApiKey"]!));

var app = builder.Build();

app.MapPost("/orders/{id}/confirm", (string id, EmailitClient emailit) =>
{
    Email email = emailit.Emails.Send(new EmailSendOptions
    {
        From = "Acme <orders@acme.com>",
        To = new[] { "ada@example.com" },
        Subject = $"Order {id} confirmed",
        Html = $"<p>We've received order {id}.</p>",
    });

    return Results.Ok(new { emailId = email.Id });
});

app.Run();

Send é síncrono; para envios em massa, execute-o a partir de um serviço em segundo plano para manter as threads de requisição livres. As opções também aceitam Cc, Bcc, ReplyTo, Attachments, Template com Variables, ScheduledAt e Tracking; consulte Enviar um e-mail.

Se o seu código já monta objetos System.Net.Mail.MailMessage, o SDK pode enviá-los pela API:

C#
using System.Net.Mail;

var message = new MailMessage("orders@acme.com", "ada@example.com", "Order confirmed", "<p>Thanks!</p>")
{
    IsBodyHtml = true,
};

Email email = emailit.Emails.Send(message);

Tratar erros

C#
using Emailit.Exceptions;

try
{
    emailit.Emails.Send(options);
}
catch (RateLimitException)
{
    // 429: back off and retry
}
catch (AuthenticationException)
{
    // 401: the API key is missing or invalid
}
catch (UnprocessableEntityException ex)
{
    // 422: for example, the from domain isn't verified
    logger.LogWarning("Emailit rejected the email: {Message}", ex.Message);
}
catch (ApiErrorException ex)
{
    logger.LogError("Emailit error {Status}: {Body}", ex.HttpStatus, ex.HttpBody);
}

Enviar por SMTP como alternativa

MailKit

A Microsoft recomenda o MailKit para código SMTP novo. Instale-o com dotnet add package MailKit:

C#
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;

var message = new MimeMessage();
message.From.Add(new MailboxAddress("Acme", "orders@acme.com"));
message.To.Add(MailboxAddress.Parse("ada@example.com"));
message.Subject = "Order confirmed";
message.Body = new TextPart("html") { Text = "<p>We've received your order.</p>" };

using var smtp = new SmtpClient();
await smtp.ConnectAsync("smtp.emailit.com", 587, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync("emailit", builder.Configuration["Emailit:ApiKey"]);
await smtp.SendAsync(message);
await smtp.DisconnectAsync(true);

Para TLS implícito, conecte-se à porta 465 com SecureSocketOptions.SslOnConnect.

System.Net.Mail

O cliente nativo funciona para casos simples. Ele só aceita STARTTLS, então use a porta 587 (ou 2525 ou 2587):

C#
using System.Net;
using System.Net.Mail;

using var client = new SmtpClient("smtp.emailit.com", 587)
{
    EnableSsl = true,
    Credentials = new NetworkCredential("emailit", apiKey),
};

client.Send(new MailMessage("orders@acme.com", "ada@example.com", "Order confirmed", "We've received your order."));

Consulte Configurações de SMTP para ver todas as portas.

Receber webhooks

Crie um webhook e guarde o segredo de assinatura dele como Emailit:WebhookSecret. Leia o corpo bruto, verifique-o e depois interprete o array de eventos:

Program.cs
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

app.MapPost("/webhooks/emailit", async (HttpRequest request, IConfiguration config) =>
{
    using var reader = new StreamReader(request.Body, Encoding.UTF8);
    var body = await reader.ReadToEndAsync();

    var signature = request.Headers["X-Emailit-Signature"].ToString();
    var timestamp = request.Headers["X-Emailit-Timestamp"].ToString();

    if (!long.TryParse(timestamp, out var ts) ||
        Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - ts) > 300)
    {
        return Results.Unauthorized();
    }

    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(config["Emailit:WebhookSecret"]!));
    var expected = Convert.ToHexString(hmac.ComputeHash(Encoding.UTF8.GetBytes($"{timestamp}.{body}"))).ToLowerInvariant();

    if (!CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(expected), Encoding.UTF8.GetBytes(signature)))
    {
        return Results.Unauthorized();
    }

    // The body is a JSON array of up to 100 events.
    using var events = JsonDocument.Parse(body);
    foreach (var evt in events.RootElement.EnumerateArray())
    {
        if (evt.GetProperty("type").GetString() == "email.bounced")
        {
            var address = evt.GetProperty("data").GetProperty("object").GetProperty("to").GetString();
            // Stop emailing this address.
        }
    }

    return Results.Ok();
});

Retorne um 2xx em até 30 segundos; as outras respostas recebem novas tentativas. Consulte Assinatura das requisições.

Dicas para produção

  • Registre o cliente como singleton. Um único EmailitClient por aplicação é suficiente.
  • Coloque os envios em massa em uma fila. Envie a partir de um BackgroundService ou de uma biblioteca de jobs como o Hangfire e limite o ritmo para ficar dentro dos seus limites de envio (2 e-mails por segundo por padrão).
  • Torne as novas tentativas seguras. Se você tentar de novo depois de um timeout, envie um cabeçalho Idempotency-Key com o HttpClient; consulte Idempotência.
  • Elimine webhooks duplicados guardando cada event_id que você processa.

Próximos passos

Anexos, agendamento e rastreamento.
Todos os eventos e os payloads deles.
Corrija erros de autenticação e de conexão.
Todas as bibliotecas oficiais.

Esta página foi útil?

Obrigado pelo feedback.

Obrigado, lemos todas as mensagens.