> ## 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. 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.

# Sending emails in Delphi

> Learn how to send emails using AhaSend SMTP with Delphi and the Indy networking library

# Sending Emails with SMTP in Delphi

Send emails through AhaSend's SMTP servers using Delphi and the powerful Indy networking library. This guide covers everything from basic setup to advanced features like HTML content, attachments, and custom headers.

> [!NOTE]
>
> **Delphi & Indy Power:** Delphi's robust development environment combined with Indy's comprehensive networking components provides excellent email capabilities for desktop and server applications.

> [!TIP]
>
> **Special Thanks:** This guide was partly provided by **Kirk**, one of our amazing customers! We're grateful for the Delphi community's contributions and expertise in helping fellow developers integrate with AhaSend.

## Prerequisites

Before you begin, ensure you have:

> [accordion] Development Environment
>
> * **Delphi installed** on your system (Delphi 10.3 or higher recommended)
> * **Indy networking library** configured in your project
> * Basic knowledge of Delphi/Object Pascal programming
> * Access to Delphi's component palette and IDE

> [accordion] AhaSend Setup
>
> * **Domain verified** in your AhaSend account
> * **SMTP credentials** created (username and password)
> * Access to your AhaSend dashboard for credential management

> [accordion] Indy Components
>
> * **TIdSMTP** component for SMTP functionality
> * **TIdSSLIOHandlerSocketOpenSSL** for secure connections
> * **TIdMessage** for email message construction
> * **TIdEncoderMIME** for encoding operations

> [!NOTE]
>
> **Need SMTP Credentials?** If you haven't created SMTP credentials yet, check out our [SMTP Credentials guide](https://ahasend.com/docs/smtp/credentials.md) for step-by-step instructions.

## Indy Components Overview

Delphi's Indy library provides powerful networking components for email operations:

> [card] TIdSMTP
>
> **Purpose:** Main SMTP client component\\
>
> **Features:** Connection, auth, sending\\
>
> **Security:** TLS/SSL support\\
>
> **Location:** Internet tab in component palette

> [card] TIdMessage
>
> **Purpose:** Email message construction\\
>
> **Features:** Headers, body, attachments\\
>
> **Encoding:** MIME support\\
>
> **Location:** Internet tab in component palette

## Connection Settings

Use these settings for all Delphi SMTP configurations with AhaSend:

> [card] SMTP Server
>
> **Host:** `send.ahasend.com`\\
>
> **Ports:** 587 (recommended), 25, 2525\\
>
> **Security:** STARTTLS\\
>
> **Authentication:** Required

## Basic Email Examples

### Component Setup

First, add the required Indy components to your form or data module:

```pascal Form Setup theme={null}
// Add these components to your form/data module:
// - TIdSMTP (name: IdSMTP1)
// - TIdSSLIOHandlerSocketOpenSSL (name: IdSSL1)
// - TIdMessage (name: IdMessage1)
// - TIdEncoderMIME (name: IdEncoderMIME1)

// Required units in your uses clause:
uses
  IdSMTP, IdSSLIOHandlerSocketOpenSSL, IdMessage,
  IdEncoderMIME, IdGlobal, IdText, IdAttachmentFile;
```

```pascal Unit Declarations theme={null}
unit EmailService;

interface

uses
  System.SysUtils, System.Classes,
  IdSMTP, IdSSLIOHandlerSocketOpenSSL, IdMessage,
  IdEncoderMIME, IdGlobal, IdText, IdAttachmentFile;

type
  TEmailService = class
  private
    FIdSMTP: TIdSMTP;
    FIdSSL: TIdSSLIOHandlerSocketOpenSSL;
    FIdMessage: TIdMessage;
    FIdEncoder: TIdEncoderMIME;
    procedure ConfigureSMTP;
    function CreateMessage(const AFrom, ATo, ASubject, ABody: string): TIdMessage;
  public
    constructor Create;
    destructor Destroy; override;
    function SendEmail(const AFrom, ATo, ASubject, ABody: string): Boolean;
  end;

implementation
```

### Basic Examples

```pascal Plain Text Email theme={null}
procedure TForm1.SendPlainTextEmail;
var
  IdMessage: TIdMessage;
begin
  // Configure SMTP component
  IdSMTP1.IOHandler := IdSSL1;
  (IdSMTP1.IOHandler as TIdSSLIOHandlerSocketOpenSSL).PassThrough := False;
  IdSMTP1.Username := 'YOUR_SMTP_USERNAME';
  IdSMTP1.Password := 'YOUR_SMTP_PASSWORD';
  IdSMTP1.Host := 'send.ahasend.com';
  IdSMTP1.Port := 587;
  IdSMTP1.AuthType := satNone;
  IdSMTP1.UseTLS := utUseExplicitTLS;
  IdSMTP1.UseEhlo := True;

  // Create message
  IdMessage := TIdMessage.Create(nil);
  try
    IdMessage.From.Address := 'hello@yourdomain.com';
    IdMessage.From.Name := 'Your Company';
    IdMessage.Recipients.Add.Address := 'user@example.com';
    IdMessage.Subject := 'Welcome to our platform!';
    IdMessage.Body.Text := 'Thanks for signing up. We''re excited to have you!';
    IdMessage.ContentType := 'text/plain';

    // Send the email
    IdSMTP1.Connect;
    try
      if IdSMTP1.Authenticate then
      begin
        IdSMTP1.SendCmd('AUTH PLAIN ' + IdEncoderMIME1.EncodeString(#0 + IdSMTP1.Username + #0 + IdSMTP1.Password));
        IdSMTP1.Send(IdMessage);
        ShowMessage('Email sent successfully!');
      end;
    finally
      IdSMTP1.Disconnect;
    end;
  finally
    IdMessage.Free;
  end;
end;
```

```pascal HTML Email theme={null}
procedure TForm1.SendHTMLEmail;
var
  IdMessage: TIdMessage;
  HTMLPart: TIdText;
begin
  // Configure SMTP component
  IdSMTP1.IOHandler := IdSSL1;
  (IdSMTP1.IOHandler as TIdSSLIOHandlerSocketOpenSSL).PassThrough := False;
  IdSMTP1.Username := 'YOUR_SMTP_USERNAME';
  IdSMTP1.Password := 'YOUR_SMTP_PASSWORD';
  IdSMTP1.Host := 'send.ahasend.com';
  IdSMTP1.Port := 587;
  IdSMTP1.AuthType := satNone;
  IdSMTP1.UseTLS := utUseExplicitTLS;
  IdSMTP1.UseEhlo := True;

  // Create message
  IdMessage := TIdMessage.Create(nil);
  try
    IdMessage.From.Address := 'hello@yourdomain.com';
    IdMessage.From.Name := 'Your Company';
    IdMessage.Recipients.Add.Address := 'user@example.com';
    IdMessage.Subject := 'Welcome to our platform!';

    // Add plain text part for fallback
    IdMessage.Body.Text := 'Welcome! Thanks for signing up. Visit https://yourdomain.com/get-started to get started.';

    // Add HTML part
    HTMLPart := TIdText.Create(IdMessage.MessageParts, nil);
    HTMLPart.ContentType := 'text/html';
    HTMLPart.Body.Text :=
      '<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>';

    // Send the email
    IdSMTP1.Connect;
    try
      if IdSMTP1.Authenticate then
      begin
        IdSMTP1.SendCmd('AUTH PLAIN ' + IdEncoderMIME1.EncodeString(#0 + IdSMTP1.Username + #0 + IdSMTP1.Password));
        IdSMTP1.Send(IdMessage);
        ShowMessage('HTML email sent successfully!');
      end;
    finally
      IdSMTP1.Disconnect;
    end;
  finally
    IdMessage.Free;
  end;
end;
```

```pascal Email with Attachment theme={null}
procedure TForm1.SendEmailWithAttachment;
var
  IdMessage: TIdMessage;
  Attachment: TIdAttachmentFile;
begin
  // Configure SMTP component
  IdSMTP1.IOHandler := IdSSL1;
  (IdSMTP1.IOHandler as TIdSSLIOHandlerSocketOpenSSL).PassThrough := False;
  IdSMTP1.Username := 'YOUR_SMTP_USERNAME';
  IdSMTP1.Password := 'YOUR_SMTP_PASSWORD';
  IdSMTP1.Host := 'send.ahasend.com';
  IdSMTP1.Port := 587;
  IdSMTP1.AuthType := satNone;
  IdSMTP1.UseTLS := utUseExplicitTLS;
  IdSMTP1.UseEhlo := True;

  // Create message
  IdMessage := TIdMessage.Create(nil);
  try
    IdMessage.From.Address := 'hello@yourdomain.com';
    IdMessage.From.Name := 'Your Company';
    IdMessage.Recipients.Add.Address := 'user@example.com';
    IdMessage.Subject := 'Your Invoice is Ready';
    IdMessage.Body.Text := 'Please find your invoice attached to this email.';

    // Add attachment
    if FileExists('C:\path\to\invoice.pdf') then
    begin
      Attachment := TIdAttachmentFile.Create(IdMessage.MessageParts, 'C:\path\to\invoice.pdf');
      Attachment.DisplayName := 'invoice.pdf';
    end;

    // Send the email
    IdSMTP1.Connect;
    try
      if IdSMTP1.Authenticate then
      begin
        IdSMTP1.SendCmd('AUTH PLAIN ' + IdEncoderMIME1.EncodeString(#0 + IdSMTP1.Username + #0 + IdSMTP1.Password));
        IdSMTP1.Send(IdMessage);
        ShowMessage('Email with attachment sent successfully!');
      end;
    finally
      IdSMTP1.Disconnect;
    end;
  finally
    IdMessage.Free;
  end;
end;
```

## Testing with Sandbox Mode

Use sandbox mode to safely test your Delphi email integration:

```pascal Sandbox Test theme={null}
procedure TForm1.SendSandboxTest;
var
  IdMessage: TIdMessage;
begin
  // Configure SMTP component
  IdSMTP1.IOHandler := IdSSL1;
  (IdSMTP1.IOHandler as TIdSSLIOHandlerSocketOpenSSL).PassThrough := False;
  IdSMTP1.Username := 'YOUR_SMTP_USERNAME';
  IdSMTP1.Password := 'YOUR_SMTP_PASSWORD';
  IdSMTP1.Host := 'send.ahasend.com';
  IdSMTP1.Port := 587;
  IdSMTP1.AuthType := satNone;
  IdSMTP1.UseTLS := utUseExplicitTLS;
  IdSMTP1.UseEhlo := True;

  // Create message
  IdMessage := TIdMessage.Create(nil);
  try
    IdMessage.From.Address := 'test@yourdomain.com';
    IdMessage.Recipients.Add.Address := 'test@example.com';
    IdMessage.Subject := 'Sandbox Test Email';
    IdMessage.Body.Text := 'This email is sent in sandbox mode for testing.';

    // Enable sandbox mode
    IdMessage.ExtraHeaders.Values['AhaSend-Sandbox'] := 'true';
    IdMessage.ExtraHeaders.Values['AhaSend-Sandbox-Result'] := 'deliver';

    // Send the email
    IdSMTP1.Connect;
    try
      if IdSMTP1.Authenticate then
      begin
        IdSMTP1.SendCmd('AUTH PLAIN ' + IdEncoderMIME1.EncodeString(#0 + IdSMTP1.Username + #0 + IdSMTP1.Password));
        IdSMTP1.Send(IdMessage);
        ShowMessage('Sandbox email sent successfully!');
      end;
    finally
      IdSMTP1.Disconnect;
    end;
  finally
    IdMessage.Free;
  end;
end;
```

```pascal Sandbox Bounce Test theme={null}
procedure TForm1.SendSandboxBounceTest;
var
  IdMessage: TIdMessage;
begin
  // Configure SMTP component
  IdSMTP1.IOHandler := IdSSL1;
  (IdSMTP1.IOHandler as TIdSSLIOHandlerSocketOpenSSL).PassThrough := False;
  IdSMTP1.Username := 'YOUR_SMTP_USERNAME';
  IdSMTP1.Password := 'YOUR_SMTP_PASSWORD';
  IdSMTP1.Host := 'send.ahasend.com';
  IdSMTP1.Port := 587;
  IdSMTP1.AuthType := satNone;
  IdSMTP1.UseTLS := utUseExplicitTLS;
  IdSMTP1.UseEhlo := True;

  // Create message
  IdMessage := TIdMessage.Create(nil);
  try
    IdMessage.From.Address := 'test@yourdomain.com';
    IdMessage.Recipients.Add.Address := 'test@example.com';
    IdMessage.Subject := 'Sandbox Bounce Test';
    IdMessage.Body.Text := 'This email simulates a bounce for webhook testing.';

    // Enable sandbox mode with bounce simulation
    IdMessage.ExtraHeaders.Values['AhaSend-Sandbox'] := 'true';
    IdMessage.ExtraHeaders.Values['AhaSend-Sandbox-Result'] := 'bounce';

    // Send the email
    IdSMTP1.Connect;
    try
      if IdSMTP1.Authenticate then
      begin
        IdSMTP1.SendCmd('AUTH PLAIN ' + IdEncoderMIME1.EncodeString(#0 + IdSMTP1.Username + #0 + IdSMTP1.Password));
        IdSMTP1.Send(IdMessage);
        ShowMessage('Sandbox bounce test sent - check webhooks!');
      end;
    finally
      IdSMTP1.Disconnect;
    end;
  finally
    IdMessage.Free;
  end;
end;
```

```pascal Error Handling with Try-Except theme={null}
procedure TForm1.SendEmailWithErrorHandling;
var
  IdMessage: TIdMessage;
  MaxRetries, RetryCount: Integer;
  Success: Boolean;
begin
  MaxRetries := 3;
  RetryCount := 0;
  Success := False;

  // Configure SMTP component
  IdSMTP1.IOHandler := IdSSL1;
  (IdSMTP1.IOHandler as TIdSSLIOHandlerSocketOpenSSL).PassThrough := False;
  IdSMTP1.Username := 'YOUR_SMTP_USERNAME';
  IdSMTP1.Password := 'YOUR_SMTP_PASSWORD';
  IdSMTP1.Host := 'send.ahasend.com';
  IdSMTP1.Port := 587;
  IdSMTP1.AuthType := satNone;
  IdSMTP1.UseTLS := utUseExplicitTLS;
  IdSMTP1.UseEhlo := True;

  while (not Success) and (RetryCount < MaxRetries) do
  begin
    Inc(RetryCount);

    IdMessage := TIdMessage.Create(nil);
    try
      IdMessage.From.Address := 'hello@yourdomain.com';
      IdMessage.Recipients.Add.Address := 'user@example.com';
      IdMessage.Subject := 'Test with Retry Logic';
      IdMessage.Body.Text := 'This email will retry on failure.';

      try
        IdSMTP1.Connect;
        try
          if IdSMTP1.Authenticate then
          begin
            IdSMTP1.SendCmd('AUTH PLAIN ' + IdEncoderMIME1.EncodeString(#0 + IdSMTP1.Username + #0 + IdSMTP1.Password));
            IdSMTP1.Send(IdMessage);
            Success := True;
            ShowMessage(Format('Email sent successfully on attempt %d', [RetryCount]));
          end;
        finally
          IdSMTP1.Disconnect;
        end;
      except
        on E: EIdSMTPReplyError do
        begin
          if E.ErrorCode >= 500 then
            Break // Don't retry permanent failures
          else
            ShowMessage(Format('SMTP error on attempt %d: %s', [RetryCount, E.Message]));
        end;
        on E: Exception do
        begin
          ShowMessage(Format('Unexpected error on attempt %d: %s', [RetryCount, E.Message]));
          if RetryCount < MaxRetries then
            Sleep(1000 * RetryCount); // Exponential backoff
        end;
      end;
    finally
      IdMessage.Free;
    end;
  end;

  if not Success then
    ShowMessage(Format('Failed to send email after %d attempts', [MaxRetries]));
end;
```

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

## Resources

> [card] [Indy Project Documentation](https://www.indyproject.org/)
>
> Official Indy networking components documentation

> [card] [Delphi Documentation](https://docwiki.embarcadero.com/)
>
> Comprehensive Delphi programming guide

> [card] [AhaSend Support](mailto:support@ahasend.com)
>
> Get help from our engineering team


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