Make onboarding emails also work via API (not only SMTP)

The following problem:

I had some issues setting up SMTP for Digital Ocean. And also other hosters, since there seems to be a tendency towards “we will not allow SMTP traffic” for a good reason. Please also refer to this thread: Use Mailgun API, instead of SMTP for onboarding-emails?

The idea here is now: Why not make ghost available to use API-calls, like the one we have with mailgun, to get the onboarding emails gone right.

Right now I can live with the “workarounds”, like using ports not suitable for SMTP. But this might be just a matter of time, since ports getting blocked.

Solution:

Make an API option for onboaring-emails as well. (like mailgun API, that is already heavily promoted).

I would assume, that this would bring a so much more flexibility to open-source hosting.

2 Likes

Ghost should support using Mailgun via API for transactional email. Can you try the configuration from this portion of the docs?

Vikas, the docs don’t show an example with Mailgun API, only SMTP. Might be a docs problem, though!

heh my bad, I saw the section and walked read right past it :upside_down_face:

Reading the wrapper code and nodemailer-mailgun-transport docs, I think something like this might work:

"mail": {
    "transport": "mailgun",
    "options": {
        "host": "<>",
        "auth": {
            "api_key": "<>",
            "domain": "<>"
        }
    }
}
5 Likes

Amazing!

It absolutely works! Would be great, to have this mentioned in the docs. But at least we have now this searchable in the forums.

Thanks again!

3 Likes

Seconding this update to the docs when possible. I spent 1-2 days just to discover this as Digital Ocean has now blocked sending with SMTP. The workaround with port 2525 is working but not sure for how long. My suggestion is to please mention this somewhere in the docs that it could be caused by Digital Ocean’s blocking as I have 5 separate websites running on ghost hosted by digital ocean that I now need to reconfigure.

Thank you.

Just adding a full config example here for anyone who needs it.

  "mail": {
    "transport": "mailgun",
    "from": "an-email-address-that-i-confirmed-with-mailgun@mydomain.tld",
    "options": {
      "auth": {
        "api_key": "my-big-long-api-key-string-from-mailgun",
        "domain": "mg.mydomain.tld"
      },
      "host": "api.mailgun.net"
    }
  },

This is what I’ve got live on my server on 5.121.

3 Likes

I’m also stuck in the Digitalocean smtp issue, but using this is giving me an “invalid Mail Transport” messge saying that the mail.transport key value of mailgun isnt valid. Any idea what the issue might be?

1 Like

Can you share your redacted config?

Yeah, I’ve been able to reproduce this.

Setup works fine, but when you run ghost start or ghost doctor, the CLI flags the value mail.transport when set to "mailgun" as invalid. But, the workaround I’ve found is that when running ghost restart the unintended behaviour does not occurr.

Going to make an issue on GitHub, initially thought this was some error on my end, but it seems clear that this may be unintended behaviour.

1 Like

I can confirm - I also need to ghost restart. This is probably a Ghost CLI issue, not main Ghost. (There’s a separate repo.) @acburdine may be interested, too! (Hi Austin!)

Yeah, looks like this is a bug on the CLI side - will get it fixed here in the next few days :+1:t2:

1 Like

I’m relocating the post to self hosting, so that we can discuss at full speed if wanted :)

Hey folks - a fix for the ghost doctor/ghost start issue was released in Ghost-CLI 1.28.1 - let us know if you see any more issues with it :smiley:

3 Likes

Has anyone tested out how/if this might be possible with the new v6 docker .env file?

I have the same problem. I can send e-mails/newsletters fine via the API setup. But I am not able to get newsletter signups working. It wont send the e-mail.

How should the e-mail section in the .env file be so it is using the API instead? I am using the docker installation method.

Generically, the env variables for Ghost in docker look like mail__transport, mail__from, mail__options__auth__api_key, etc. Use double _ between nested values in the json.

1 Like

Thank you for answering I appreciate it.

I have added this in the .env file, but it doesn’t seem to work. (XXXX Is for privacy)

mail__transport=mailgun
mail__host=api.mailgun.net
mail__from=bxxxxx@gmail.com
mail__options__auth__api_key=3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1610-f87df25e
mail__options__auth__domain=sandbox5xxxxxxxxxxxxxxxxxxxx4.mailgun.org

Any ideas, or have I done something wrong here?

If I try to see in the docker logs I get:

[2025-08-14 13:20:15] INFO ActivityPub webhooks in correct state
[2025-08-14 13:20:15] INFO URL Service ready in 1267ms
[2025-08-14 13:20:25] INFO "GET /members/api/integrity-token/" 200 15ms
[2025-08-14 13:20:25] ERROR Failed to send email. Reason: Forbidden.

Failed to send email. Reason: Forbidden.

"Please see https://ghost.org/docs/config/#mail for instructions on configuring email."

Error ID:
    70989c60-7911-11f0-a78b-4bb82bcc182a

Getting a fresh api key from mailgun may be helpful. You might also check Mailgun for any error logs.

Yeah, I can see it is getting rejected in Mailgun logs. Not sure why, apparently it has to be able to send some data to mailgun.