Skip to main content
Docs

Social connections, also known as OAuth connections in Clerk, allow users to gain access to your application by using their existing credentials from an Identity Provider (IdP), like Google or Microsoft. For example, if you enable Google as a social provider, then when a user wants to sign in to your application, they can select Google and use their Google account to sign in.

Note

When using social connections, the sign-up and sign-in flows are equivalent. If a user doesn't have an account and tries to sign in, an account will be made for them, and vice versa.

Configure social connections in the Clerk Dashboard and use the Clerk Backend API to read connected accounts and fetch OAuth access tokens for signed-in users.

Enable a social connection

Development instances

For development instances, Clerk uses pre-configured shared OAuth credentials and redirect URIs to make the development flow as smooth as possible. This means that you can enable most social providers without additional configuration.

To enable a social connection:

  1. In the Clerk Dashboard, navigate to the SSO connections page.
  2. Select the Add connection button, and select For all users.
  3. Select the provider you want to use.

Production instances

For production instances, you will need to configure the provider with custom OAuth credentials. See the list of supported providers below for provider-specific setup instructions.

Configure additional OAuth scopes

Each OAuth provider requires a specific set of scopes that are necessary for proper authentication with Clerk. These essential scopes are pre-configured and automatically included by Clerk. They typically include permissions for basic profile information and email access, which are fundamental for user authentication and account creation.

In addition to the core scopes, you can specify additional scopes supported by the provider. These scopes can be used to access additional user data from the provider.

To add additional OAuth scopes, when you are enabling a new social connection, enable Use custom credentials. The Scopes field will appear.

Get an OAuth access token for a social provider

You can use a social provider's OAuth to access user data from that provider in addition to their data from Clerk.

Use the getUserOauthAccessToken() method to get the user's OAuth access token. This method must be used in a server environment, and cannot be run on the client.

Note

Clerk does not automatically keep OAuth access tokens fresh behind the scenes. When you request an access token using the relevant backend API endpoint, Clerk will attempt to obtain a fresh access token as well as a new refresh token. However, this process occurs only when you initiate the request; Clerk does not proactively refresh tokens on your behalf.

The following example demonstrates how to retrieve the OAuth access token for a user and use it to fetch user data from the Notion API. It assumes:

If your SDK isn't listed, you can use the comments in the example to help you adapt it to your SDK.

app/api/notion/route.tsx
import { auth, clerkClient } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'

export async function GET() {
  // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { isAuthenticated, userId } = await auth()

  // Protect the route from unauthenticated users
  if (!isAuthenticated) {
    return NextResponse.json({ message: 'User not authenticated' }, { status: 401 })
  }

  const provider = 'notion'

  // Initialize clerkClient
  const client = await clerkClient()

  // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token
  const clerkResponse = await client.users.getUserOauthAccessToken(userId, provider)
  const accessToken = clerkResponse.data[0]?.token ?? ''
  if (!accessToken) {
    return NextResponse.json({ message: 'Access token not found' }, { status: 401 })
  }

  // Fetch the user data from the Notion API
  // This endpoint fetches a list of users
  // https://developers.notion.com/reference/get-users
  const notionUrl = 'https://api.notion.com/v1/users'

  const notionResponse = await fetch(notionUrl, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Notion-Version': '2022-06-28',
    },
  })

  // Handle the response from the Notion API
  const notionData = await notionResponse.json()

  return NextResponse.json({ message: notionData })
}
src/api/notion.ts
import { clerkClient } from '@clerk/astro/server'
import type { APIRoute } from 'astro'

export const GET: APIRoute = async (context) => {
  // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { isAuthenticated, userId } = context.locals.auth()

  // Protect the route from unauthenticated users
  if (!isAuthenticated) {
    return new Response('Unauthorized', { status: 401 })
  }

  const provider = 'notion'

  // Initialize clerkClient
  // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token
  const clerkResponse = await clerkClient(context).users.getUserOauthAccessToken(userId, provider)
  const accessToken = clerkResponse.data[0]?.token ?? ''
  if (!accessToken) {
    return new Response('Access token not found', { status: 401 })
  }

  // Fetch the user data from the Notion API
  // This endpoint fetches a list of users
  // https://developers.notion.com/reference/get-users
  const notionUrl = 'https://api.notion.com/v1/users'

  const notionResponse = await fetch(notionUrl, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Notion-Version': '2022-06-28',
    },
  })

  // Handle the response from the Notion API
  const notionData = await notionResponse.json()

  // Return the Notion data
  return new Response(JSON.stringify({ notionData }))
}
notion.js
import { createClerkClient, getAuth } from '@clerk/express'
import express from 'express'

const app = express()
// Initialize clerkClient
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })

app.get('/user', async (req, res) => {
  // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { isAuthenticated, userId } = getAuth(req)

  // Protect the route from unauthenticated users
  if (!isAuthenticated) {
    return res.status(401).json({ error: 'User not authenticated' })
  }

  const provider = 'notion'

  // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token
  const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider)
  const accessToken = clerkResponse.data[0]?.token ?? ''
  if (!accessToken) {
    return res.status(401).json({ error: 'Access token not found' })
  }

  // Fetch the user data from the Notion API
  // This endpoint fetches a list of users
  // https://developers.notion.com/reference/get-users
  const notionUrl = 'https://api.notion.com/v1/users'

  const notionResponse = await fetch(notionUrl, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Notion-Version': '2022-06-28',
    },
  })

  // Handle the response from the Notion API
  const notionData = await notionResponse.json()

  // Return the Notion data
  res.json(notionData)
})
import { createClerkClient } from '@clerk/backend'

// Initialize clerkClient
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })

async function getNotionData(request) {
  // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { isAuthenticated, userId } = request.auth

  // Protect the route from unauthenticated users
  if (!isAuthenticated) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }

  // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token
  const provider = 'notion'
  const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider)
  const accessToken = clerkResponse.data[0]?.token ?? ''
  if (!accessToken) {
    return Response.json({ error: 'Access token not found' }, { status: 403 })
  }

  // Fetch the user data from the Notion API
  // This endpoint fetches a list of users
  // https://developers.notion.com/reference/get-users
  const notionUrl = 'https://api.notion.com/v1/users'

  const notionResponse = await fetch(notionUrl, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Notion-Version': '2022-06-28',
    },
  })

  // Handle the response from the Notion API
  const notionData = await notionResponse.json()

  // Return the Notion data
  return notionData
}
app/routes/notion.tsx
import { clerkClient, getAuth } from '@clerk/react-router/server'
import type { Route } from './+types/notion'

export async function loader(args: Route.LoaderArgs) {
  // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { isAuthenticated, userId } = await getAuth(args)

  // Protect the route from unauthenticated users
  if (!isAuthenticated) {
    return new Response('User not authenticated', {
      status: 401,
    })
  }

  const provider = 'notion'

  // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token
  const clerkResponse = await clerkClient(args).users.getUserOauthAccessToken(userId, provider)
  const accessToken = clerkResponse.data[0]?.token ?? ''
  if (!accessToken) {
    return new Response('Access token not found', {
      status: 401,
    })
  }

  // Fetch the user data from the Notion API
  // This endpoint fetches a list of users
  // https://developers.notion.com/reference/get-users
  const notionUrl = 'https://api.notion.com/v1/users'

  const notionResponse = await fetch(notionUrl, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Notion-Version': '2022-06-28',
    },
  })

  // Handle the response from the Notion API
  const notionData = await notionResponse.json()

  // Return the Notion data
  return { notionData }
}
app/routes/api/notion.tsx
import { json } from '@tanstack/react-start'
import { createFileRoute } from '@tanstack/react-router'
import { auth, clerkClient } from '@clerk/tanstack-react-start/server'

export const ServerRoute = createFileRoute('/api/notion')({
  server: {
    handlers: {
      GET: async () => {
        // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
        // Accessing the `Auth` object differs depending on the SDK you're using
        // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
        const { isAuthenticated, userId } = await auth()

        // Protect the route from unauthenticated users
        if (!isAuthenticated) {
          return new Response('User not authenticated', {
            status: 401,
          })
        }

        const provider = 'notion'

        // Initialize clerkClient
        // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token
        const clerkResponse = await clerkClient().users.getUserOauthAccessToken(userId, provider)
        const accessToken = clerkResponse.data[0]?.token ?? ''
        if (!accessToken) {
          return new Response('Access token not found', {
            status: 401,
          })
        }

        // Fetch the user data from the Notion API
        // This endpoint fetches a list of users
        // https://developers.notion.com/reference/get-users
        const notionUrl = 'https://api.notion.com/v1/users'

        const notionResponse = await fetch(notionUrl, {
          headers: {
            Authorization: `Bearer ${accessToken}`,
            'Notion-Version': '2022-06-28',
          },
        })

        // Handle the response from the Notion API
        const notionData = await notionResponse.json()

        return json(notionData)
      },
    },
  },
})

Add a social connection after sign-up

For each social provider, you can disable the option to sign up and sign in to your application using the provider. This is useful when you want users to connect their OAuth account after authentication — for example, when your application needs to read a user's GitHub repository data but doesn't require GitHub for sign-in.

To configure the option for users to sign up and sign in with a social provider:

  1. In the Clerk Dashboard, navigate to the SSO connections page.
  2. Select the social provider you want to configure.
  3. Enable or disable Enable for sign-up and sign-in.
  4. Save the changes.

Once signed in, a user can connect to additional social providers without going through another sign-up. The Account Portal shows which providers a user has connected and which they can still connect to on their user profile page.

Supported social providers

Clerk provides a wide range of social providers to ease your user's sign-up and sign-in processes. Select a provider to learn how to configure it for your Clerk app.

Apple logo

Apple

Add Apple as an authentication provider for your Clerk app.

Atlassian logo

Atlassian

Add Atlassian as an authentication provider for your Clerk app.

Bitbucket logo

Bitbucket

Add Bitbucket as an authentication provider for your Clerk app.

Box logo

Box

Add Box as an authentication provider for your Clerk app.

Coinbase logo

Coinbase

Add Coinbase as an authentication provider for your Clerk app.

Discord logo

Discord

Add Discord as an authentication provider for your Clerk app.

Dropbox logo

Dropbox

Add Dropbox as an authentication provider for your Clerk app.

Facebook logo

Facebook

Add Facebook as an authentication provider for your Clerk app.

GitHub logo

GitHub

Add GitHub as an authentication provider for your Clerk app.

GitLab logo

GitLab

Add GitLab as an authentication provider for your Clerk app.

Google logo

Google

Add Google as an authentication provider for your Clerk app.

HubSpot logo

HubSpot

Add HubSpot as an authentication provider for your Clerk app.

Hugging Face logo

Hugging Face

Add Hugging Face as an authentication provider for your Clerk app.

LINE logo

LINE

Add LINE as an authentication provider for your Clerk app.

Linear logo

Linear

Add Linear as an authentication provider for your Clerk app.

LinkedIn logo

LinkedIn

Add LinkedIn as an authentication provider for your Clerk app.

Microsoft logo

Microsoft

Add Microsoft as an authentication provider for your Clerk app.

Notion logo

Notion

Add Notion as an authentication provider for your Clerk app.

Slack logo

Slack

Add Slack as an authentication provider for your Clerk app.

Spotify logo

Spotify

Add Spotify as an authentication provider for your Clerk app.

TikTok logo

TikTok

Add TikTok as an authentication provider for your Clerk app.

Twitch logo

Twitch

Add Twitch as an authentication provider for your Clerk app.

Vercel logo

Vercel

Add Vercel as an authentication provider for your Clerk app.

X/Twitter logo

X/Twitter v2

Add X (Twitter v2) as an authentication provider for your Clerk app.

Xero logo

Xero

Add Xero as an authentication provider for your Clerk app.

Don't see the provider you're looking for? You can configure a custom OIDC-compatible provider or request a new one.

Feedback

What did you think of this content?

Last updated on