{"id":20114,"date":"2024-12-11T00:00:00","date_gmt":"2024-12-11T00:00:00","guid":{"rendered":"https:\/\/www.mailgun.com\/blog\/send-email-with-c-sharp-2\/"},"modified":"2026-09-14T23:33:34","modified_gmt":"2026-09-14T23:33:34","slug":"send-email-with-c-sharp","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/","title":{"rendered":"Enviando e-mail usando C# e a API do Mailgun"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">.NET is one of the <a href=\"https:\/\/survey.stackoverflow.co\/2024\/technology#2-web-frameworks-and-technologies\" target=\"_tabs\" rel=\"noopener noreferrer\">most popular, stable, and admired web frameworks<\/a> you can use to build modern web applications. The tooling provided by .NET can help you get started quickly and maintain your applications well into the future. With it, you can build everything from small laser-focused microservices to full-fledged web applications.<\/p>\n\n<p class=\"wp-block-paragraph\">Eventually, though, every real-life application needs to be able to send <a href=\"https:\/\/www.mailgun.com\/pt\/solutions\/use-cases\/transactional-email\/\" target=\"_tabs\" rel=\"noopener noreferrer\">transactional emails<\/a> (such as account verification, password resets, automated daily\/monthly summary reports, and so on). While .NET offers tooling that helps you send emails, it doesn&#8217;t have the production-capable infrastructure you need to reliably and efficiently send them.<\/p>\n\n<p class=\"wp-block-paragraph\">In this article, you&#8217;ll learn how to use Mailgun&#8217;s HTTP API to send transactional emails from your .NET applications and ensure that your integration is reliable, scalable, and secure.<\/p>\n\r\n    <nav data-content-type=\"longform\" class=\"toc-block longform-spacings px-5 py-6 px-md-6 px-lg-7 py-md-7 bg-light fs-sm rounded-lg\" aria-labelledby=\"toc-title-8828\"><p class=\"h5 m-0\" id=\"toc-title-8828\">\u00cdndice<\/p><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">01<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#how-to-send-email-using-the-mailgun-api\">How to send email using the Mailgun API<\/a><a class=\"scrollme link-body-color\" href=\"#set-up-your-mailgun-account\">Set up your Mailgun account<\/a><a class=\"scrollme link-body-color\" href=\"#create-a-new-c-project\">Create a new C# project<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">02<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#more-about-mailgun-api-endpoints\">More about Mailgun API endpoints<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">03<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#send-your-first-email-with-the-mailgun-api\">Send your first email with the Mailgun API<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">04<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#handle-responses-and-errors\">Handle responses and errors<\/a><a class=\"scrollme link-body-color\" href=\"#handle-400-error-codes\">Handle 400 error codes<\/a><a class=\"scrollme link-body-color\" href=\"#handle-500-error-codes\">Handle 500 error codes<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">05<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#production-ready-email-integration\">Production-ready email integration<\/a><a class=\"scrollme link-body-color\" href=\"#secure-your-api-key\">Secure your API key<\/a><a class=\"scrollme link-body-color\" href=\"#other-production-grade-features\">Other production-grade features<\/a><a class=\"scrollme link-body-color\" href=\"#integrate-with-the-net-ecosystem\">Integrate with the .NET ecosystem<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">06<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#wrapping-up\">Wrapping up<\/a><\/div><\/div><\/nav>    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> <a href='https:\/\/www.mailgun.com\/pt\/'>Mailgun<\/a> is a transactional email service that can power your .NET applications to send production-ready emails. You can choose to use either Mailgun&#x27;s <a href='https:\/\/www.mailgun.com\/pt\/features\/servidor-smtp\/'>SMTP service<\/a> or its <a href='https:\/\/www.mailgun.com\/pt\/empresarial\/api-de-e-mail\/'>HTTP API<\/a> for higher-performance transactional email delivery.<\/div>\r\n    <\/div>\r\n\n<h2 class=\"wp-block-heading\">How to send email using the Mailgun API<\/h2>\n\n<p class=\"wp-block-paragraph\">Before you begin this tutorial, you&#8217;ll need the following prerequisites:<\/p>\n\n<ul class=\"wp-block-list\">\n<li>Basic knowledge of C# and .NET<\/li>\n\n\n\n<li>Any modern IDE like Visual Studio, JetBrains Rider, or Visual Studio Code<\/li>\n<\/ul>\n\n<p class=\"wp-block-paragraph\">If you choose not to use Visual Studio and running dotnet &#8211;info from a terminal isn&#8217;t successful, then you&#8217;ll need to <a href=\"https:\/\/dotnet.microsoft.com\/en-us\/download\" target=\"_tabs\" rel=\"noopener noreferrer\">download and install the latest .NET SDK<\/a>.<\/p>\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> .NET is a cross-platform framework, so you can install it on Windows, Mac, and Linux.If you have trouble creating an API key, you can follow <a href='https:\/\/help.mailgun.com\/hc\/en-us\/articles\/203380100-Where-can-I-find-my-API-keys-and-SMTP-credentials'>these instructions<\/a>.<\/div>\r\n    <\/div>\r\n\n<h3 class=\"wp-block-heading\">Set up your Mailgun account<\/h3>\n\n<p class=\"wp-block-paragraph\">Start by <a href=\"https:\/\/signup.mailgun.com\/new\/signup\" target=\"_tabs\" rel=\"noopener noreferrer\">creating a free Mailgun account<\/a>. Once you&#8217;re logged in, create a new API key and store it for later use.<\/p>\n\n<p class=\"wp-block-paragraph\">For production email sending, you need to register a domain that you own with Mailgun. In this tutorial, you&#8217;ll use the <a href=\"https:\/\/app.mailgun.com\/mg\/sending\/domains?domains=%7B%22limit%22%3A10%2C%22region%22%3A%22us1%22%2C%22search%22%3A%22sandbox%22%2C%22skip%22%3A0%7D\" target=\"_tabs\" rel=\"noopener noreferrer\">sandbox domain<\/a> provided by Mailgun.<\/p>\n\n<h3 class=\"wp-block-heading\">Create a new C# project<\/h3>\n\n<p class=\"wp-block-paragraph\">Once your Mailgun account is set up, you need to create a new .NET MVC web solution and configure some additional tools to help you send transactional emails with .NET.<\/p>\n\n<p class=\"wp-block-paragraph\">Open a terminal and run dotnet new mvc -n MailDemo. This command creates a new .NET web project using an MVC architecture inside a new \/MailDemo folder. Next, execute cd MailDemo to navigate into the new folder created for you.<\/p>\n\n<p class=\"wp-block-paragraph\">After you&#8217;ve navigated into the folder, you need to add your configuration values to appsettings.json. Add a new JSON entry named &#8220;Mailgun&#8221;. The value for Mailgun:ApiKey is the API key that you created in the previous section (you&#8217;ll learn about securing your API keys later). Mailgun:Domain is the sandbox domain that has already been created for you.<\/p>\n\n<p class=\"wp-block-paragraph\">Your entire appsettings.json file should look like this:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    {rn    &quot;Logging&quot;: {rn        &quot;LogLevel&quot;: {rn            &quot;Default&quot;: &quot;Information&quot;,rn            &quot;Microsoft.AspNetCore&quot;: &quot;Warning&quot;rn        }rn    },rn    &quot;AllowedHosts&quot;: &quot;*&quot;,rn    &quot;Mailgun&quot;: {rn        &quot;ApiKey&quot;: &quot;&lt;Your API Key&gt;&quot;,rn        &quot;Domain&quot;: &quot;&lt;Your sandbox domain&gt;&quot;rn    }rn}\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">Next, you need to configure a <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/extensions\/httpclient-factory#named-clients\" target=\"_tabs\" rel=\"noopener noreferrer\">named HttpClient<\/a> for easy reuse of default parameters. To do so, open Program.cs. The top of the file should look like this:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    using System.Net.Http.Headers;rnusing System.Text;rnrnvar builder = WebApplication.CreateBuilder(args);rnrn\/\/ Add services to the containerrnbuilder.Services.AddControllersWithViews();rnrn\/\/ Set up your named HttpClient for easy reusernbuilder.Services.AddHttpClient(&quot;Mailgun&quot;, client =&gt;rn{rn    \/\/ Grab values from the configurationrn    var apiKey = builder.Configuration.GetValue&lt;string&gt;(&quot;Mailgun:ApiKey&quot;);rn    var base64Auth = Convert.ToBase64String(Encoding.ASCII.GetBytes($&quot;api:{apiKey}&quot;));rn    var domain = builder.Configuration.GetValue&lt;string&gt;(&quot;Mailgun:Domain&quot;);rnrn    \/\/ Set default values on the HttpClientrn    client.BaseAddress = new Uri($&quot;https:\/\/api.mailgun.net\/v3\/{domain}\/messages&quot;);rn    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Basic&quot;, base64Auth);rn});rnrnvar app = builder.Build();rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">Since you&#8217;ll only be sending emails, your HttpClient is configured with the full URL from Mailgun&#8217;s HTTP API that&#8217;s used for sending mail.<\/p>\n\n<p class=\"wp-block-paragraph\">At this point, everything you need to send your first email is ready.<\/p>\n\n<h2 class=\"wp-block-heading\">More about Mailgun API endpoints<\/h2>\n\n<p class=\"wp-block-paragraph\">The HttpClient is configured to send HTTP requests to the https:\/\/api.mailgun.net\/v3\/{domain}\/messages endpoint. Mailgun also offers other endpoints to help you have a robust and holistic tool for managing and sending transactional emails:<\/p>\n\n<ul class=\"wp-block-list\">\n<li>Send email: POST \/v3\/{domain_name}\/messages<\/li>\n\n\n\n<li>Send email in MIME format: POST \/v3\/{domain_name}\/messages.mime<\/li>\n\n\n\n<li>Retrieve a stored email: GET \/v3\/domains\/{domain_name}\/messages\/{storage_key}<\/li>\n\n\n\n<li>View your domains: GET \/v4\/domains<\/li>\n\n\n\n<li>Create a new domain: POST \/v4\/domains<\/li>\n\n\n\n<li>View a paginated list of all inbound and outbound events: GET \/v3\/{domain_name}\/events<\/li>\n\n\n\n<li>View a paginated list of all bounces: GET \/v3\/{domainID}\/bounces<\/li>\n<\/ul>\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> You can view the other available endpoints by visiting <a href='https:\/\/documentation.mailgun.com\/docs\/mailgun\/api-reference\/openapi-final\/tag\/Messages\/'>Mailgun&#x27;s API reference documentation<\/a>.<\/div>\r\n    <\/div>\r\n\n<h2 class=\"wp-block-heading\">Send your first email with the Mailgun API<\/h2>\n\n<p class=\"wp-block-paragraph\">Before you send your first transactional email, make sure that the recipient email address you use is one of the authorized recipients for your sandbox domain. In your Mailgun account, <a href=\"https:\/\/app.mailgun.com\/mg\/sending\/domains\" target=\"_tabs\" rel=\"noopener noreferrer\">view your domains<\/a>, open your sandbox domain, and on the right-hand side, add your personal email as an authorized recipient:<\/p>\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" class=\"wp-image-4064\" width=\"1570\" height=\"812\" src=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.20.57_PM.png\" alt=\"Overview Screen\" srcset=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.20.57_PM.png 1570w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.20.57_PM-300x155.png 300w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.20.57_PM-768x397.png 768w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.20.57_PM-1024x530.png 1024w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.20.57_PM-1536x794.png 1536w\" sizes=\"(max-width: 1570px) 100vw, 1570px\" \/><\/figure>\n\n<p class=\"wp-block-paragraph\">Next, create a new file at \/Controllers\/OrderController.cs and replace the contents of the file with the following:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    using System.Diagnostics;rnusing Microsoft.AspNetCore.Mvc;rnusing MailDemo.Models;rnusing System.Text;rnusing System.Net.Mime;rnrnnamespace MailDemo.Controllers;rnrnpublic class OrderController : Controllerrn{rn    private readonly HttpClient _httpClient;rn    private readonly IConfiguration _config;rnrn    public OrderController(IHttpClientFactory httpClientFactory, IConfiguration config)rn    {rn        \/\/ Get your named HttpClient that is preconfiguredrn        this._httpClient = httpClientFactory.CreateClient(&quot;Mailgun&quot;);rn        this._config = config;rn    }rnrn    public async Task&lt;IActionResult&gt; Confirm()rn    {rn        using MultipartFormDataContent form = new();rnrn        \/\/ Local function keeps this code a bit clearerrn        void SetFormParam(string key, string value) =&gt;rn        form.Add(new StringContent(value, Encoding.UTF8, MediaTypeNames.Text.Plain), key);rnrn        SetFormParam(&quot;from&quot;, $&quot;Test User &lt;postmaster@{this._config.GetValue&lt;string&gt;(&quot;Mailgun:Domain&quot;)}&gt;&quot;);rn        SetFormParam(&quot;to&quot;, &quot;your_authorized_recipient.com&quot;);rn        SetFormParam(&quot;subject&quot;, &quot;Hello World!&quot;);rn        SetFormParam(&quot;text&quot;, &quot;My first transactional email!&quot;);rn        SetFormParam(&quot;html&quot;, @&quot;&lt;html&gt;&lt;body&gt;&lt;p style=&quot;&quot;color:blue;&quot;&quot;&gt;My first transactional email!&lt;\/p&gt;&lt;\/body&gt;&lt;\/html&gt;&quot;);rnrn        var result = await this._httpClient.PostAsync(string.Empty, form);rnrn        if (!result.IsSuccessStatusCode)rn        {rn            return new JsonResult(await result.Content.ReadAsStringAsync());rn        }rnrn        return new JsonResult(@&quot;Your order was confirmed. You should get an email soon!&quot;);rn    }rn}rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">Execute dotnet run from your terminal to start your web application. Then, open a web browser and navigate to \/order\/confirm. You should get an email in your inbox within a couple of seconds:<\/p>\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" class=\"wp-image-4068\" width=\"1646\" height=\"936\" src=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.21.06_PM.png\" alt=\"Hello World Screen Shot\" srcset=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.21.06_PM.png 1646w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.21.06_PM-300x171.png 300w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.21.06_PM-768x437.png 768w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.21.06_PM-1024x582.png 1024w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screenshot_2024-12-10_at_5.21.06_PM-1536x873.png 1536w\" sizes=\"(max-width: 1646px) 100vw, 1646px\" \/><\/figure>\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> The email might get sent to your spam folder because you haven&#x27;t registered the domain yet. That&#x27;s okay for now.<\/div>\r\n    <\/div>\r\n\n<h2 class=\"wp-block-heading\">Handle responses and errors<\/h2>\n\n<p class=\"wp-block-paragraph\">Unfortunately, sometimes things go wrong. For instance, your API key could have a typo, maybe you didn&#8217;t add all the required fields to the HTTP request, or you could hit Mailgun&#8217;s rate limits.<\/p>\n\n<p class=\"wp-block-paragraph\">A failed HTTP request to Mailgun&#8217;s API will return one of four different HTTP error codes:<\/p>\n\n<ul class=\"wp-block-list\">\n<li>400: Something with the formatting of the request is wrong.<\/li>\n\n\n\n<li>401: Authentication failed.<\/li>\n\n\n\n<li>429: You&#8217;ve reached Mailgun&#8217;s rate limit.<\/li>\n\n\n\n<li>500: Something on the network or Mailgun&#8217;s end went wrong.<\/li>\n<\/ul>\n\n<p class=\"wp-block-paragraph\">Let&#8217;s take a look at how you can handle some of these failure scenarios.<\/p>\n\n<h3 class=\"wp-block-heading\">Handle 400 error codes<\/h3>\n\n<p class=\"wp-block-paragraph\">Whenever you get a 400 HTTP status code returned, it means that your payload or formatting was incorrect. For example, Mailgun will respond with a 400 HTTP status code if a required field is missing.<\/p>\n\n<p class=\"wp-block-paragraph\">In these cases, there&#8217;s a general approach that you can take:<\/p>\n\n<ul class=\"wp-block-list\">\n<li>Throw an exception, as this is a failure scenario that&#8217;s not recoverable.<\/li>\n\n\n\n<li>Log the exception and the reasons for the exception.<\/li>\n<\/ul>\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what the code for this could look like:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    if (!result.IsSuccessStatusCode)rn{rn    var status = (int) result.StatusCode;rnrn    if (status == 400)rn    {rn        var responseContent = await result.Content.ReadAsStringAsync();rn        var exception = new BadHttpRequestException(&quot;Mailgun 400 HTTP status code&quot;);rnrn        this._logger.LogError(exception, exception.Message, responseContent);rn        throw exception;rn    }rn}rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">You may also want to take a similar approach with the 401 HTTP status code.<\/p>\n\n<h3 class=\"wp-block-heading\">Handle 500 error codes<\/h3>\n\n<p class=\"wp-block-paragraph\">Whenever you receive a 500 HTTP status code, it may mean something has gone wrong on Mailgun&#8217;s side or a general network issue was experienced. In these cases, there are a few different approaches you could take:<\/p>\n\n<ul class=\"wp-block-list\">\n<li>Queue the email to be attempted again later.<\/li>\n\n\n\n<li>In the same code path, retry after a short period.<\/li>\n\n\n\n<li>Employ an advanced technique like a <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/architecture\/patterns\/circuit-breaker\" target=\"_tabs\" rel=\"noopener noreferrer\">circuit breaker<\/a><\/li>\n<\/ul>\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what a basic retry approach might look like:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    if (!result.IsSuccessStatusCode)rn{rn    var status = (int) result.StatusCode;rnrn    if (status == 500)rn    {rn        \/\/ Retry the email after 1 second in hopes that the error was transientrnrn        await Task.Delay(1000);rn        result = await _httpClient.PostAsync(string.Empty, form);rnrn        if (!result.IsSuccessStatusCode)rn        {rn            \/\/ Log and throw an exception like you did in the previous examplern        }rn    }rn}rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">In this scenario, if you receive a 500 status code, you&#8217;ll wait for one second and try the HTTP request again. If the retried request also has a failure, then you&#8217;ll log and throw an exception in the same way that you did for the 400 status code scenario.<\/p>\n\n<p class=\"wp-block-paragraph\">To give you an idea of what the overall code might look like, here&#8217;s a skeleton of how your code could begin to handle various error scenarios:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    if (!result.IsSuccessStatusCode)rn{rn    var status = (int)result.StatusCode;rnrn    if (status == 400)rn    {rn        \/\/ Log the error and notify the development team that thern        \/\/ request was not formatted properly.rn    }rn    else if (status == 401)rn    {rn        \/\/ Log the error and notify the development team that thern        \/\/ request&#039;s authentication failed.rn    }rn    else if (status == 429)rn    {rn        \/\/ Use a .NET library like Polly to throttle or try this requestrn        \/\/ again with an exponential back-off, etc.rn    }rn    elsern    {rn        \/\/ Something went wrong: log the error and apply a distributed rn        \/\/ error handling technique like a circuit breaker.rn        \/\/ See https:\/\/learn.microsoft.com\/en-us\/azure\/architecture\/patterns\/circuit-breaker for more.rn    }rn}rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<h2 class=\"wp-block-heading\">Production-ready email integration<\/h2>\n\n<p class=\"wp-block-paragraph\">At this point, you&#8217;ve sent an email with .NET and C#, but to get production ready, there are a few important things to consider.<\/p>\n\n<h3 class=\"wp-block-heading\">Secure your API key<\/h3>\n\n<p class=\"wp-block-paragraph\"><b>You <\/b><b><i>cannot<\/i><\/b><b> store your real production API key in source code<\/b>. Additionally, it should not be accessible by anyone in plain text files.<\/p>\n\n<p class=\"wp-block-paragraph\">There are many tools you can use to secure your API key. Every cloud provider has its own key management system that allows your application to retrieve your secrets securely. For example, <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/key-vault\/general\/overview\" target=\"_tabs\" rel=\"noopener noreferrer\">Azure Key Vault<\/a> or <a href=\"https:\/\/docs.aws.amazon.com\/secretsmanager\/latest\/userguide\/intro.html\" target=\"_tabs\" rel=\"noopener noreferrer\">AWS Secrets Manager<\/a> work great.<\/p>\n\n<h3 class=\"wp-block-heading\">Other production-grade features<\/h3>\n\n<p class=\"wp-block-paragraph\">Mailgun also supports many production-grade features you may need, such as:<\/p>\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/documentation.mailgun.com\/docs\/mailgun\/user-manual\/sending-messages\/#send-with-attachments\" target=\"_tabs\" rel=\"noopener noreferrer\">Adding attachments<\/a> to your emails<\/li>\n\n\n\n<li>The ability to <a href=\"https:\/\/documentation.mailgun.com\/docs\/mailgun\/user-manual\/sending-messages\/#templates\" target=\"_tabs\" rel=\"noopener noreferrer\">create reusable email templates<\/a><\/li>\n\n\n\n<li>Personalization features like <a href=\"https:\/\/documentation.mailgun.com\/docs\/mailgun\/api-reference\/openapi-final\/tag\/Messages\/#tag\/Messages\/operation\/httpapi.(*apiHandler).handler-fm-19!path=o:tag&amp;t=request\" target=\"_tabs\" rel=\"noopener noreferrer\">variables and tags<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/documentation.mailgun.com\/docs\/mailgun\/api-reference\/openapi-final\/tag\/Messages\/#tag\/Messages\/operation\/httpapi.(*apiHandler).handler-fm-19!path=cc&amp;t=request\" target=\"_tabs\" rel=\"noopener noreferrer\">CC, BCC, and reply-to headers<\/a><\/li>\n<\/ul>\n\n<h3 class=\"wp-block-heading\">Integrate with the .NET ecosystem<\/h3>\n\n<p class=\"wp-block-paragraph\">To demonstrate how easy it is to integrate with production-ready tooling from the .NET ecosystem, go ahead and use an open source library like <a href=\"https:\/\/github.com\/jamesmh\/coravel\/\" target=\"_tabs\" rel=\"noopener noreferrer\">Coravel<\/a> to enhance the reuse and developer experience of your solution.<\/p>\n\n<p class=\"wp-block-paragraph\">Execute dotnet add package coravel.mailer from your terminal while in the MailDemo folder.<\/p>\n\n<p class=\"wp-block-paragraph\">Then, add the following JSON entry to your appsettings.json file:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    &quot;Coravel&quot;: {rn    &quot;Mail&quot;: {rn        &quot;From&quot;: {rn            &quot;Name&quot;: &quot;Test User&quot;,rn            &quot;Email&quot;: &quot;postmaster@&lt;Your sandbox domain&gt;&quot;rn        }rn    }rn}rnNext, create a class file called MailgunMailer.cs that implements the ICanSendMail interface. You might notice that this is essentially the same logic you originally had in OrderController:rnusing System.Net.Mime;rnusing System.Text;rnusing Coravel.Mailer.Mail;rnrnnamespace MailDemo;rnrnpublic class MailgunMailer : ICanSendMailrn{rn    private readonly HttpClient _httpClient;rn    private readonly IConfiguration _config;rnrn    public MailgunMailer(IHttpClientFactory httpClientFactory, IConfiguration config)rn    {rn        this._httpClient = httpClientFactory.CreateClient(&quot;Mailgun&quot;);rn        this._config = config;rn    }rnrn    public async Task SendAsync(MessageBody message, string subject, IEnumerable&lt;MailRecipient&gt; to, MailRecipient from, MailRecipient replyTo, IEnumerable&lt;MailRecipient&gt; cc, IEnumerable&lt;MailRecipient&gt; bcc, IEnumerable&lt;Attachment&gt;? attachments = null, MailRecipient? sender = null)rn    {rn        using MultipartFormDataContent form = new();rnrn        void SetFormParam(string key, string value) =&gt;rn        form.Add(new StringContent(value, Encoding.UTF8, MediaTypeNames.Text.Plain), key);rnrn        if (from is not null)rn        {rn            SetFormParam(&quot;from&quot;, $&quot;{from.Name} &lt;{from.Email}&gt;&quot;);rn        }rn        elsern        {rn            \/\/ This gives you a default &quot;from&quot; field if not defined by the callerrn            SetFormParam(&quot;from&quot;, $&quot;{this._config.GetValue&lt;string&gt;(&quot;Coravel:Mail:From:Name&quot;)} &lt;{this._config.GetValue&lt;string&gt;(&quot;Coravel:Mail:From:Email&quot;)}&gt;&quot;);rn        }rnrn        foreach (var recipient in to)rn        {rn            SetFormParam(&quot;to&quot;, recipient.Email);rn        }rn        SetFormParam(&quot;subject&quot;, subject);rnrn        if (message.HasHtmlMessage())rn        {rn            SetFormParam(&quot;html&quot;, message.Html);rn        }rnrn        if (message.HasPlainTextMessage())rn        {rn            SetFormParam(&quot;text&quot;, message.Text);rn        }rnrn        var result = await _httpClient.PostAsync(string.Empty, form);rnrn        \/\/ Error handling logic...rn    }rn}rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">Next, you need to tell Coravel to use this mailer. In your Program.cs file, before var app = builder.Build() is called, add the following:<\/p>\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                C#                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-csharp\">\r\n                                <code id=\"code_0_content\" class=\"language-csharp\">\r\n\r\n                                    builder.Services.AddScoped&lt;MailDemo.MailgunMailer&gt;();rnbuilder.AddCustomMailer&lt;MailDemo.MailgunMailer&gt;();rnFinally, replace the code for OrderController with the following:rnusing Microsoft.AspNetCore.Mvc;rnusing Coravel.Mailer.Mail.Interfaces;rnusing Coravel.Mailer.Mail;rnrnnamespace MailDemo.Controllers;rnrnpublic class OrderController : Controllerrn{rn    private readonly IMailer _mailer;rnrn    public OrderController(IMailer mailer)rn    {rn        this._mailer = mailer;rn    }rnrn    public async Task&lt;IActionResult&gt; Confirm()rn    {rn        var mailable = Mailable.AsInline()rn            .To(&quot;jamesmichaelhickey@gmail.com&quot;)rn            .Subject(&quot;Hello World!&quot;)rn            .Html(@&quot;&lt;html&gt;&lt;body&gt;&lt;p style=&quot;&quot;color:blue;&quot;&quot;&gt;My first transactional email!&lt;\/p&gt;&lt;\/body&gt;&lt;\/html&gt;&quot;)rn            .Text(&quot;My first transactional email!&quot;);rnrn        await _mailer.SendAsync(mailable);rnrn        return new JsonResult(@&quot;Your order was confirmed. You should get an email soon!&quot;);rn    }rn}rn\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n<p class=\"wp-block-paragraph\">After a little bit of a one-time configuration, you&#8217;ll notice the logic for sending emails from your application code is much easier to understand and less verbose.<\/p>\n\n<p class=\"wp-block-paragraph\">You&#8217;ve also added support through Mailgun and Coravel to define both HTML and plain text email bodies. Mailgun recommends <a href=\"https:\/\/documentation.mailgun.com\/docs\/mailgun\/email-best-practices\/email_content\/\" target=\"_tabs\" rel=\"noopener noreferrer\">sending both HTML and plain text together<\/a>. It&#8217;s best to send multipart emails using both text and HTML, or text only. Sending HTML-only email is not well received by ESPs.<\/p>\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> Mailgun and Coravel also support other features like CC, BCC, and attachments for more production-grade transactional emails.<\/div>\r\n    <\/div>\r\n\n<h2 class=\"wp-block-heading\">Wrapping up<\/h2>\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.mailgun.com\/pt\/\" target=\"_tabs\" rel=\"noopener noreferrer\">Mailgun<\/a> offers a straightforward <a href=\"https:\/\/www.mailgun.com\/pt\/empresarial\/api-de-e-mail\/\" target=\"_tabs\" rel=\"noopener noreferrer\">HTTP API<\/a> to send emails from your .NET solutions efficiently and securely. In this article, you learned how to integrate Mailgun&#8217;s HTTP API into a C# web application and begin adding production-grade tooling along with Mailgun&#8217;s production-ready capabilities.<\/p>\n\n<p class=\"wp-block-paragraph\">By using Mailgun and .NET together, your transactional emails can scale efficiently with <a href=\"https:\/\/ardalis.com\/better-performance-from-async-operations\/\" target=\"_tabs\" rel=\"noopener noreferrer\">.NET async\/await functionality<\/a>, the framework&#8217;s overall <a href=\"https:\/\/www.techempower.com\/benchmarks\/#section=data-r21&amp;hw=ph&amp;test=composite\" target=\"_tabs\" rel=\"noopener noreferrer\">high-performance web infrastructure<\/a>, <a href=\"https:\/\/github.com\/jamesmh\/coravel\" target=\"_tabs\" rel=\"noopener noreferrer\">additional tooling<\/a> from the .NET ecosystem, and Mailgun&#8217;s performant and straightforward HTTP API.<\/p>\n\n<p class=\"wp-block-paragraph\">Was this helpful? Subscribe to our newsletter to get updates on tutorials, emails news, and insights from our resident email geeks.<\/p>\n\r\n    <aside data-content-type=\"longform\"  class=\"banner-block longform-spacings rounded-lg shadow-lg px-5 py-6 px-md-6 py-md-7 p-lg-7 bg-light\" data-theme=\"dark\" aria-labelledby=\"banner-block-block_4bcb728e1840f3b90dcd79b8130e2b76\">\r\n                    <p class=\"text-uppercase section-caption text-body-color\">\r\n                Sign Up            <\/p>\r\n                            <p class=\"h4 text-accent fw-bold\" id=\"banner-block-block_4bcb728e1840f3b90dcd79b8130e2b76\">\r\n                It&#8217;s easy to get started. And it&#8217;s free.            <\/p>\r\n                            <div class=\"mb-0 text-body-color\">\r\n                                    <div class=\"content-body mb-0 text-body-color\">See what you can accomplish with the world\u2019s best email delivery platform.<\/div>\r\n                            <\/div>\r\n        \r\n        <div class=\"text-start mt-5\"><a href=\"https:\/\/signup.mailgun.com\/new\/signup\"  class=\"btn btn-secondary\" >Get started<\/a><\/div>\r\n    <\/aside>\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Domine o envio de e-mail transacional com a API HTTP do Mailgun em C#. Este guia mostra como configurar uma conta do Mailgun, integrar com .NET e lidar com erros para uma entrega de e-mail pronta para produ\u00e7\u00e3o.<\/p>\n","protected":false},"author":18,"featured_media":3952,"menu_order":0,"template":"","meta":{"_acf_changed":false,"footnotes":""},"blog_category":[19],"class_list":["post-20114","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog_category-dev-life"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Enviar e-mails em C# usando a API do Mailgun: guia passo a passo - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"Aprenda a enviar e-mail usando a API do Mailgun e C# para uma entrega de e-mail confi\u00e1vel. Instru\u00e7\u00f5es passo a passo para configura\u00e7\u00e3o, tratamento de erros e prepara\u00e7\u00e3o para produ\u00e7\u00e3o.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Enviar e-mails em C# usando a API do Mailgun: guia passo a passo - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"Aprenda a enviar e-mail usando a API do Mailgun e C# para uma entrega de e-mail confi\u00e1vel. Instru\u00e7\u00f5es passo a passo para configura\u00e7\u00e3o, tratamento de erros e prepara\u00e7\u00e3o para produ\u00e7\u00e3o.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/\" \/>\n<meta property=\"og:site_name\" content=\"Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-14T23:33:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"448\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/\",\"name\":\"Enviar e-mails em C# usando a API do Mailgun: guia passo a passo - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Dev-Life.png\",\"datePublished\":\"2024-12-11T00:00:00+00:00\",\"dateModified\":\"2026-09-14T23:33:34+00:00\",\"description\":\"Aprenda a enviar e-mail usando a API do Mailgun e C# para uma entrega de e-mail confi\u00e1vel. Instru\u00e7\u00f5es passo a passo para configura\u00e7\u00e3o, tratamento de erros e prepara\u00e7\u00e3o para produ\u00e7\u00e3o.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Dev-Life.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Dev-Life.png\",\"width\":720,\"height\":448},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/send-email-with-c-sharp\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/inicio\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enviando e-mail usando C# e a API do Mailgun\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"description\":\"Poderosas APIs de e-mail transacional que permitem a voc\u00ea enviar, receber e rastrear e-mails, criadas com os desenvolvedores em mente. Saiba mais hoje mesmo!\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"width\":512,\"height\":512,\"caption\":\"Transactional Email API Service For Developers | Mailgun\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Enviar e-mails em C# usando a API do Mailgun: guia passo a passo - Transactional Email API Service For Developers | Mailgun","description":"Aprenda a enviar e-mail usando a API do Mailgun e C# para uma entrega de e-mail confi\u00e1vel. Instru\u00e7\u00f5es passo a passo para configura\u00e7\u00e3o, tratamento de erros e prepara\u00e7\u00e3o para produ\u00e7\u00e3o.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/","og_locale":"pt_BR","og_type":"article","og_title":"Enviar e-mails em C# usando a API do Mailgun: guia passo a passo - Transactional Email API Service For Developers | Mailgun","og_description":"Aprenda a enviar e-mail usando a API do Mailgun e C# para uma entrega de e-mail confi\u00e1vel. Instru\u00e7\u00f5es passo a passo para configura\u00e7\u00e3o, tratamento de erros e prepara\u00e7\u00e3o para produ\u00e7\u00e3o.","og_url":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/","og_site_name":"Transactional Email API Service For Developers | Mailgun","article_modified_time":"2026-09-14T23:33:34+00:00","og_image":[{"width":720,"height":448,"url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/","url":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/","name":"Enviar e-mails em C# usando a API do Mailgun: guia passo a passo - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/pt\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","datePublished":"2024-12-11T00:00:00+00:00","dateModified":"2026-09-14T23:33:34+00:00","description":"Aprenda a enviar e-mail usando a API do Mailgun e C# para uma entrega de e-mail confi\u00e1vel. Instru\u00e7\u00f5es passo a passo para configura\u00e7\u00e3o, tratamento de erros e prepara\u00e7\u00e3o para produ\u00e7\u00e3o.","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/#primaryimage","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","width":720,"height":448},{"@type":"BreadcrumbList","@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/send-email-with-c-sharp\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/pt\/inicio\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/pt\/blog\/"},{"@type":"ListItem","position":3,"name":"Enviando e-mail usando C# e a API do Mailgun"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/pt\/#website","url":"https:\/\/www.mailgun.com\/pt\/","name":"Transactional Email API Service For Developers | Mailgun","description":"Poderosas APIs de e-mail transacional que permitem a voc\u00ea enviar, receber e rastrear e-mails, criadas com os desenvolvedores em mente. Saiba mais hoje mesmo!","publisher":{"@id":"https:\/\/www.mailgun.com\/pt\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/pt\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/pt\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/pt\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.mailgun.com\/pt\/#\/schema\/logo\/image\/","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","width":512,"height":512,"caption":"Transactional Email API Service For Developers | Mailgun"},"image":{"@id":"https:\/\/www.mailgun.com\/pt\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/20114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/users\/18"}],"version-history":[{"count":3,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/20114\/revisions"}],"predecessor-version":[{"id":20269,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/20114\/revisions\/20269"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/media\/3952"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/media?parent=20114"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog_category?post=20114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}