How to Use Notify with FastAPI

Send email from a FastAPI endpoint with httpx and x-api-key.

Send transactional email from FastAPI. Call Notify from the server so your API key stays private.

Prerequisites

  • API key — generated when you sign up
  • Verified domain (optional) — required for production sends from a custom from address
  • Python 3.9+, FastAPI, and an async HTTP client (httpx)

Install

pip install fastapi uvicorn httpx
NOTIFY_API_KEY=your_api_key_here

Send an email from an endpoint

import os
from typing import Optional

import httpx
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr

app = FastAPI()

NOTIFY_URL = "https://notify.cx/api/email/send"


class WelcomeEmail(BaseModel):
    to: EmailStr
    name: Optional[str] = None


@app.post("/api/send-welcome")
async def send_welcome(body: WelcomeEmail):
    name = body.name or "there"
    payload = {
        "to": body.to,
        "subject": "Welcome aboard",
        "message": f"<h1>Hi {name}!</h1><p>Thanks for signing up.</p>",
    }

    async with httpx.AsyncClient(timeout=30.0) as client:
        response = await client.post(
            NOTIFY_URL,
            headers={
                "Content-Type": "application/json",
                "x-api-key": os.environ["NOTIFY_API_KEY"],
            },
            json=payload,
        )

    data = response.json()
    if response.is_error:
        raise HTTPException(status_code=response.status_code, detail=data)

    return data

Run the app:

uvicorn main:app --reload

The message field accepts plain text or HTML. See Sending Emails.


Shared send helper

async def send_notify_email(
    *,
    to: str,
    subject: str,
    message: str,
    from_address: str | None = None,
) -> dict:
    payload = {"to": to, "subject": subject, "message": message}
    if from_address:
        payload["from"] = from_address

    async with httpx.AsyncClient(timeout=30.0) as client:
        response = await client.post(
            "https://notify.cx/api/email/send",
            headers={
                "Content-Type": "application/json",
                "x-api-key": os.environ["NOTIFY_API_KEY"],
            },
            json=payload,
        )

    data = response.json()
    if response.is_error:
        raise HTTPException(status_code=response.status_code, detail=data)
    return data

Where to next?