supabase-rb-rb
Auth

Sign in a user through OTP

Send a magic-link or SMS one-time password.

Trigger a passwordless sign-in by sending the user a one-time code (or magic link, for email). The user completes sign-in by calling verify_otp with the code, or by clicking the magic link in the email.

By default, GoTrue will create the user if no account exists. Pass options: { should_create_user: false } to require an existing account.

Signature

supabase.auth.sign_in_with_otp(credentials)

credentials is a hash — call with a literal ({ email: "..." }) or Ruby's hash-literal shorthand (email: "...").

Parameters

NameTypeRequiredDescription
emailStringOptionalUser email. Provide either email or phone.
phoneStringOptionalUser phone number in E.164 format. Provide either email or phone.
optionsHashOptionalNested options: email_redirect_to (String, URL embedded in the magic link), should_create_user (Boolean, default true, set false to require an existing account), data (Hash, user_metadata applied if the user is created), channel (String, sms or whatsapp for phone OTP; defaults to sms), captcha_token (String).

Returns

Returns
Supabase::Auth::Types::AuthOtpResponse

A Struct with :message_id, :user, and :session. For magic-link / OTP flows the user and session fields are nil until the code is verified — only message_id is populated.

response = supabase.auth.sign_in_with_otp(
  email: "ada@example.com",
  options: { email_redirect_to: "https://app.example.com/auth/callback" }
)

response.message_id   # => "..."

Example — SMS OTP

response = supabase.auth.sign_in_with_otp(
  phone: "+15555550123",
  options: { channel: "sms" }
)

# Later, after the user reads the SMS:
supabase.auth.verify_otp(
  phone: "+15555550123",
  token: "123456",
  type: "sms"
)

Example — require an existing account

response = supabase.auth.sign_in_with_otp(
  email: "ada@example.com",
  options: { should_create_user: false }
)

Missing both email and phone raises Supabase::Auth::Errors::AuthInvalidCredentialsError. verify_otp is the second step.

On this page