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 fastapiSend
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.