Guide

How to send email with Flask

Send email from a Flask route with the REST API.

In short

Create a Sendpository account, verify your domain, put your API key in SENDPOSITORY_API_KEY, and send with the code below - one HTTPS request per email, from server-side code only.

1. Verify your sending domain

Add your domain in the dashboard and publish the three DNS records it shows - SPF and a bounce record on an sp. subdomain, and a DKIM key on your apex. Your existing records are never edited. Verification usually lands in a few minutes, and you can set up the code below while you wait.

2. Create a key

Create an API key with the sending permission. It is shown once, so put it straight into your secrets. Export SENDPOSITORY_API_KEY before starting the app.

3. Install

Terminal
pip install flask requests

4. Send an email

Flask
import os
import requests
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.post("/contact")
def contact():
    res = requests.post(
        "https://api.sendpository.com/v1/emails",
        headers={"Authorization": f"Bearer {os.environ['SENDPOSITORY_API_KEY']}"},
        json={
            "from": "Your App <hello@mail.yourdomain.com>",
            "to": ["team@yourdomain.com"],
            "reply_to": [request.json["email"]],
            "subject": "New contact form message",
            "text": request.json["message"],
        },
        timeout=10,
    )
    return jsonify(res.json()), res.status_code

A success returns { "id": "..." } - the message’s id for looking it up later. A failure returns { "error": { "type", "message" } } with a 4xx or 5xx status.

Where the send belongs

Outside the request if you can. Flask's development server is single-threaded, so a blocking send during local testing makes the whole app appear to hang.

If you have no queue, a thread started from the view is enough for a low-volume form - but give it a timeout and log its failures, because nothing is watching it.

Testing it

Things to know

Questions

Why does my Flask app freeze when sending?

The development server is single-threaded, so a blocking send stalls the whole app. It disappears under a production WSGI server with multiple workers, but it is still worth moving the send off the request path.

How do I send email with Flask?

Verify your sending domain, create an API key, put it in an environment variable, and POST the message as JSON to https://api.sendpository.com/v1/emails from server-side Flask code. The example on this page runs as written once the domain is verified.

Can I send email with Flask without SMTP?

Yes. This is plain HTTPS, so Flask needs no mail library and no SMTP port - which matters on hosts that block outbound 25 and 587. Failures come back as a status code on the call instead of as a bounce message hours later.

More guides

Send your first email in minutes

6,000 emails a month (up to 200 a day), free forever. No card needed.