How to Send Email in Golang via SMTP or Email API

Editorial Note: We may earn a commission when you visit links on our website.
How to send email in Golang

When building a backend service, you’ll often need to add email-sending functionality to your web app. You’ve come to the right place if you’re looking to send emails in Go.

I’ve built email systems for Go applications for years, from simple notification scripts to production apps handling thousands of emails daily. The method you choose makes all the difference.

This guide covers three approaches to send email in Go: net/smtp for basic sending, Gomail for easier implementation, and the SendLayer Go SDK for scalable delivery.

You’ll get working code for plain text, HTML emails, attachments, and multiple recipients. Let’s dive in.

Understanding Email Sending Options in Go

When you’re working with email in Go, there are two main ways to send messages:

SMTP: Direct Sending

SMTP (Simple Mail Transfer Protocol) is the traditional way to send email. With Go’s standard net/smtp package, you can connect directly to an SMTP server and send emails without needing third-party SDKs.

Email APIs: Simplified Integration

Transactional email service providers like SendLayer, Postmark, and Amazon SES provide an abstraction over raw SMTP, making it easier to manage features such as authentication, retries, and analytics.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

How to Send Email in Golang With SMTP and API

Prerequisites

Below are some requirements you’ll need to follow along with this guide:

  • Golang is installed on your machine
  • Basic programming knowledge
  • SMTP provider

If you’re using SendLayer, you’ll need to authorize your sending domain. This step is essential to improve your site’s email deliverability.

Setting Up a Golang Project

You’ll need to install Go (Golang) on your machine if you haven’t already. Go supports Windows, macOS, and Linux. The installation steps may vary a little depending on your operating system.

Their official documentation includes specific instructions for various Operating Systems on installing Go.

After installing Go, open a terminal window and create a new directory using the command:

mkdir email-app

Next, navigate into the directory and create a new file:

cd email-app && touch sendEmail.go

Then open the folder in your favorite code editor (I’m using VS Code).

Once you’ve opened it, you’re ready to start sending emails in Go.

Method 1: Send Email Using net/smtp (Native Go)

Go’s standard library includes the net/smtp package for sending emails. This is the most basic approach and doesn’t require external dependencies.

Here’s an example of sending a basic email with the native Go package.

package main

import (
    "fmt"
    "net/smtp"
)

func main() {
    // SMTP server configuration
    smtpHost := "smtp.example.com"
    smtpPort := "587"
    
    // Sender credentials
    from := "[email protected]"
    password := "your-smtp-password"
    username := "your-smtp-username"
    
    // Recipient
    to := []string{"[email protected]"}
    
    // Message
    message := []byte("Subject: Test Email from Go\r\n" +
        "\r\n" +
        "This is a test email sent using net/smtp in Go.\r\n")
    
    // Authentication
    auth := smtp.PlainAuth("", username, password, smtpHost)
    
    // Send email
    err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, message)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Println("Email sent successfully!")
}

You’ll need to update smtpHost and smtpPort with your email provider’s credentials. Also, you’ll need to update username, password, and from with your personal SMTP details.

For Gmail SMTP, you’ll need to create an app-specific password. The username is the same as your Gmail address.

While net/smtp works for basic email, it lacks convenience features such as automatic MIME encoding and attachment handling. For production apps, Gomail or an SDK is recommended.

In the next sections, we’ll cover both SMTP using Gomail and API sending methods.

Method 2: Send Emails With SMTP in Go

This section, we’ll use the Gomail package, a third-party library for sending email.

Sending Plain Text Emails

To get started, you’ll need to install the package on your machine. To do so, open a terminal window, then navigate to your Go project directory and run the command:

go get gopkg.in/mail.v2

Once the installation completes, open the sendEmail.go file we created earlier and paste the snippet below:

package main

import (
	"fmt"
    "gopkg.in/gomail.v2"
)

func main() {
	// Initializing the email method
    msg := gomail.NewMessage()

	// Setting email headers
    msg.SetHeader("From", "[email protected]")
    msg.SetHeader("To", "[email protected]")
    msg.SetHeader("Subject", "Email Sent From Go With SendLayer SMTP!")

	// Setting Email body
    msg.SetBody("text/plain", "This is an example of a plain text message sent using Go")

	// Setting up SMTP dialer
    dialer := gomail.NewDialer("smtp.sendlayer.net", 587, "your-smtp-username", "your-smtp-password")

	// Sending the email
    if err := dialer.DialAndSend(msg); err != nil {
		fmt.Println("Error:", err)
        panic(err)
    } else {
		fmt.Println("Email sent successfully")
	}
}

Here is what the code does:

First, we import the gomail package we just installed. The gomail.NewMessage() line initializes the email module.

Then we configure the email headers using the msg.SetHeader() method. This is where you’ll specify the sender, recipient, and email subject.

Next, we use the msg.SetBody() method to write the actual message. It accepts 2 parameters: the message format and the message string.

After configuring the email headers and body, we use the gomail.NewDialer() module to set the SMTP server settings. You’ll need to replace the details in the snippet above with your actual SMTP server details.

I’m using SendLayer SMTP credentials for this tutorial. But the code works with any SMTP provider you use. You just need to replace the SMTP credentials with the one from your provider.

Retrieve Your SMTP Credentials

If you decide to use SendLayer as well, here’s how to retrieve your credentials. Start by logging in to your account dashboard and navigating to the Settings » SMTP Credentials screen.

After that, be sure to replace the dummy details with your actual username and password.

Finally, use the dialer.DialAndSend() method to send the email message. The method accepts one parameter, which is the message object. In our example, the parameter is stored in the msg variable.

Send HTML Emails in Go

Gomail also allows you to send HTML emails. To do so, you’ll need to specify the format as HTML in the msg.SetBody() line of code.

msg.SetBody("text/html", `
        <html>
            <body>
                <h2>This is a Test Email from Golang</h2>
                <p><b>Hello!</b> This test HTML email was sent using SendLayer SMTP server</p>
            </body>
        </html>
    `)

Email best practices often suggest having a plain text version of your email message. This will serve as a fallback for email clients that do not support HTML emails.

You can implement this by using the AddAlternative() module. Here is an updated version of our initial code.

package main

import (
	"fmt"
    "gopkg.in/gomail.v2"
)

func main() {
	// Initializing the email method
    msg := gomail.NewMessage()

	// Setting email headers
    msg.SetHeader("From", "[email protected]")
    msg.SetHeader("To", "[email protected]")
    msg.SetHeader("Subject", "Email Sent From Go With SendLayer SMTP!")

	// Setting Email body
    msg.SetBody("text/plain", "This is an example of a plain text message sent using Go")

   // HTML Email version
   msg.AddAlternative("text/html", `
        <html>
            <body>
                <h2>This is a Test Email from Golang</h2>
                <p><b>Hello!</b> This test HTML email was sent using SendLayer SMTP server</p>
            </body>
        </html>
    `)

	// Setting up SMTP dialer
    dialer := gomail.NewDialer("smtp.sendlayer.net", 587, "your-smtp-username", "your-smtp-password")

	// Sending the email
    if err := dialer.DialAndSend(msg); err != nil {
		fmt.Println("Error:", err)
        panic(err)
    } else {
		fmt.Println("Email sent successfully")
	}
}

Send Emails To Multiple Recipients

To send emails to multiple recipients, simply append the recipient email address(es) to the recipient header:

	// Setting email headers
    msg.SetHeader("From", "[email protected]")
    msg.SetHeader("To", "[email protected]", "[email protected]", "[email protected]")
    msg.SetHeader("Subject", "Email Sent From Go With SendLayer SMTP!")

Send Email With Attachments in Golang

You can also include attachment files in your email messages using the .Attach() method. This method accepts one parameter, which is a string containing the path to the attachment file. Here’s an updated version of the code:

package main

import (
	"fmt"
    "gopkg.in/gomail.v2"
)

func main() {
	// Initializing the email method
    msg := gomail.NewMessage()

	// Setting email headers
    msg.SetHeader("From", "[email protected]")
    msg.SetHeader("To", "[email protected]")
    msg.SetHeader("Subject", "Email Sent From Go With SendLayer SMTP!")

   // HTML Email
   msg.SetBody("text/html", `
        <html>
            <body>
                <h2>This is a Test Email from Golang</h2>
                <p><b>Hello!</b> This test HTML email was sent using SendLayer SMTP server</p>
            </body>
        </html>
    `)

   // Golang send email with attachment function
   msg.Attach("path/to/file.pdf")

	// Setting up SMTP dialer
    dialer := gomail.NewDialer("smtp.sendlayer.net", 587, "your-smtp-username", "your-smtp-password")

	// Sending the email
    if err := dialer.DialAndSend(msg); err != nil {
		fmt.Println("Error:", err)
        panic(err)
    } else {
		fmt.Println("Email sent successfully")
	}
}

Send a Test Email in Go

After creating your email function, testing it to ensure it’s properly configured is important. To do so, simply run the .go file you created in a terminal window:

go run sendEmail.go

You should see a success notification in the terminal. Go ahead and check the email inbox of the recipient you specified.

Send email in Go - gmail inbox

Congratulations! You’ve successfully built an email notification system in your Golang application.

SMTP vs API: Which Should You Use?

Choosing between SMTP and an email API depends on your use case. Here’s how they compare:

FeatureSMTP (net/smtp, Gomail)Email API (SendLayer SDK)
Setup ComplexityMedium – requires SMTP configEasy – just your API key
DeliverabilityDepends on server reputationHigh – managed infrastructure
ScalabilityLimited by SMTP serverHighly scalable
AnalyticsNoneOpens, clicks, bounces
Error HandlingManual retry logic neededAutomatic retries
WebhooksNot availableReal-time event notifications
Best ForSmall apps, testingProduction, high volume

For most production Go applications, an email API provides better reliability and features. Let’s see how to implement it.

Method 3: Send Email in Go via API

While SMTP works well for smaller projects, using an email API offers better performance and reliability. It also includes features such as webhook management and event tracking.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

You can send emails either by making direct API calls to the email endpoint or using an SDK. For this tutorial, I’ll use the SDK approach as it includes additional features like error handling, attachment encoding and simplified request format.

To get started, you’ll first need to install the SendLayer Golang SDK using the go get command:

go get github.com/sendlayer/sendlayer-go

The package requires an active API key for authentication and authorization. Here’s how to create/retrieve your API key in SendLayer.

Retrieve Your API Key

To retrieve your API key, log in to your SendLayer account. Once you’re logged in, click the Settings menu and select the API Keys tab.

Click API keys tab

Then click the copy icon next to Default API key to copy it.

Copy SendLayer API key to send email with python

After retrieving your API key, create a .env file in the root directory of your project and paste the API key into the file.

API_KEY=your-sendlayer-api-key

I’m using environment variables to store the API key. This prevents you from accidentally exposing sensitive credentials on version control systems.

Pro Tip: Make sure to include the .env file in your project’s .gitignore to prevent it from being pushed along with other project files.

Send Email via API Using SendLayer SDK

To send an email with the Golang SDK, you’ll first need to initialize the client with your API key. Then call sl.Emails.Send() with a SendEmailRequest object containing the email parameter.

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/sendlayer/sendlayer-go"
)

func main() {
    // Initialize the client with your API key
	apiKey := os.Getenv("API_KEY")
	if apiKey == "" {
		fmt.Println("Please set API_KEY environment variable")
		os.Exit(1)
	}
    
    sl := sendlayer.New(apiKey)

    // Send an email
    resp, err := sl.Emails.Send(&sendlayer.SendEmailRequest{
        From:    "[email protected]",
        To:      "[email protected]",
        Subject: "Test Email",
        Text:    "This is a test email",
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Email sent! Message ID:", resp.MessageID)
}

Code breakdown

The SDK requires an active API key to initialize it before you can send an email.

After initializing the package, configure the email parameters. The SDK accepts multiple parameters. However, the following are required:

  • Text or Html: Either HTML or plain text email content
  • From: Sender email address
  • To: A string or list of email recipient(s)
  • Subject: The email subject line

The sl.Emails.Send() method handles the email request with the email parameters as an argument.

Note: The From email address needs to include the domain name you authorized in SendLayer. For instance, if you verified example.com as your sending domain, the sender email should include @example.com.

When you run the file, you’ll see the MessageID printed in the console if the email is successfully sent. You should also receive an email in the recipient’s email inbox.

Test email sent with SendLayer API

Sending HTML Emails with the SDK

To send HTML emails, set the Html field in the request payload.

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/sendlayer/sendlayer-go"
)

func main() {
    // Initialize the client with your API key
	apiKey := os.Getenv("API_KEY")
	if apiKey == "" {
		fmt.Println("Please set API_KEY environment variable")
		os.Exit(1)
	}
    
    sl := sendlayer.New(apiKey)

    // Send an HTML email
    resp, err := sl.Emails.Send(&sendlayer.SendEmailRequest{
        From:    "[email protected]",
        To:      "[email protected]",
        Subject: "Test Email",
        Text:    "Plain text fallback",
        Html:    "<html><body><p>This is a test email sent with the <a href=\"https://sendlayer.com\">SendLayer</a> API!</p></body></html>",
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Email sent! Message ID:", resp.MessageID)
}

Note: You can include both Text and Html parameters to have both plain text and HTML versions of your email.

Send Emails to Multiple Recipients

SendLayer API also supports sending emails to multiple users, including “CC” and “BCC” email addresses. To do so, use the EmailAddress object to add the list of recipients, including Cc and Bcc.

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/sendlayer/sendlayer-go"
)

func main() {
    // Initialize the client with your API key
	apiKey := os.Getenv("API_KEY")
	if apiKey == "" {
		fmt.Println("Please set API_KEY environment variable")
		os.Exit(1)
	}
    
    sl := sendlayer.New(apiKey)

    // Send to multiple recipients
    resp, err := sl.Emails.Send(&sendlayer.SendEmailRequest{
        From: sendlayer.EmailAddress{
            Email: "[email protected]",
            Name:  "Paulie Paloma",
        },
        To: []sendlayer.EmailAddress{
            {Email: "[email protected]", Name: "Recipient 1"},
            {Email: "[email protected]", Name: "Recipient 2"},
        },
        Subject: "Sending Emails to Multiple Recipients",
        Html:    "<p>This is a <strong>test email</strong>!</p>",
        Text:    "This is a test email!",
        Cc:      []sendlayer.EmailAddress{{Email: "[email protected]", Name: "CC Recipient"}},
        Bcc:     []sendlayer.EmailAddress{{Email: "[email protected]", Name: "BCC Recipient"}},
        ReplyTo: sendlayer.EmailAddress{Email: "[email protected]", Name: "Reply To"},
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Email sent! Message ID:", resp.MessageID)
}

Send Email with Attachments via API in Go

You can also send emails with file attachments. To attach files to your email, use the Attachments field in the SendEmailRequest object.

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/sendlayer/sendlayer-go"
)

func main() {
    // Initialize the client with your API key
	apiKey := os.Getenv("API_KEY")
	if apiKey == "" {
		fmt.Println("Please set API_KEY environment variable")
		os.Exit(1)
	}
    
    sl := sendlayer.New(apiKey)

    // Send email with attachments
    resp, err := sl.Emails.Send(&sendlayer.SendEmailRequest{
        From: sendlayer.EmailAddress{Email: "[email protected]", Name: "Paulie Paloma"},
        To: []sendlayer.EmailAddress{
            {Email: "[email protected]", Name: "Recipient"},
        },
        Subject: "Email with Attachment",
        Html:    "<p>Please find the attached document.</p>",
        Attachments: []sendlayer.Attachment{
            {Path: "path/to/file.pdf", Type: "application/pdf"},
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Email sent! Message ID:", resp.MessageID)
}

The SDK handles file encoding, so you’ll only need to set Path to your local file path or hosted file URL. Then set the file Type (MIME type).

SendLayer SDK supports both local and remote file attachments and allows you to add multiple attachment files.

After updating the snippet, be sure to test your email module to ensure it is working. Here’s what the email looks like with a file attached.

Sending API email in Go

Best Practices for Sending Emails in Go

These are some industry recommendations for sending emails in Go.

Use Goroutines for Async Sending

Never block your main application flow when sending emails:

// Bad - blocks execution
err := sendEmail(recipient)

// Good - sends asynchronously
go func() {
    if err := sendEmail(recipient); err != nil {
        log.Printf("Failed to send email: %v", err)
    }
}()

Validate Email Addresses

If you’re using the built-in net/mail package, always validate before sending:

import "net/mail"

func validateEmail(email string) error {
    _, err := mail.ParseAddress(email)
    return err
}

However, API sending methods, such as the SendLayer Go SDK, include email validation by default. This means that all email addresses, including the sender’s and recipient’s, are validated before the request is sent.

4. Use Environment Variables

Never hardcode credentials. Use environment variables to store sensitive details. In your code, you can access the environment variable with the os.Getenv method. Here’s an example:

import "os"

apiKey := os.Getenv("SENDLAYER_API_KEY")
if apiKey == "" {
    log.Fatal("SENDLAYER_API_KEY not set")
}

FAQs – Send Email in Golang

These are answers to some of the top questions we see about sending emails with Golang.

How do I handle email bounces and delivery failures when sending emails in Go?

With SMTP, you need to process bounce messages manually. However, email APIs often provide tools and webhooks for managing bounces and delivery failures. Check our tutorial to learn more about managing webhooks in SendLayer.

Can I send emails asynchronously in Go to improve application performance?

Yes! You can use goroutines and channels to send emails asynchronously in the background.

What are the advantages of using an API-based service over SMTP in Go?

Using a transactional email service improves deliverability. Some providers also offer built-in analytics and handle bounces. They scale better than direct SMTP for high-volume sending. You can check our guide for details about the different sending methods (SMTP vs APIs).

Can I send email in Golang without SMTP?

Yes! You can connect your Golang app to an API-based email service like SendLayer. Then send your emails through the API.

How do I send HTML email in Go?

Here’s how to send HTML emails in Go using the three methods covered in this tutorial:

  • Gomail: Use SetBody("text/html", htmlContent)
  • SendLayer SDK: Set the Html field in the SendEmailRequest object.
  • net/smtp: Set the MIME headers to Content-Type: text/html.

That’s it! Now you know how to send emails in Golang with SMTP or API.

Next, would you like to learn about the various types of email bounce? Check out our tutorial on hard bounce vs soft bounce emails for more information.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

Ready to send your emails in the fastest and most reliable way? Get started today with the most user-friendly and powerful SMTP email delivery service. SendLayer Business includes 5,000 emails a month with premium support.