Email verification
Require a confirmed email address before anybody signs in — what each sign-in method does, the confirmation page, and switching it on safely.
An environment can refuse to finish a sign-in until the person has confirmed their email address. It is off by default. Switch it on under Settings → Security & sign-up policy → Email verification, the first section of the policy card. Sandbox and Production each have their own setting; the section says which one you are editing.
The section also shows how many people in that environment have not confirmed their address. Those are the people who will see the confirmation page at their next sign-in, so check the number before you save.
On the API it is requireEmailVerification on the environment's auth policy.
What a person sees
Somebody who signs in correctly with an address that is not confirmed is not
sent back to your application. The hosted page stops them on Confirm your
email address, shows the address masked (r•••@gmail.com), and emails a new
link straight away.
- Send another link sends a new one. It is throttled to one a minute and five a day for each account, counting the mail sent at sign-up, and the page says the same thing whether or not a mail went out.
- Opening the link in the same browser finishes the sign-in that was
waiting. If the account has a second factor, it is asked for first. The
person then lands on your application's
redirect_uriwith itsstate, the same as any other sign-in. - Opening the link somewhere else, such as a phone's mail app, confirms the address and offers Sign in back into the same application. It does not sign anybody in by itself, because the link proves only the inbox.
- I have confirmed it — continue checks again, for somebody who opened the link in another tab.
The page is shown only after the password, code or passkey was right. Showing it to anybody else would let the form be used to find out which addresses signed up and never confirmed.
Each sign-in method
| Method | What happens |
|---|---|
| Password | Stopped until the address is confirmed |
| Text message | Stopped. A phone code proves the phone, not the inbox |
| Passkey | Stopped. A passkey proves the device, not the inbox |
| Social sign-in | Not stopped when the provider confirms the address (such as Google) |
| Social, provider cannot vouch | Stopped. X, Twitch and Roblox share no verified flag |
| Magic link | Never stopped. Opening the link confirms the address |
| Emailed second-factor code | Answering a code sent to the account's own address confirms it |
| Password reset | Finishing a reset confirms the address |
| Enterprise SSO | Not affected. The identity provider decides |
| An existing Base316 session | Not used to skip the page. The person signs in again and is stopped there |
| A new sign-up on hosted pages | Stopped right after creating the account. The sign-up mail is the link |
An account with no email address, such as one created by text message, is never stopped. There is nothing to confirm.
When a social provider confirms the address, the account is marked confirmed on every sign-in, including accounts that already existed. Someone who signed up with a password and never opened the mail is confirmed the first time they choose Continue with Google.
On the API
Your own sign-in screens get the same answer from the same rule.
POST /v1/auth/signin, /v1/auth/phone/verify, /v1/auth/mfa/verify,
/v1/auth/mfa/required/complete and /v1/auth/passkeys/signin/finish
answer 403 with reason EMAIL_NOT_VERIFIED instead of a session. With the
SDK this is a Base316Error whose reason is "EMAIL_NOT_VERIFIED".
<SignIn /> in @base316/react already shows it. Confirm the address with
POST /v1/auth/verify-email and the token from the link.
Switching this on stops everybody counted in the section until they open a link. Most will find the mail and carry on. Some addresses will bounce. Look at the count first, and switch it on in Sandbox before Production.

