Confirming email change token for Identity / GoTrue

I’m trying to understand how to verify the ‘email_change_token’ that is generated by a GoTrue / Identity instance when a user’s email address is updated.

A couple of considerations –

  • I’m not using the Identity Widget and have a custom auth flow that is processing auth events manually.
  • I’m also not able to use the GoTrue-JS library and am creating similarly structured methods in serverless functions that hit the same GoTrue endpoints.

I see the email_change_token is passed back as URL fragment, similar to how confirmation_tokens and recovery_tokens are returned. For the latter two, I’m able to process these via the /verify endpoint.

Looking through the code of the GoTrue and GoTrue-JS repos, I can’t deduce what means or method is used to verify the email_change_token to complete the process of updating an email address.

@futuregerald @jonsully - It looks like you may have already peeked under the covers for this…

Could you, or anyone else, help shed light on this?


Hey @Clayton :wave:t2:

No worries on not using the out-of-the-box solutions. I wrote a pure-React library to interface with GoTrue so I was in the same shoes.

When someone changes their email address on file, Netlify sends a confirmation email to that new email address. When the user clicks the link in the confirmation email, they’re directed to your site with a token in the URL, keyed as email_change (I believe you know this much). To confirm the new email, you need to PUT to /user (the standard ‘update user’ function) with the token set under the email_change_token key in the payload.

Abstracting from my library and illustrating with a standard fetch, this ought to be something like:

fetch("", {
  method: 'PUT',
  Authorization: getUsersJWTBearer(),
  body: JSON.stringify({
      email_change_token: '12oi41h2oih1fonif1oi2n' //the value from the url

Want to give that a shot and see if it does the trick?


@jonsully you’re a scholar and a gentleman!

Thank you - that was exactly the information I needed :facepunch: