diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift
index 5e14aa02..2217b088 100644
--- a/Sources/Auth/AuthClient.swift
+++ b/Sources/Auth/AuthClient.swift
@@ -457,6 +457,76 @@ public actor AuthClient {
     )
   }
 
+  /// Attempts a single-sign on using an enterprise Identity Provider.
+  /// - Parameters:
+  ///   - domain: The email domain to use for signing in.
+  ///   - redirectTo: The URL to redirect the user to after they sign in with the third-party
+  /// provider.
+  ///   - captchaToken: The captcha token to be used for captcha verification.
+  /// - Returns: A URL that you can use to initiate the provider's authentication flow.
+  public func signInWithSSO(
+    domain: String,
+    redirectTo: URL? = nil,
+    captchaToken: String? = nil
+  ) async throws -> SSOResponse {
+    await sessionManager.remove()
+
+    let (codeChallenge, codeChallengeMethod) = prepareForPKCE()
+
+    return try await api.execute(
+      Request(
+        path: "/sso",
+        method: .post,
+        body: configuration.encoder.encode(
+          SignInWithSSORequest(
+            providerId: nil,
+            domain: domain,
+            redirectTo: redirectTo,
+            gotrueMetaSecurity: captchaToken.map { AuthMetaSecurity(captchaToken: $0) },
+            codeChallenge: codeChallenge,
+            codeChallengeMethod: codeChallengeMethod
+          )
+        )
+      )
+    )
+    .decoded(decoder: configuration.decoder)
+  }
+
+  /// Attempts a single-sign on using an enterprise Identity Provider.
+  /// - Parameters:
+  ///   - providerId: The ID of the SSO provider to use for signing in.
+  ///   - redirectTo: The URL to redirect the user to after they sign in with the third-party
+  /// provider.
+  ///   - captchaToken: The captcha token to be used for captcha verification.
+  /// - Returns: A URL that you can use to initiate the provider's authentication flow.
+  public func signInWithSSO(
+    providerId: String,
+    redirectTo: URL? = nil,
+    captchaToken: String? = nil
+  ) async throws -> SSOResponse {
+    await sessionManager.remove()
+
+    let (codeChallenge, codeChallengeMethod) = prepareForPKCE()
+
+    return try await api.execute(
+      Request(
+        path: "/sso",
+        method: .post,
+        body: configuration.encoder.encode(
+          SignInWithSSORequest(
+            providerId: providerId,
+            domain: nil,
+            redirectTo: redirectTo,
+            gotrueMetaSecurity: captchaToken.map { AuthMetaSecurity(captchaToken: $0) },
+            codeChallenge: codeChallenge,
+            codeChallengeMethod: codeChallengeMethod
+          )
+        )
+      )
+    )
+    .decoded(decoder: configuration.decoder)
+  }
+
   /// Log in an existing user by exchanging an Auth Code issued during the PKCE flow.
   public func exchangeCodeForSession(authCode: String) async throws -> Session {
     guard let codeVerifier = try codeVerifierStorage.getCodeVerifier() else {
@@ -945,29 +1015,29 @@ public actor AuthClient {
   }
 
   private func prepareForPKCE() -> (codeChallenge: String?, codeChallengeMethod: String?) {
-    if configuration.flowType == .pkce {
-      let codeVerifier = PKCE.generateCodeVerifier()
-
-      do {
-        try codeVerifierStorage.storeCodeVerifier(codeVerifier)
-      } catch {
-        assertionFailure(
-          """
-          An error occurred while storing the code verifier,
-          PKCE flow may not work as expected.
-
-          Error: \(error.localizedDescription)
-          """
-        )
-      }
+    guard configuration.flowType == .pkce else {
+      return (nil, nil)
+    }
+
+    let codeVerifier = PKCE.generateCodeVerifier()
 
-      let codeChallenge = PKCE.generateCodeChallenge(from: codeVerifier)
-      let codeChallengeMethod = codeVerifier == codeChallenge ? "plain" : "s256"
+    do {
+      try codeVerifierStorage.storeCodeVerifier(codeVerifier)
+    } catch {
+      assertionFailure(
+        """
+        An error occurred while storing the code verifier,
+        PKCE flow may not work as expected.
 
-      return (codeChallenge, codeChallengeMethod)
+        Error: \(error.localizedDescription)
+        """
+      )
     }
 
-    return (nil, nil)
+    let codeChallenge = PKCE.generateCodeChallenge(from: codeVerifier)
+    let codeChallengeMethod = codeVerifier == codeChallenge ? "plain" : "s256"
+
+    return (codeChallenge, codeChallengeMethod)
   }
 
   private func isImplicitGrantFlow(url: URL) -> Bool {
diff --git a/Sources/Auth/Types.swift b/Sources/Auth/Types.swift
index 9da70cbf..a6ea0e7e 100644
--- a/Sources/Auth/Types.swift
+++ b/Sources/Auth/Types.swift
@@ -664,3 +664,18 @@ public enum MessagingChannel: String, Codable, Sendable {
   case sms
   case whatsapp
 }
+
+struct SignInWithSSORequest: Encodable {
+  let providerId: String?
+  let domain: String?
+  let redirectTo: URL?
+  let gotrueMetaSecurity: AuthMetaSecurity?
+  let codeChallenge: String?
+  let codeChallengeMethod: String?
+}
+
+public struct SSOResponse: Codable, Hashable, Sendable {
+  /// URL to open in a browser which will complete the sign-in flow by taking the user to the
+  /// identity provider's authentication flow.
+  public let url: URL
+}
diff --git a/Tests/AuthTests/RequestsTests.swift b/Tests/AuthTests/RequestsTests.swift
index 4c5851b4..13c7a383 100644
--- a/Tests/AuthTests/RequestsTests.swift
+++ b/Tests/AuthTests/RequestsTests.swift
@@ -375,6 +375,30 @@ final class RequestsTests: XCTestCase {
     }
   }
 
+  func testSignInWithSSOUsingDomain() async {
+    let sut = makeSUT()
+
+    await assert {
+      _ = try await sut.signInWithSSO(
+        domain: "supabase.com",
+        redirectTo: URL(string: "https://supabase.com"),
+        captchaToken: "captcha-token"
+      )
+    }
+  }
+
+  func testSignInWithSSOUsingProviderId() async {
+    let sut = makeSUT()
+
+    await assert {
+      _ = try await sut.signInWithSSO(
+        providerId: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F",
+        redirectTo: URL(string: "https://supabase.com"),
+        captchaToken: "captcha-token"
+      )
+    }
+  }
+
   private func assert(_ block: () async throws -> Void) async {
     do {
       try await block()
diff --git a/Tests/AuthTests/__Snapshots__/RequestsTests/testSignInWithSSOUsingDomain.1.txt b/Tests/AuthTests/__Snapshots__/RequestsTests/testSignInWithSSOUsingDomain.1.txt
new file mode 100644
index 00000000..5c0e1139
--- /dev/null
+++ b/Tests/AuthTests/__Snapshots__/RequestsTests/testSignInWithSSOUsingDomain.1.txt
@@ -0,0 +1,7 @@
+curl \
+	--request POST \
+	--header "Apikey: dummy.api.key" \
+	--header "Content-Type: application/json" \
+	--header "X-Client-Info: gotrue-swift/x.y.z" \
+	--data "{\"domain\":\"supabase.com\",\"gotrue_meta_security\":{\"captcha_token\":\"captcha-token\"},\"redirect_to\":\"https:\/\/supabase.com\"}" \
+	"http://localhost:54321/auth/v1/sso"
\ No newline at end of file
diff --git a/Tests/AuthTests/__Snapshots__/RequestsTests/testSignInWithSSOUsingProviderId.1.txt b/Tests/AuthTests/__Snapshots__/RequestsTests/testSignInWithSSOUsingProviderId.1.txt
new file mode 100644
index 00000000..8fbbf196
--- /dev/null
+++ b/Tests/AuthTests/__Snapshots__/RequestsTests/testSignInWithSSOUsingProviderId.1.txt
@@ -0,0 +1,7 @@
+curl \
+	--request POST \
+	--header "Apikey: dummy.api.key" \
+	--header "Content-Type: application/json" \
+	--header "X-Client-Info: gotrue-swift/x.y.z" \
+	--data "{\"gotrue_meta_security\":{\"captcha_token\":\"captcha-token\"},\"provider_id\":\"E621E1F8-C36C-495A-93FC-0C247A3E6E5F\",\"redirect_to\":\"https:\/\/supabase.com\"}" \
+	"http://localhost:54321/auth/v1/sso"
\ No newline at end of file