Send email with .NET
A typed HttpClient registered once, injected everywhere.
You need a verified sending domain and an API key from Settings › API Keys. If neither exists yet, the quickstart covers both in a couple of minutes.
Send
public sealed class SendingClient(HttpClient http)
{
public Task<HttpResponseMessage> SendWelcomeAsync(string to, string userId) =>
http.PostAsJsonAsync("/api/v1/emails", new
{
from = "Acme <[email protected]>",
to,
subject = "Welcome",
html = "<p>You're in.</p>",
idempotencyKey = $"welcome-{userId}"
});
}
// Program.cs
builder.Services.AddHttpClient<SendingClient>(client =>
{
client.BaseAddress = new Uri("https://sending.dev");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", builder.Configuration["Sending:ApiKey"]);
});A successful call answers 202 with the message id: accepted and queued, not yet delivered. Delivery, opens, bounces and complaints arrive later, on webhooks or in the dashboard.
What changes in .NET
AddHttpClient gives you connection reuse and a place to hang retry policies, which is the difference between a demo and something that runs at three in the morning.
The thing that catches people
System.Text.Json camelCases property names by default in ASP.NET Core but not in a plain console app. If the API answers 422 on idempotencyKey, that default is why.
Next
- All the fields: cc and bcc, reply-to, attachments, templates, scheduling.
- Webhooks: delivery, bounce and complaint events, signed with HMAC.
- Domains: SPF, DKIM and MAIL FROM, and why sending is refused until they are in place.
- MCP: the same operations as tools, when the one writing the code is an agent.