Live Chat

We'll need to share your messages (and your email address if you're logged in) with our live chat provider, Drift. Here's their privacy policy.

If you don't want to do this, you can email us instead at

Building Email-Driven Apps
« Anvil Cookbook
Sending and responding to email in code

Email is the most popular messaging platform on Earth. We use email to arrange events, to exchange files, and to notify each other when something happens.

You should be able to email your applications too. But to receive email, you need to set up a server somewhere, run an SMTP daemon, and somehow connect that to your code.

We’re here to fix that. Today, we’re delighted to show you the easiest way to build email-driven apps. All you need to do is write a Python function. For example, here’s all the code you need to receive emails and store them in a database:
def incoming_email(msg):
  msg.reply(text="Thank you for your message.")

Sending is just as simple:
  subject="New message",
  text="This is awesome",
  html="This is <b>awesome</b>"

Despite its simplicity, it’s also fully featured - you can handle attachments, recipients, and even use DKIM to check that a message is genuine before trusting what it says.


You can scroll down for a cookbook of common examples, or watch as I build a full disposable-email-address service, and publish it on the web, in four minutes:

Example Snippets Watch video

Video example: Disposable Email

App Source Code
Note: We skim past the UI building pretty fast in that video.
If you want to see how it's done, check out our other tutorials for a slower explanation.

Sample Email Code

Here are a few things you might want to do with email. You can follow along from these code snippets, or view them all in the Anvil editor:

Open Example Code

1. Receiving email and saving it in a database
def incoming_email(msg):

2. Replying to an email you’ve received
def incoming_email(msg):
  msg.reply(text="Thank you for your message.")

3. Sending email

def send_a_message(txt):
    cc=["Someone Else <>"],
    subject="Hello World",
    text="Hi there!"

4. Handling attachments

All attachments are Anvil Media objects. This means you can upload them from web browsers, store them in databases, make them downloadable, and more.

def send_by_email(file):
    subject="New upload",

Incoming attachments are just as straightforward. Here’s how to save all attachments in a database:
def incoming_email(msg):
  for f in msg.attachments:

5. Authenticating senders

Email has historically been easy to spoof. Helpfully, many providers now support DKIM, which lets you verify that the email actually came from the domain it says it did.

The dkim property of the message contains details about all that message’s valid DKIM signatures, and a shortcut to check whether it’s signed by the address in msg.envelope.from_address:
def incoming_email(msg):
  if msg.envelope.from_address == ''
      and msg.dkim.valid_from_sender:
    msg.reply(text="You're the real deal!")

There’s a shorthand, if you only want to accept DKIM-authenticated messages (and reject all others):
def incoming_email(msg):
  if msg.envelope.from_address == '':
    msg.reply(text="You're the real deal!")

6. Rejecting (“bouncing”) messages
def incoming_email(msg):
Try it yourself

Start writing email-driven apps for free with Anvil:

Try it now

You can also read more about the Email service in the Anvil reference docs.

Learn More

Get the best out of Anvil with our free email course.