Enviar un correo
Un mensaje ahora o más tarde, con adjuntos, o cien en una sola petición.
Enviar un mensaje
var sent = await client.Emails.SendAsync(new Body{ ["from"] = "Acme Billing <[email protected]>", ["to"] = new[] { "[email protected]", "[email protected]" }, ["replyTo"] = "[email protected]", ["subject"] = "Your September invoice", ["html"] = "<p>The invoice is attached.</p>", ["text"] = "The invoice is attached.", ["tags"] = new Body { ["invoice"] = "inv_2026_09_4192" },}); Console.WriteLine($"{sent["id"]} {sent["status"]}");to, cc y bcc aceptan una dirección o una lista, y una dirección es un texto como Ada <[email protected]> o un diccionario con email y name. El cuerpo sale de html y text, de un template guardado o de un draftId.
Cada envío lleva una clave de idempotencia. El cliente crea una por llamada y la reutiliza cuando reintenta, así que una petición reintentada reproduce el primer mensaje. Pasa idempotencyKey: para que eso se mantenga entre procesos y reinicios.
Adjuntos
await using var invoice = File.OpenRead("invoice.pdf"); await client.Emails.SendAsync(new Body{ ["from"] = "[email protected]", ["to"] = "[email protected]", ["subject"] = "Your September invoice", ["text"] = "The invoice is attached.", ["attachments"] = new[] { new Body { ["filename"] = "invoice.pdf", ["content"] = invoice, ["contentType"] = "application/pdf" }, new Body { ["fileId"] = "file_3f9c2a7b1e4d8f60a5c7b92d" }, },});content acepta un byte[] o un Stream legible, que el cliente codifica en base64, o un texto que ya es base64. fileId nombra un archivo subido con client.Files.UploadAsync(), que es como se envía un archivo de más de 5 MB.
Enviar más tarde
var scheduled = await client.Emails.SendAsync(new Body{ ["from"] = "[email protected]", ["to"] = "[email protected]", ["subject"] = "Your invoice is due tomorrow", ["text"] = "A reminder that the invoice is due tomorrow.", ["scheduledAt"] = DateTimeOffset.UtcNow.AddDays(1),}); var id = scheduled["id"]!.GetValue<string>(); await client.Emails.RescheduleAsync(id, DateTimeOffset.UtcNow.AddDays(2)); var cancelled = await client.Emails.CancelAsync(id); Console.WriteLine(cancelled["status"]);scheduledAt acepta un DateTimeOffset, un instante ISO 8601 o una duración como PT1H. Un DateTimeOffset en cualquier parte de un cuerpo se envía como un instante ISO 8601 en UTC. Un mensaje programado se puede cambiar o cancelar hasta que sale.
Enviar un lote
var result = await client.Emails.SendBatchAsync(new[]{ new Body { ["from"] = "[email protected]", ["to"] = "[email protected]", ["subject"] = "Order AC-4192 has shipped", ["text"] = "It is on its way." }, new Body { ["from"] = "[email protected]", ["to"] = "[email protected]", ["subject"] = "Order AC-4193 has shipped", ["text"] = "It is on its way." },}); Console.WriteLine($"{result.Sent} sent, {result.Failed} failed"); foreach (var item in result){ if ((string?)item["status"] == "error") { Console.WriteLine($"{item["index"]} {item["error"]?["message"]}"); }}Un lote admite hasta 100 mensajes y nunca es todo o nada: una dirección incorrecta hace fallar su propio elemento y el resto sale igualmente. Comprueba Failed y el status de cada elemento en lugar de confiar en una excepción.