AWS Cognito Custom Email Sender Lambda Trigger — passing structured JSON payloads cleanly

We need to bypass AWS SES limits in AWS Cognito and send custom HTML signup verification emails via AutoSend using a KMS-encrypted Custom Email Sender Lambda Trigger. How is this configured?

How AWS Cognito Custom Email Sender Works

Cognito supports a CustomEmailSender Lambda trigger that intercepts verification codes and temporary passwords, encrypts the code using AWS KMS, and passes the event payload to your Lambda function.

Lambda Code Example (Node.js 18 / AWS SDK v3):

import { KMSClient, DecryptCommand } from "@aws-sdk/client-kms";

const kms = new KMSClient({});

export const handler = async (event: any) => {
  if (event.triggerSource === "CustomEmailSender_SignUp" || event.triggerSource === "CustomEmailSender_ForgotPassword") {
    // 1. Decrypt verification code encrypted by Cognito
    const command = new DecryptCommand({
      CiphertextBlob: Buffer.from(event.request.code, "base64"),
      EncryptionContext: { "cognito": event.userPoolId }
    });
    const { Plaintext } = await kms.send(command);
    const code = new TextDecoder().decode(Plaintext);

    // 2. Dispatch custom HTML email via AutoSend API
    await fetch("https://api.autosend.com/v1/mails/send", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.AUTOSEND_API_KEY}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        from: { email: "auth@yourdomain.com", name: "Security Team" },
        to: { email: event.request.userAttributes.email },
        subject: "Your Verification Code",
        html: `<h2>Welcome!</h2><p>Your verification code is <strong>${code}</strong></p>`
      })
    });
  }
};

Key Setup Steps in AWS Console:

  • Grant the Cognito User Pool permission to invoke your Lambda function.
  • Ensure the Lambda function environment variable AUTOSEND_API_KEY is set.
  • Assign kms:Decrypt IAM policy permissions to the Lambda execution role.