Confirm a storefront customer's email address
Consumes a single-use email-verification token (constant-time compared, TTL and bound-address checked in the service), flips `email_verified` to true and `has_account` to true, which is what makes retro-linked guest bookings visible in `me`. An invalid, expired, already-consumed, or address-mismatched token returns a uniform 400 (no oracle). Behind the publishable key, the `customer_accounts` flag, and the customer-auth rate-limit bucket. Returns 200 with `{ emailVerified: true }`. This is NO LONGER part of account creation, and the distinction matters: since the C2 account activation hardening an account comes into existence at `activation/confirm`, which sets the credential, `email_verified` and `has_account` together in one transaction. `register` claims nothing, so the "claimed guest row completes here" flow this endpoint was built for no longer exists. What remains is ONLY the pre-hardening rows that still carry a token minted under the old flow: no live path mints a verification token any more, because `resendVerification` is the sole issuer and is itself a no-op in every reachable case (see its JSDoc). There is no buyer-facing email-change flow to serve either. It deliberately does not check WHO installed the password, which is exactly why `resendVerification` refuses to mint a fresh token for a password-backed unverified row: that combination only exists in the legacy compromised population, and re-arming it here would let the victim's click complete a takeover the attacker started. > **Note:** This endpoint requires the e-commerce feature to be enabled on your site.
/customers/verify-emailhttps://api.lynkow.com/storefront/{siteId}Request bodyrequired
tokenstringrequiredRequired. Min 1 character