Proxy Mail QA

Test Amazon Cognito emails

Amazon Cognito user pools email a code or link to confirm sign-up, a code to reset a forgotten password and a temporary password when you invite someone. To test them, sign up with a fresh Proxy Mail QA address and the code or link shows up on its row. Watch the default sender: it sends only 50 emails a day per AWS account.

Updated

Details below are from the Amazon Cognito, Amazon SES and AWS Amplify documentation on 29 October 2026. Check them for current details.

What Cognito sends

Email Sent when Holds Valid for
Sign-up confirmation Someone signs up, or asks for the code again A code, or a link if you choose links 24 hours
Forgotten password Someone asks to reset their password, or an admin resets it A code 1 hour
Invitation You create the user yourself The username and a temporary password 7 days by default
Attribute verification Someone changes their email address A code 24 hours
Sign-in code Email MFA, or passwordless sign-in with a one-time code A code Minutes: an MFA code lasts 3 by default, up to 15

The invitation comes from AdminCreateUser, and an admin reset (AdminResetUserPassword) sends the same email as ForgotPassword. Sign-in codes by email need the Essentials or Plus feature plan and your user pool sending with your own Amazon SES. The forgotten-password and email-change emails use the same template as the sign-up code, so they look alike.

First: the default sender sends 50 emails a day

A new user pool sends from no-reply@verificationemail.com, Cognito’s own sender. It sends to any address, so a test inbox gets the mail, but only 50 emails a day per AWS account, and the count resets at 09:00 UTC. A test suite that signs up a few dozen accounts uses that up, and the emails stop until the next reset.

For anything more than trying it out, send with Amazon SES: in the user pool, open Authentication methods → Email configuration, choose Edit, and pick a From address you’ve verified in SES.

Then: take your own SES out of the sandbox

A new Amazon SES account starts in the sandbox, which only delivers to verified addresses and domains, in each Region separately. Cognito hands the email to SES, and SES won’t send it to a test inbox. Request production access in the SES console for the Region your user pool sends from. Test email not arriving? covers SES and the other providers.

Amplify Gen 2

defineAuth sets the same things in code. verificationEmailStyle picks a code ('CODE') or a link ('LINK') for sign-up, and senders.email sends from your own SES address instead of the default sender:

amplify/auth/resource.ts
import { defineAuth } from '@aws-amplify/backend';

export const auth = defineAuth({
  loginWith: {
    email: {
      verificationEmailStyle: 'CODE',
      verificationEmailSubject: 'Your Acme verification code',
      verificationEmailBody: (createCode) => `Your Acme verification code is ${createCode()}.`,
    },
  },
  senders: {
    email: {
      fromEmail: 'no-reply@acme.example',
      fromName: 'Acme',
    },
  },
});

The From address has to be verified in Amazon SES, and Amplify’s docs say to request production access first.

Test it by hand

  1. Create an address in Proxy Mail QA.
  2. Sign up in your app with it.
  3. The code or link appears on the address’s row within seconds. From the default sender, the row names the service as Amazon Cognito.

Then try a forgotten password and an email change. An invitation holds a temporary password rather than a code, so open it in the address’s inbox to read it.

Automate it

signup.spec.ts
import { test, expect } from 'proxymail-qa/playwright';

test('Cognito sign-up sends a working code', async ({ page, qa }) => {
  const { address, password } = await qa.createAddress({ password: true });
  const submitted = new Date();
  await page.goto('/signup');
  await page.getByLabel('Email').fill(address);
  await page.getByLabel('Password').fill(password);
  await page.getByRole('button', { name: 'Create account' }).click();

  const { value: code } = await qa.waitForCode(address, { since: submitted });
  await page.getByLabel('Confirmation code').fill(code);
  await page.getByRole('button', { name: 'Confirm' }).click();
  await expect(page.getByText('Welcome')).toBeVisible();
});

Match the labels to your sign-up page. The generated password is 16 characters with every kind a Cognito password policy can require: upper and lower case letters, a number and a symbol. In a reset test, pass since the moment you asked for the reset: the reset email looks like the sign-up one, and since makes sure the wait returns the new code. More in Test sign-up emails in Playwright.

Try it on your next sign-up test

Free plan, no credit card. Create an address and watch the code or link arrive.

Create a free accountOpen the app

Questions

Why did Cognito stop sending emails?

The default email sender, no-reply@verificationemail.com, sends at most 50 emails a day per AWS account, and the count resets at 09:00 UTC. Until then, sign-up and reset emails stop. Switch the user pool to send with Amazon SES and your SES account's limits apply instead.

Why don't emails from my own Amazon SES address arrive?

Your SES account is probably still in the sandbox, which only delivers to verified addresses and domains. Request production access for the Region you send from. Until then the email never leaves AWS, and Proxy Mail QA shows that nothing has reached the address.

How long does a Cognito code last?

A sign-up code or link lasts 24 hours, a forgotten-password code 1 hour and an email MFA code 3 minutes by default. Ask for a new code and Proxy Mail QA marks the older one as replaced.

Code or link?

Choose in the user pool's verification message settings, or with verificationEmailStyle in Amplify. Only the sign-up email can hold a link, which goes to your user pool's domain to confirm the account. Password resets and email changes always send a code.

See every email testing problem we solve

Amazon Web Services, AWS, Amazon Cognito, Amazon SES and AWS Amplify are trademarks of Amazon.com, Inc. or its affiliates. Proxy Mail QA is independent and isn’t affiliated with or endorsed by them.