Email verification looks like a simple two-request feature: create a user, send a code, then accept the code. In a real REST API, the hard part is the boundary between those requests. Email delivery can be delayed, clients retry after a timeout, and a user can open two verification links at nearly the same time.
I model that boundary as a short-lived verification lease. The lease gives one verification attempt an owner, an expiration time, and an idempotency key. This makes retries boring: the API can return the same result for the same operation instead of creating more codes or moving the account through an unexpected state.
Why email verification needs a lease
A verification token is not only a secret. It is also a claim about state: which account requested it, when it was created, whether it was consumed, and which request is allowed to consume it.…