> ## Documentation Index
> Fetch the complete documentation index at: https://ahasend.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> AhaSend stores all message data in the EU. See /facts.
> The API base URL is https://api.ahasend.com. Send the API key in the Authorization: Bearer header. See /api-reference/authentication.
> Use send.ahasend.com for SMTP in the EU, or send-us.ahasend.com as a US connection point forwarding to the EU. Ports 25, 587 and 2525 use STARTTLS. Port 465 is not supported. See /smtp.
> For send-only integrations, create an API Key v2 under Credentials → Add and scope it to messages:send:{your-domain}. See /send-api/credentials and /api-reference/scopes.

# Send Email in C# via SMTP (MailKit)

> Send email from C# and .NET through AhaSend's SMTP relay with MailKit, and why System.Net.Mail SmtpClient fails AUTH over STARTTLS. HTML, attachments, headers.

Send emails through AhaSend's SMTP servers using C# and .NET with the powerful MailKit library. This guide covers why you should avoid `System.Net.Mail` and use MailKit instead for reliable email delivery.

<Warning>
  **Avoid System.Net.Mail:** The built-in `SmtpClient` in .NET does not reliably support `AUTH PLAIN` over `STARTTLS`, causing authentication failures with AhaSend. Use MailKit instead for guaranteed compatibility.
</Warning>

## Prerequisites

Before sending, [verify your domain](/docs/domains) and [create an SMTP credential](/docs/smtp/credentials). Use a [sandbox credential](/docs/send-api/sandbox) for these examples so no email is delivered. Keep the username and password in your server's secret store.

Before you begin, ensure you have:

<AccordionGroup>
  <Accordion title="Development Environment" icon="desktop">
    * **.NET SDK** installed (.NET 6.0 or higher recommended)
    * **Visual Studio** or **Visual Studio Code** for development
    * **NuGet package manager** access
    * Basic knowledge of C# programming
  </Accordion>

  <Accordion title="Project Dependencies" icon="code-fork">
    * **MailKit** NuGet package (recommended)
    * **MimeKit** (included with MailKit)
    * Avoid using `System.Net.Mail` for PLAIN AUTH over STARTTLS
  </Accordion>
</AccordionGroup>

## Why MailKit Over System.Net.Mail?

AhaSend works with any SMTP-compatible library, but for C#/.NET applications, we strongly recommend MailKit over the built-in `System.Net.Mail`:

<CardGroup cols={2}>
  <Card title="✅ MailKit (Recommended)">
    **Pros:** Modern, reliable STARTTLS<br />
    **Auth:** AUTH PLAIN/LOGIN support<br />
    **Compatibility:** Works with StartTLS<br />
    **Features:** Rich MIME support, attachments, HTML
  </Card>

  <Card title="❌ System.Net.Mail (Avoid)">
    **Issues:** Unreliable STARTTLS authentication<br />
    **Auth:** Silent AUTH failures with AhaSend<br />
    **Status:** Legacy, minimal updates<br />
    **Problems:** May not send AUTH commands at all
  </Card>
</CardGroup>

## Connection Settings

| Setting | Value |
| - | - |
| EU host | `send.ahasend.com` |
| US connection point | `send-us.ahasend.com`; accepts SMTP and forwards it to the EU |
| Ports | 25, 587 and 2525 |
| Encryption | STARTTLS required on every supported port |
| Authentication | AUTH PLAIN only after STARTTLS |
| Username and password | Your SMTP credential, not an API key |
| Port 465 | Implicit TLS is not supported |

All message data is stored in the EU. See [SMTP limits](/docs/smtp#what-are-the-smtp-limits).

## Why System.Net.Mail Fails

The built-in `System.Net.Mail.SmtpClient` in .NET has fundamental issues with STARTTLS authentication that make it incompatible with AhaSend.

### The Problem

Even with correct credentials and `EnableSsl = true`, the SMTP client often never issues an `AUTH` command after the STARTTLS handshake. This causes silent authentication failures where the connection appears to succeed but emails are rejected.

<Warning>
  **Tested and Confirmed:** We've tested this issue on .NET 9 across Linux and Windows. The problem persists across different .NET versions and platforms.
</Warning>

### What Doesn't Work

Here's the problematic code that fails with AhaSend:

```csharp System.Net.Mail (Don't Use This) theme={null}
using System;
using System.Net;
using System.Net.Mail;

class Program
{
    static void Main(string[] args)
    {
        SmtpClient smtp = new SmtpClient("send.ahasend.com", 587);

        // Enable StartTLS
        smtp.EnableSsl = true;

        // Don't use the OS/Windows account. We want to supply our own credentials.
        smtp.UseDefaultCredentials = false;
        smtp.Credentials = new NetworkCredential("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

        MailMessage message = new MailMessage("hello@yourdomain.com", "user@example.com");
        message.Subject = "Testing Auth";
        message.Body = "This is a test email via AUTH PLAIN.";

        try
        {
            smtp.Send(message);
            Console.WriteLine("Email sent successfully.");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error sending email: " + ex.Message);
            if (ex.InnerException != null)
            {
                Console.WriteLine("Inner Exception: " + ex.InnerException.Message);
            }
        }
    }
}
```

### Debugging the Issue

You can confirm this authentication failure by capturing SMTP traffic with tools like `tcpdump` or `Wireshark`:

1. **Connection succeeds** - Client connects to AhaSend SMTP server
2. **STARTTLS works** - TLS encryption is established successfully
3. **AUTH command missing** - Client never sends authentication credentials
4. **Silent failure** - No clear error message, just rejection

<Info>
  **Know a Workaround?** If you've found a way to make `System.Net.Mail` work reliably with AhaSend's AUTH PLAIN over STARTTLS, please [contact our support team](mailto:support@ahasend.com). We'd be happy to update this guide with your solution!
</Info>

## Use MailKit (Recommended)

MailKit is a modern, actively maintained .NET library that correctly handles SMTP authentication with AhaSend. It properly negotiates authentication mechanisms like `PLAIN` and `LOGIN` over `STARTTLS`.

### Installation

Install MailKit via NuGet Package Manager:

<CodeGroup>
  ```bash Package Manager Console theme={null}
  Install-Package MailKit
  ```

  ```bash .NET CLI theme={null}
  dotnet add package MailKit
  ```

  Use the exact version installed by `dotnet add package MailKit` in your project file:

  ```xml PackageReference theme={null}
  <PackageReference Include="MailKit" Version="YOUR_INSTALLED_VERSION" />
  ```

  ```text Package Manager UI theme={null}
  Search for "MailKit" by Jeffrey Stedfast in NuGet Package Manager
  ```
</CodeGroup>

<Info>
  **MimeKit Included:** MailKit automatically includes MimeKit for MIME message construction. No additional packages needed!
</Info>

### Basic MailKit Examples

<CodeGroup>
  ```csharp Plain Text Email theme={null}
  using System;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect to AhaSend SMTP with STARTTLS
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);

                  // Authenticate with your SMTP credentials
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  // Create a simple message
                  var message = new MimeMessage();
                  message.From.Add(new MailboxAddress("Your Company", "hello@yourdomain.com"));
                  message.To.Add(new MailboxAddress("User", "user@example.com"));
                  message.Subject = "Welcome to our platform!";
                  message.Body = new TextPart("plain")
                  {
                      Text = "Thanks for signing up. We're excited to have you!"
                  };

                  client.Send(message);
                  client.Disconnect(true);

                  Console.WriteLine("Email sent successfully!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to send email: {ex.Message}");
              }
          }
      }
  }
  ```

  ```csharp HTML Email theme={null}
  using System;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect to AhaSend SMTP with STARTTLS
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);

                  // Authenticate with your SMTP credentials
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  // Create an HTML message
                  var message = new MimeMessage();
                  message.From.Add(new MailboxAddress("Your Company", "hello@yourdomain.com"));
                  message.To.Add(new MailboxAddress("User", "user@example.com"));
                  message.Subject = "Welcome to our platform!";

                  var builder = new BodyBuilder();

                  // Set the plain-text version of the message text
                  builder.TextBody = "Welcome! Thanks for signing up. Visit https://yourdomain.com/get-started to get started.";

                  // Set the html version of the message text
                  builder.HtmlBody = @"
                      <html>
                      <body>
                          <h1>Welcome!</h1>
                          <p>Thanks for signing up. We're <strong>excited</strong> to have you!</p>
                          <p><a href=""https://yourdomain.com/get-started"">Get Started</a></p>
                      </body>
                      </html>";

                  message.Body = builder.ToMessageBody();

                  client.Send(message);
                  client.Disconnect(true);

                  Console.WriteLine("HTML email sent successfully!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to send email: {ex.Message}");
              }
          }
      }
  }
  ```

  ```csharp Email with Attachments theme={null}
  using System;
  using System.IO;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect to AhaSend SMTP with STARTTLS
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);

                  // Authenticate with your SMTP credentials
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  // Create message with attachment
                  var message = new MimeMessage();
                  message.From.Add(new MailboxAddress("Your Company", "hello@yourdomain.com"));
                  message.To.Add(new MailboxAddress("User", "user@example.com"));
                  message.Subject = "Your Invoice is Ready";

                  var builder = new BodyBuilder();

                  // Set the message body
                  builder.TextBody = "Please find your invoice attached to this email.";
                  builder.HtmlBody = @"
                      <html>
                      <body>
                          <h1>Invoice Attached</h1>
                          <p>Please find your invoice attached to this email.</p>
                      </body>
                      </html>";

                  // Add attachment
                  string attachmentPath = @"C:\path\to\invoice.pdf";
                  if (File.Exists(attachmentPath))
                  {
                      builder.Attachments.Add(attachmentPath);
                  }

                  message.Body = builder.ToMessageBody();

                  client.Send(message);
                  client.Disconnect(true);

                  Console.WriteLine("Email with attachment sent successfully!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to send email: {ex.Message}");
              }
          }
      }
  }
  ```
</CodeGroup>

### Advanced MailKit Examples

<CodeGroup>
  ```csharp Multiple Recipients & Special Headers theme={null}
  using System;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect to AhaSend SMTP with STARTTLS
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);

                  // Authenticate with your SMTP credentials
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  // Create message with multiple recipients
                  var message = new MimeMessage();
                  message.From.Add(new MailboxAddress("Your Company", "updates@yourdomain.com"));

                  // Add multiple recipients
                  message.To.Add(new MailboxAddress("User One", "user1@example.com"));
                  message.To.Add(new MailboxAddress("User Two", "user2@example.com"));

                  // Add CC recipient
                  message.Cc.Add(new MailboxAddress("Manager", "manager@yourdomain.com"));

                  // Add BCC recipient (not visible to other recipients)
                  message.Bcc.Add(new MailboxAddress("Analytics", "analytics@yourdomain.com"));

                  message.Subject = "Product Updates with Tracking";

                  // Add AhaSend special headers
                  message.Headers.Add("ahasend-track-opens", "true");
                  message.Headers.Add("ahasend-track-clicks", "true");
                  message.Headers.Add("ahasend-tags", "product-update,newsletter,csharp");
                  message.Headers.Add("AhaSend-Metadata-Retention", "30");
                  message.Headers.Add("AhaSend-Data-Retention", "7");

                  var builder = new BodyBuilder();
                  builder.TextBody = "Check out our latest features at https://yourdomain.com/features";
                  builder.HtmlBody = @"
                      <html>
                      <body>
                          <h1>Product Updates</h1>
                          <p>Check out our <a href=""https://yourdomain.com/features"">latest features</a>!</p>
                          <p>This email has tracking enabled and custom tags.</p>
                      </body>
                      </html>";

                  message.Body = builder.ToMessageBody();

                  client.Send(message);
                  client.Disconnect(true);

                  Console.WriteLine("Email sent with special headers!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to send email: {ex.Message}");
              }
          }
      }
  }
  ```

  ```csharp Bulk Email Sending theme={null}
  using System;
  using System.Collections.Generic;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          // Recipients list
          var recipients = new List<(string Email, string Name)>
          {
              ("user1@example.com", "John Doe"),
              ("user2@example.com", "Jane Smith"),
              ("user3@example.com", "Bob Johnson")
          };

          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect once for all emails
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  foreach (var recipient in recipients)
                  {
                      try
                      {
                          var message = new MimeMessage();
                          message.From.Add(new MailboxAddress("Your Company", "hello@yourdomain.com"));
                          message.To.Add(new MailboxAddress(recipient.Name, recipient.Email));
                          message.Subject = "Personalized Newsletter";

                          // Add custom header for bulk emails
                          message.Headers.Add("ahasend-tags", "newsletter,bulk,csharp");

                          var builder = new BodyBuilder();
                          builder.TextBody = $"Hello {recipient.Name}! This is your personalized newsletter.";
                          builder.HtmlBody = $@"
                              <html>
                              <body>
                                  <h1>Hello {recipient.Name}!</h1>
                                  <p>This is your personalized newsletter.</p>
                              </body>
                              </html>";

                          message.Body = builder.ToMessageBody();

                          client.Send(message);
                          Console.WriteLine($"Email sent to {recipient.Email}");

                          // Add delay to avoid rate limiting
                          System.Threading.Thread.Sleep(100);
                      }
                      catch (Exception ex)
                      {
                          Console.WriteLine($"Failed to send to {recipient.Email}: {ex.Message}");
                      }
                  }

                  client.Disconnect(true);
                  Console.WriteLine("Bulk email sending completed!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to connect to SMTP server: {ex.Message}");
              }
          }
      }
  }
  ```

  ```csharp Email Service Class theme={null}
  using System;
  using System.Threading.Tasks;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  public class EmailService
  {
      private readonly string _smtpHost;
      private readonly int _smtpPort;
      private readonly string _smtpUsername;
      private readonly string _smtpPassword;

      public EmailService(string smtpHost, int smtpPort, string smtpUsername, string smtpPassword)
      {
          _smtpHost = smtpHost;
          _smtpPort = smtpPort;
          _smtpUsername = smtpUsername;
          _smtpPassword = smtpPassword;
      }

      public async Task<bool> SendEmailAsync(string fromEmail, string fromName, string toEmail, string toName,
                                            string subject, string textBody, string htmlBody = null)
      {
          try
          {
              using var client = new SmtpClient();

              // Connect to AhaSend SMTP with STARTTLS
              await client.ConnectAsync(_smtpHost, _smtpPort, SecureSocketOptions.StartTls);

              // Authenticate with your SMTP credentials
              await client.AuthenticateAsync(_smtpUsername, _smtpPassword);

              // Create message
              var message = new MimeMessage();
              message.From.Add(new MailboxAddress(fromName, fromEmail));
              message.To.Add(new MailboxAddress(toName, toEmail));
              message.Subject = subject;

              var builder = new BodyBuilder();
              builder.TextBody = textBody;

              if (!string.IsNullOrEmpty(htmlBody))
              {
                  builder.HtmlBody = htmlBody;
              }

              message.Body = builder.ToMessageBody();

              await client.SendAsync(message);
              await client.DisconnectAsync(true);

              return true;
          }
          catch (Exception ex)
          {
              Console.WriteLine($"Failed to send email: {ex.Message}");
              return false;
          }
      }

      public async Task<bool> SendWelcomeEmailAsync(string toEmail, string toName)
      {
          var subject = "Welcome to our platform!";
          var textBody = $"Hello {toName}, welcome to our platform!";
          var htmlBody = $@"
              <html>
              <body>
                  <h1>Welcome {toName}!</h1>
                  <p>Thanks for joining our platform. We're excited to have you!</p>
              </body>
              </html>";

          return await SendEmailAsync("hello@yourdomain.com", "Your Company",
                                     toEmail, toName, subject, textBody, htmlBody);
      }
  }

  // Usage example
  class Program
  {
      static async Task Main(string[] args)
      {
          var emailService = new EmailService(
              "send.ahasend.com",
              587,
              "YOUR_SMTP_USERNAME",
              "YOUR_SMTP_PASSWORD"
          );

          // Send welcome email
          bool success = await emailService.SendWelcomeEmailAsync("user@example.com", "John Doe");

          if (success)
          {
              Console.WriteLine("Welcome email sent successfully!");
          }
          else
          {
              Console.WriteLine("Failed to send welcome email.");
          }
      }
  }
  ```
</CodeGroup>

## Testing with Sandbox Mode

Use sandbox mode to safely test your C# email integration:

<CodeGroup>
  ```csharp Sandbox Test theme={null}
  using System;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect to AhaSend SMTP with STARTTLS
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);

                  // Authenticate with your SMTP credentials
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  // Create sandbox test message
                  var message = new MimeMessage();
                  message.From.Add(new MailboxAddress("Test", "test@yourdomain.com"));
                  message.To.Add(new MailboxAddress("Test User", "test@example.com"));
                  message.Subject = "Sandbox Test Email";

                  // Enable sandbox mode
                  message.Headers.Add("AhaSend-Sandbox", "true");
                  message.Headers.Add("AhaSend-Sandbox-Result", "deliver");

                  message.Body = new TextPart("plain")
                  {
                      Text = "This email is sent in sandbox mode for testing."
                  };

                  client.Send(message);
                  client.Disconnect(true);

                  Console.WriteLine("Sandbox email sent successfully!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to send sandbox email: {ex.Message}");
              }
          }
      }
  }
  ```

  ```csharp Sandbox Bounce Test theme={null}
  using System;
  using MailKit.Net.Smtp;
  using MailKit.Security;
  using MimeKit;

  class Program
  {
      static void Main()
      {
          using (var client = new SmtpClient())
          {
              try
              {
                  // Connect to AhaSend SMTP with STARTTLS
                  client.Connect("send.ahasend.com", 587, SecureSocketOptions.StartTls);

                  // Authenticate with your SMTP credentials
                  client.Authenticate("YOUR_SMTP_USERNAME", "YOUR_SMTP_PASSWORD");

                  // Create sandbox bounce test message
                  var message = new MimeMessage();
                  message.From.Add(new MailboxAddress("Test", "test@yourdomain.com"));
                  message.To.Add(new MailboxAddress("Test User", "test@example.com"));
                  message.Subject = "Sandbox Bounce Test";

                  // Enable sandbox mode with bounce simulation
                  message.Headers.Add("AhaSend-Sandbox", "true");
                  message.Headers.Add("AhaSend-Sandbox-Result", "bounce");

                  var builder = new BodyBuilder();
                  builder.TextBody = "This email simulates a bounce for webhook testing.";
                  builder.HtmlBody = @"
                      <html>
                      <body>
                          <h1>Bounce Test</h1>
                          <p>This email simulates a bounce for webhook testing.</p>
                      </body>
                      </html>";

                  message.Body = builder.ToMessageBody();

                  client.Send(message);
                  client.Disconnect(true);

                  Console.WriteLine("Sandbox bounce test sent - check webhooks!");
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Failed to send sandbox email: {ex.Message}");
              }
          }
      }
  }
  ```
</CodeGroup>

<Info>
  **Sandbox Benefits:** Emails sent in sandbox mode are free, trigger webhooks normally, and never actually deliver to recipients - perfect for development and testing.
</Info>

## Resources

<CardGroup cols={2}>
  <Card title="MailKit Documentation" icon="book" href="https://www.mimekit.net/docs/">
    Official MailKit and MimeKit documentation
  </Card>

  <Card title="Microsoft .NET Docs" icon="book" href="https://docs.microsoft.com/en-us/dotnet/">
    Comprehensive .NET development guide
  </Card>

  <Card title="MailKit GitHub" icon="code" href="https://github.com/jstedfast/MailKit">
    Source code, examples, and issue tracking
  </Card>

  <Card title="AhaSend Support" icon="life-ring" href="mailto:support@ahasend.com">
    Get help from our engineering team
  </Card>
</CardGroup>

<Tip>
  **Pro Tip:** Always use MailKit instead of System.Net.Mail for AhaSend integration. Configure your SMTP settings through dependency injection, implement proper error handling with retry logic, and start with sandbox mode during development. Use async patterns for better performance in web applications.
</Tip>

## Related Guides

* Before sending: [verify your domain](/docs/domains) and [create an SMTP credential](/docs/smtp/credentials).
* Connection and message rules: [SMTP hosts, ports and limits](/docs/smtp), [special headers](/docs/smtp/special-headers), [sandbox mode](/docs/send-api/sandbox), [retention](/docs/retention) and [plan features](/docs/facts#plans-and-features).
* Other ways to send: [REST API](/docs/send-api/send-email), [AhaSend CLI](/docs/cli/quickstart), [Node.js SDK](/docs/guides/nodejs-sdk) and [Go SDK](/docs/guides/go-sdk).
* Delivery events: [webhook setup](/docs/integrations/webhooks) and [local webhook testing](/docs/cli/webhook-testing).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.