← All posts

2 Best Ways to Send Emails from Unity

· Updated October 2, 2026

UnityScriptingEmailsSMTP
Send emails from Unity

A feedback button that opens a ready-to-send email gets far more replies than an address tucked away in the credits. Point the same plumbing somewhere else and it will send you crash logs and device details from test builds without anyone typing a word.

Unity can do both without a plugin. There are two ways, and they suit different jobs:

  1. Open the player’s own mail app with a mailto: link. The player sees the message and presses send.
  2. Send the message yourself through an SMTP server. Nothing appears on screen, which is what you want for logs and diagnostics.

Below is working code for both in current versions of Unity, plus the security catch that most tutorials on this topic leave out.

Option 1: open the player’s mail app with mailto

This is the one I reach for first. It needs no server, no credentials and no special permissions, and because the player can read exactly what’s being sent, there’s nothing to justify in a privacy policy.

Add this component to any GameObject and hook SendEmail up to a button’s OnClick:

using UnityEngine;
using UnityEngine.Networking;

public class MailSender : MonoBehaviour
{
    [SerializeField] private string address = "support@yourstudio.com";

    public void SendEmail()
    {
        string subject = Escape("Feedback for " + Application.productName);
        string body = Escape("Tell us what happened:\n\n\n");
        Application.OpenURL($"mailto:{address}?subject={subject}&body={body}");
    }

    private static string Escape(string text)
    {
        // EscapeURL turns spaces into '+', which many mail apps show literally.
        return UnityWebRequest.EscapeURL(text).Replace("+", "%20");
    }
}

Older tutorials, including the first version of this one, used WWW.EscapeURL. The WWW class has been deprecated for years, and UnityWebRequest.EscapeURL does the same job. Keep the Replace call: without it, the subject arrives as “Feedback+for+My+Game”.

Adding device details to the report

A bug report is far more useful when you know what it came from. SystemInfo and Application cover most of it, so I pre-fill a block under the player’s message and ask them to leave it alone:

string body = Escape(
    "Tell us what happened:\n\n\n\n" +
    "---- please leave this part ----\n" +
    $"Game version: {Application.version}\n" +
    $"Device: {SystemInfo.deviceModel}\n" +
    $"OS: {SystemInfo.operatingSystem}\n" +
    $"Memory: {SystemInfo.systemMemorySize} MB\n" +
    $"GPU: {SystemInfo.graphicsDeviceName}");

Two things to know before you ship this. If the device has no mail app set up, OpenURL quietly does nothing, so keep a plain-text address visible somewhere as a fallback. And some mail apps cut off very long mailto: links, so this is no place for a full log file. For that, you need option 2.

Option 2: send it yourself through SMTP

SMTP lets the game send the email directly, with no mail app and nothing on screen. That makes it the right tool for crash logs in test builds and for internal QA tools. I’ll use Gmail’s SMTP server because almost everyone has an account, but any provider works the same way.

Gmail no longer accepts your normal password from apps, so create an App Password first:

  1. Turn on 2-Step Verification for the Google account. App Passwords don’t exist without it.
  2. Open your Google account’s security page and find App passwords.
  3. Create one for your game and keep the 16-character password somewhere safe.

If an older guide told you to switch on “less secure app access”, that setting is gone; Google removed it completely. With the App Password ready, here’s the sender:

using System.Net;
using System.Net.Mail;
using UnityEngine;

public class SmtpMailSender : MonoBehaviour
{
    // Fine for internal builds. Read the security section before shipping this.
    private const string SenderAddress = "yourgame@gmail.com";
    private const string AppPassword = "your-app-password";

    public async void SendSmtpMail(string subject, string body)
    {
        using var mail = new MailMessage(SenderAddress, "you@yourstudio.com", subject, body);
        using var smtp = new SmtpClient("smtp.gmail.com", 587)
        {
            EnableSsl = true,
            Credentials = new NetworkCredential(SenderAddress, AppPassword),
        };

        try
        {
            await smtp.SendMailAsync(mail);
            Debug.Log("Email sent.");
        }
        catch (SmtpException e)
        {
            // A wrong App Password shows up here as an authentication error.
            Debug.LogWarning($"Email failed ({e.StatusCode}): {e.Message}");
        }
    }
}

The code in the original version of this post is still copied around a lot, so here’s what changed and why:

  • It doesn’t freeze the game. Send blocks the main thread until Gmail answers, which can take seconds on a phone. SendMailAsync waits in the background, and because Unity resumes await on the main thread, it’s safe to update the UI afterwards.
  • It only says “sent” when it was. The old version logged its success message in a finally block, so a failed send still printed “Email sent!”.
  • It keeps certificate checks on. Old tutorials, mine included, set ServicePointManager.ServerCertificateValidationCallback to always return true. That was a workaround for certificate problems in very old versions of Unity, and it switches off the check that stops someone on the same Wi-Fi from reading your password. Current versions don’t need it, so leave it out.

You also don’t need to change the API Compatibility Level any more. SmtpClient is part of .NET Standard 2.0, so it’s available under the default setting in any recent version of Unity. Two limits remain: it won’t work in WebGL builds, because browsers don’t allow raw network connections, and Microsoft now recommends MailKit over SmtpClient for new .NET projects, which is worth knowing if your needs grow.

Which one should you use?

For anything a player triggers, use mailto. It’s transparent, it needs no secrets, and the player’s own mail app deals with attachments, retries and spam filters. SMTP earns its place in test builds and internal tools, where you want reports to arrive without anyone pressing send.

The security catch with SMTP

Anything inside a Unity build can be pulled back out. C# compiles to IL that decompiles almost line for line, and even IL2CPP builds keep string literals in a metadata file that free tools can read. Ship an App Password in a public game and assume someone will find it and use your account to send spam.

So for a live game, don’t send email from the client at all. Have the game post the message to a small endpoint you control (a serverless function is plenty) and let that send it through your mail provider or a transactional email service. The credentials stay on the server, and you can rate-limit the endpoint so nobody can turn it into a spam cannon. The Unity side is short:

using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class FeedbackSender : MonoBehaviour
{
    [SerializeField] private string endpoint = "https://yourstudio.com/api/feedback";

    [System.Serializable]
    private class Feedback
    {
        public string message;
        public string version;
        public string device;
    }

    public IEnumerator Send(string message)
    {
        string json = JsonUtility.ToJson(new Feedback
        {
            message = message,
            version = Application.version,
            device = SystemInfo.deviceModel,
        });

        using var request = new UnityWebRequest(endpoint, "POST");
        request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(json));
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");

        yield return request.SendWebRequest();

        if (request.result != UnityWebRequest.Result.Success)
            Debug.LogWarning($"Feedback failed: {request.error}");
    }
}

Start it with StartCoroutine(Send(text)) from your feedback form. If your needs grow past email, into native share sheets, push notifications or a platform SDK, that’s native plugin territory, which works quite differently from plain C#. My guide to integrating native Android and iOS SDKs into Unity covers how I approach it.

Common questions

How do I send an email from a Unity game?

The two plugin-free options are opening the user's default mail app with Application.OpenURL and a mailto URL, or sending directly through an SMTP server with SmtpClient. The mailto approach shows the user everything being sent, while SMTP sends silently in the background, which suits crash logs and diagnostics.

Can Unity send emails through Gmail?

Yes. Point SmtpClient at smtp.gmail.com on port 587 with EnableSsl set to true, and authenticate with a Google App Password rather than your normal account password. Creating an App Password requires 2-Step Verification to be enabled on the Google account.

Why is my Gmail password not working with SMTP in Unity?

Google no longer accepts regular account passwords from apps and removed the less secure app access setting entirely. You need to enable 2-Step Verification, generate an App Password on your account's security page, and use that in your NetworkCredential instead.

Does sending email from Unity work in WebGL builds?

The SMTP approach does not work in WebGL builds. The mailto approach via Application.OpenURL still works there since it just hands a URL to the browser, and for anything more you'd need a server-side endpoint that sends the email for you.

Is it safe to put SMTP credentials in a Unity build?

No. Anything inside a Unity build can be decompiled, including hardcoded SMTP usernames and passwords. Keep the SMTP approach for internal builds, prototypes, and QA tooling, and for a live game send the email from a small backend so credentials never leave the server.