Generate an email link (admin)
Generate magic-link / recovery / invite / signup URLs without sending the email.
Generate a one-time auth link (and its underlying OTP) without GoTrue sending the email itself. Use this when you want to ship the link through your own transactional email provider, embed it in a Slack message, or surface it in a back-office tool. The type parameter switches between the different flows GoTrue supports.
Service-role key required
This endpoint requires the project's service_role key. Never call it from a browser, mobile app, or any client you don't fully control.
Signature
supabase.auth.admin.generate_link(params)params is a hash. Pass it as a literal ({ type: "magiclink", email: "..." }) or use Ruby's hash-literal shorthand.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
type | String | Required | One of "signup", "invite", "magiclink", "recovery", "email_change_current", or "email_change_new". Determines which other fields are required and what kind of link is produced. |
email | String | Required | Target email address. Required for every link type. |
password | String | Optional | Required only when type is "signup". Sets the user's initial password as part of the link payload. |
new_email | String | Optional | Required only when type is "email_change_current" or "email_change_new". The address the user is moving to. |
options | Hash | Optional | Optional flow-modifying options — see keys below. |
options keys
| Name | Type | Required | Description |
|---|---|---|---|
data | Hash | Optional | Seed user_metadata. Only honored for type "signup" and "invite" (when the link will actually create a user). |
redirect_to | String | Optional | Where the resulting action_link should send the user after the token is consumed. Must match your Redirect URLs allowlist. |
Returns
A Struct with :properties (a GenerateLinkProperties Struct exposing :action_link, :email_otp, :hashed_token, :redirect_to, :verification_type) and :user (the affected Types::User). The :action_link is the URL you'll typically paste into your own email template; :email_otp is the bare 6-digit code if you want to display it directly; :hashed_token is what's used internally by verify_otp when token_hash: is passed.
Example — generate a magic link to send via your own email provider
response = supabase.auth.admin.generate_link(
type: "magiclink",
email: "ada@example.com",
options: { redirect_to: "https://app.example.com/auth/callback" }
)
action_link = response.properties.action_link
email_otp = response.properties.email_otp # "123456"
# Hand action_link to your own SendGrid/Postmark/Resend pipeline:
Mailer.deliver(to: "ada@example.com", subject: "Sign in", body: <<~HTML)
Click <a href="#{action_link}">here</a> to sign in,
or enter this code: <strong>#{email_otp}</strong>
HTMLExample — generate a signup confirmation link (with password)
response = supabase.auth.admin.generate_link(
type: "signup",
email: "new@example.com",
password: "correct horse battery staple",
options: {
data: { display_name: "Newcomer" },
redirect_to: "https://app.example.com/welcome"
}
)
# The user is created (unconfirmed) and you receive an action_link
# they must click to confirm. Useful for "self-serve signup via Slack".
puts response.properties.action_link
puts response.user.email # => "new@example.com"
puts response.user.email_confirmed_at # => nil (still needs confirmation)Example — generate a password recovery link
response = supabase.auth.admin.generate_link(
type: "recovery",
email: "ada@example.com",
options: { redirect_to: "https://app.example.com/reset" }
)
# The link sends the user to /reset, where you'd then call
# update_user(password: "...") on their behalf.
puts response.properties.action_linkExample — generate an email-change confirmation link
# Send the user (on their *current* address) a confirmation link.
supabase.auth.admin.generate_link(
type: "email_change_current",
email: "old@example.com",
new_email: "new@example.com"
)
# Then ALSO send a confirmation to the *new* address (GoTrue's "double opt-in"):
supabase.auth.admin.generate_link(
type: "email_change_new",
email: "old@example.com",
new_email: "new@example.com"
)options[:redirect_to] is merged into the request URL's query string (not the JSON body). The returned GenerateLinkResponse Struct exposes properties.action_link, properties.email_otp, properties.hashed_token, properties.redirect_to, properties.verification_type, plus the user Struct.