supabase-rb-rb
Auth

Verify and log in through OTP

Verify a one-time password (or email confirmation link) and produce a session.

Submit the code or token a user received from sign_in_with_otp, an email confirmation link, an SMS, or a password-recovery email to GoTrue's POST /verify endpoint. On success the user is signed in, the session is persisted, and a SIGNED_IN event is emitted.

Two related input modes:

  • token: + (email: or phone:) — the 6-digit code path (used by SMS and email OTPs).
  • token_hash: (no email/phone needed) — the link path, where the hashed token comes from the URL query string of a magic link / confirmation / recovery email.

Signature

supabase.auth.verify_otp(params)

params is a hash — pass a literal or use Ruby's hash-literal shorthand.

Parameters

NameTypeRequiredDescription
typeStringRequiredOTP type: "signup", "magiclink", "recovery", "invite", "email_change" for email flows; "sms", "phone_change" for phone flows; "email" for token_hash link flows.
emailStringOptionalUser email. Required with token: for email-OTP flows; ignored when token_hash: is provided.
phoneStringOptionalUser phone number in E.164 format. Required with token: for SMS flows; ignored when token_hash: is provided.
tokenStringOptional6-digit code the user received. Mutually exclusive with token_hash:.
token_hashStringOptionalHashed token from a magic-link / confirmation / recovery URL. Used in place of token: + email/phone for link-based flows.
optionsHashOptionalNested options: redirect_to (String, post-verification redirect for link flows), captcha_token (String).

Returns

Returns
Supabase::Auth::Types::AuthResponse

A Struct with :user and :session. On successful verification both are populated; the session is also saved to the configured storage and SIGNED_IN is dispatched to every on_auth_state_change subscriber.

response = supabase.auth.verify_otp(
  email: "ada@example.com",
  token: "123456",
  type: "email"
)

response.user.email           # => "ada@example.com"
response.session.access_token # => "eyJ..."

Example — verify an SMS code

response = supabase.auth.verify_otp(
  phone: "+15555550123",
  token: "123456",
  type: "sms"
)
# Your callback page receives ?token_hash=...&type=email in the URL.
response = supabase.auth.verify_otp(
  token_hash: params[:token_hash],
  type: params[:type] # e.g. "email" or "recovery"
)

response.session.access_token

Example — verify a password-recovery code

# After reset_password_for_email lands the user with a code:
response = supabase.auth.verify_otp(
  email: "ada@example.com",
  token: "654321",
  type: "recovery"
)

# Now update_user can be called against the recovered session.
supabase.auth.update_user(password: "new-strong-password-2026")

On success the returned session is saved and SIGNED_IN is dispatched. Invalid or expired codes surface as Supabase::Auth::Errors::AuthApiError.

On this page