AWS Cognito · Python

Block disposable email in AWS Cognito

Attach a Lambda to the PreSignUp trigger of your Cognito User Pool. The Lambda runs synchronously and can throw to reject before the user record is written.

The code

# lambda_function.py
import json
import os
import urllib.request

PIISEND_URL = "https://api.piisend.com/api/v1/intelligence/email"

def is_disposable(email: str) -> bool:
    try:
        req = urllib.request.Request(
            PIISEND_URL,
            data=json.dumps({"email": email}).encode(),
            headers={
                "Authorization": f"Bearer {os.environ['PIISEND_API_KEY']}",
                "Content-Type": "application/json",
            },
            method="POST",
        )
        with urllib.request.urlopen(req, timeout=5) as resp:
            data = json.loads(resp.read())
            return data.get("signals", {}).get("disposable") is True
    except Exception:
        return False  # fail open

def lambda_handler(event, context):
    email = event["request"]["userAttributes"].get("email", "")
    if email and is_disposable(email):
        raise Exception("Please use a permanent email address.")
    return event

API key

Set `PIISEND_API_KEY` in Lambda environment variables or Secrets Manager.

Fail-open vs fail-closed

Returning False on errors allows signup — adjust for your risk model.

Pair with verification

Attach to PreSignUp trigger; test with Cognito hosted UI and API signUp flows.

Send verification email with Piisend

After blocking disposable addresses, send OTP and verification mail through the same Piisend account. One API key for intelligence checks and transactional sends.