How To Receive E-mails in ASP.NET MVC using MailGun

Mailgun has a fantastic API for doing a lot of stuff with e-mail. Not only is it a breeze to use their dedicated SMTP service to send a lot of e-mails with great deliver-ability – it is also very powerful for routing e-mails back to your application.

There’s a lot of use cases for routing e-mails back to your app, a few includes:

  • Reply to messages within your app
  • Send files to your app from any device, without providing native apps for any particular devices
  • Execute commands from e-mail to e.g. run a background task, or whatever makes your users happy

Heck, you can even transfer money using e-mail. Just write $10 in the subject line, send it to your friend and add [email protected] to the CC recipients list and you’ve just sent money via e-mail.

Mailgun routes

To route back e-mail to your application, you need two things:

  1. Setup an MX record of a domain so that it points to
  2. Add a route within Mailgun that forwards to your web app

Setting up the MX record is beyond the scope of this blog post. You can take a look at the Mailgun docs and find guides for common hosting providers.

To setup a route, you need to login to Mailgun, find the Routes tab and create a new route with a match criteria that let’s you filter by recipient, header etc. Read more about routes in the docs.

Receiving messages via HTTP

Whenever an e-mail matches the criteria of the route, Mailgun will issue an HTTP POST request to the URL you specified as part of the forward() action.

To receive the request in a controller/action in ASP.NET MVC, you can use the following code:

Mailgun listens to the HTTP status code you return:

For Route POSTs, Mailgun listens for the following codes from your server and reacts accordingly:

If Mailgun receives a 200 (Success) code it will determine the webhook POST is successful and not retry.
If Mailgun receives a 406 (Not Acceptable) code, Mailgun will determine the POST is rejected and not retry.
For any other code, Mailgun will retry POSTing according to the schedule below for Webhooks other than the

And will retry for 8 hours:

If your application is unable to process the webhook request but you do not return a 406 error code, Mailgun will retry (other than for delivery notification) during 8 hours at the following intervals before stop trying: 10 minutes, 10 minutes, 15 minutes, 30 minutes, 1 hour, 2 hour and 4 hours.