Send email with FastAPI

An async endpoint that answers immediately and sends in the background.

You need a verified sending domain and an API key from Settings › API Keys. If neither exists yet, the quickstart covers both in a couple of minutes.

Install

pip install sending-sdk fastapi

Send

import os
from fastapi import BackgroundTasks, FastAPI
from sending import Sending
 
app = FastAPI()
client = Sending(api_key=os.environ["SENDING_API_KEY"])
 
def deliver(email: str, user_id: str) -> None:
    client.emails.send({
        "from": "Acme <[email protected]>",
        "to": email,
        "subject": "Welcome",
        "html": "<p>You're in.</p>",
        "idempotencyKey": f"welcome-{user_id}",
    })
 
@app.post("/signup")
async def signup(email: str, user_id: str, tasks: BackgroundTasks):
    tasks.add_task(deliver, email, user_id)
    return {"queued": True}

A successful call answers 202 with the message id: accepted and queued, not yet delivered. Delivery, opens, bounces and complaints arrive later, on webhooks or in the dashboard.

What changes in FastAPI

Sending is already asynchronous on our side: the API accepts the message and a worker delivers it. A background task here only keeps your own request fast.

The thing that catches people

Calling a blocking client directly inside an async def endpoint stalls the event loop for the whole process. Either use a background task, as above, or run it in a thread.

Next

  • All the fields: cc and bcc, reply-to, attachments, templates, scheduling.
  • Webhooks: delivery, bounce and complaint events, signed with HMAC.
  • Domains: SPF, DKIM and MAIL FROM, and why sending is refused until they are in place.
  • MCP: the same operations as tools, when the one writing the code is an agent.

Nearby: Python

All 30 stacks