---
title: Built-in providers
description: Configure single or multi-tenant login/SSO with built-in provider settings.
sidebar:
  order: 3
---

This page shows a full list of all the built-in providers exposed by **SuperTokens**.

<TenantTypeSwitch />

<VariantContent storageKey="tenant-type" value="single">

## Google

To generate your client ID and secret follow the [official documentation](https://support.google.com/cloud/answer/6158849?hl=en).
Set the authorisation callback URL to `<YOUR_WEBSITE_DOMAIN>/auth/callback/google`

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "google",
              clients: [
                {
                  clientId: "<GOOGLE_OAUTH_CLIENT_ID>",
                  clientSecret: "<GOOGLE_OAUTH_CLIENT_SECRET>",
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "google",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "<GOOGLE_CLIENT_ID>",
										ClientSecret: "<GOOGLE_CLIENT_SECRET>",
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="google",
                            clients=[
                                ProviderClientConfig(
                                    client_id="<GOOGLE_CLIENT_ID>",
                                    client_secret="<GOOGLE_CLIENT_SECRET>",
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Google workspaces

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "google-workspaces",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                  additionalConfig: {
                    hd: "example.com",
                  },
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "google-workspaces",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
                                        AdditionalConfig: map[string]interface{}{
                                            "hd": "example.com",
                                        },
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="google-workspaces",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                    additional_config={
                                        "hd": "example.com",
                                    },
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Apple

To generate your client ID and secret follow [this article](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003).

Initialize the ThirdParty and Session recipes on the frontend and backend. When using the prebuilt UI, add Apple to its frontend provider list.

Unlike other providers, Apple sends a form POST to your backend callback instead of redirecting directly to the frontend. Set `redirectURIOnProviderDashboard` to a backend route such as `<YOUR_API_DOMAIN>/auth/callback/apple`, and set `frontendRedirectURI` to the frontend callback page. The backend middleware redirects to that page, which completes authentication by calling `signInAndUp`.

Apple doesn't allow `localhost` in the provider callback URL.
If you are in `dev` mode, you can use the `dev` keys provided above.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "apple",
              clients: [
                {
                  clientId: "<APPLE_CLIENT_ID>",
                  additionalConfig: {
                    keyId: "<APPLE_KEY_ID>",
                    privateKey: "<APPLE_PRIVATE_KEY>",
                    teamId: "<APPLE_TEAM_ID>",
                  },
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
                                ThirdPartyId: "apple",
                                Clients: []tpmodels.ProviderClientConfig{
                                    {
                                        ClientID: "4398792-io.supertokens.example.service",
                                        AdditionalConfig: map[string]interface{}{
                                            "keyId":      "7M48Y4RYDL",
                                            "privateKey": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
                                            "teamId":     "YWQCXGJRJL",
                                        },
                                    },
                                },
                            },
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="apple",
                            clients=[
                                ProviderClientConfig(
                                    client_id="4398792-io.supertokens.example.service",
                                    additional_config={
                                        "keyId":      "7M48Y4RYDL",
                                        "privateKey": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
                                        "teamId":     "YWQCXGJRJL",
                                    },
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Discord

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "discord",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "discord",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="discord",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Facebook

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "facebook",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "facebook",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="facebook",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## GitHub

To generate your client ID and secret follow the [official documentation](https://docs.github.com/en/developers/apps/creating-an-oauth-app).
Set the authorisation callback URL to `<YOUR_WEBSITE_DOMAIN>/auth/callback/github`

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "github",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "github",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="github",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## GitLab

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "gitlab",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
              oidcDiscoveryEndpoint: "https://gitlab.example.com/.well-known/openid-configuration",
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
				SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "gitlab",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
								OIDCDiscoveryEndpoint: "https://gitlab.example.com/.well-known/openid-configuration",
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="gitlab",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                            oidc_discovery_endpoint="https://gitlab.example.com/.well-known/openid-configuration"
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Twitter

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "twitter",
              clients: [
                {
                  clientId: "<TWITTER_OAUTH_CLIENT_ID>",
                  clientSecret: "<TWITTER_OAUTH_CLIENT_SECRET>",
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "twitter",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
										ClientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="twitter",
                            clients=[
                                ProviderClientConfig(
                                    client_id="4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
                                    client_secret="BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## LinkedIn

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "linkedin",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "linkedin",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="linkedin",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## Okta

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "okta",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
              oidcDiscoveryEndpoint: "https://dev-<id>.okta.com/.well-known/openid-configuration",
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "okta",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
                                OIDCDiscoveryEndpoint: "https://dev-<id>.okta.com/.well-known/openid-configuration",
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="okta",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                            oidc_discovery_endpoint="https://dev-<id>.okta.com/.well-known/openid-configuration",
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

## SAML

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "boxy-saml",
              name: "<provider-name>", // Replace with the correct provider name
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                  additionalConfig: {
                    boxyURL: "<TODO: Example: http://domain.example.com:5225/>",
                  },
                },
              ],
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
				SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "boxy-saml",
								Name:         "<provider-name>",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
										AdditionalConfig: map[string]interface{}{
											"boxyURL": "<TODO: Example: http://domain.example.com:5225/>",
										},
									},
								},
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="boxy-saml",
                            name="<provider-name>",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                    additional_config={
                                        "boxyURL": "<TODO: Example: http://domain.example.com:5225/>",
                                    },
                                ),
                            ],
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>


## Active Directory

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          {
            config: {
              thirdPartyId: "active-directory",
              clients: [
                {
                  clientId: "TODO",
                  clientSecret: "TODO",
                },
              ],
              oidcDiscoveryEndpoint:
                "https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
            },
          },
        ],
      },
    }), // initializes signin / sign up features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
                SignInAndUpFeature: tpmodels.TypeInputSignInAndUp{
					Providers: []tpmodels.ProviderInput{
						{
							Config: tpmodels.ProviderConfig{
								ThirdPartyId: "active-directory",
								Clients: []tpmodels.ProviderClientConfig{
									{
										ClientID:     "TODO:",
										ClientSecret: "TODO:",
									},
								},
                                OIDCDiscoveryEndpoint: "https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
							},
						},
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty import ProviderInput, ProviderConfig, ProviderClientConfig, SignInAndUpFeature

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        thirdparty.init(

            sign_in_and_up_feature=SignInAndUpFeature(
                providers=[
                    ProviderInput(
                        config=ProviderConfig(
                            third_party_id="active-directory",
                            clients=[
                                ProviderClientConfig(
                                    client_id="TODO:",
                                    client_secret="TODO:",
                                ),
                            ],
                            oidc_discovery_endpoint="https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
                        ),
                    ),
                ]
            )
        )
    ]
)
```
</Tab>
</CodeGroup>

</VariantContent>


<VariantContent storageKey="tenant-type" value="multi">

Call the following function / API to add the third party provider to a specific tenant.

## Google

To generate your client ID and secret follow the [official documentation](https://support.google.com/cloud/answer/6158849?hl=en)

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-google.gif" alt="Create Google Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "google",
    name: "Google",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "google",
		Name:         "Google",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="google",
        name="Google",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="google",
    name="Google",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "google",
    "name": "Google",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>

## Google workspaces

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-google-workspaces.gif" alt="Create Google Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "google-workspaces",
    name: "Google Workspaces",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
        additionalConfig: {
          hd: "example.com",
        },
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "google-workspaces",
		Name:         "Google Workspaces",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
                AdditionalConfig: map[string]interface{}{
                    "hd": "example.com",
                },
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="google-workspaces",
        name="Google Workspaces",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
                additional_config={
                    "hd": "example.com",
                },
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="google-workspaces",
    name="Google Workspaces",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
            additional_config={
                "hd": "example.com",
            },
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "google-workspaces",
    "name": "Google Workspaces",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "...",
        "additionalConfig": {
            "hd": "example.com"
        }
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>

## Apple

To generate your client ID and secret follow [this article](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003)
Note that Apple doesn't allow `localhost` in the URL.
If you are in `dev` mode, you can use the `dev` keys provided above.

Call the following function / API to add the third party provider to a specific tenant.

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-apple.gif" alt="Create Apple Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "apple",
    name: "Apple",
    clients: [
      {
        clientId: "...",
        additionalConfig: {
          keyId: "...",
          privateKey: "...",
          teamId: "...",
        },
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "apple",
		Name:         "Apple",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
                AdditionalConfig: map[string]interface{}{
                    "keyId":      "...",
                    "privateKey": "...",
                    "teamId":     "...",
                },
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="apple",
        name="Apple",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
                additional_config={
                    "keyId":      "...",
                    "privateKey": "...",
                    "teamId":     "...",
                },
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="apple",
    name="Apple",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
            additional_config={
                "keyId":      "...",
                    "privateKey": "...",
                    "teamId":     "...",
            },
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "apple",
    "name": "Apple",
    "clients": [
      {
        "clientId": "...",
        "additionalConfig": {
            "keyId": "...",
            "privateKey": "...",
            "teamId": "..."
        }
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>

## Discord

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-discord.gif" alt="Create Discord Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "discord",
    name: "Discord",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "discord",
		Name:         "Discord",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="discord",
        name="Discord",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="discord",
    name="Discord",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "discord",
    "name": "Discord",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## Facebook

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-facebook.gif" alt="Create Facebook Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "facebook",
    name: "Facebook",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "facebook",
		Name:         "Facebook",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="facebook",
        name="Facebook",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="facebook",
    name="Facebook",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "facebook",
    "name": "Facebook",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## GitHub

To generate your client ID and secret follow the [official documentation](https://docs.github.com/en/developers/apps/creating-an-oauth-app)

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-github.gif" alt="Create GitHub Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "github",
    name: "GitHub",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "github",
		Name:         "GitHub",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="github",
        name="GitHub",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="github",
    name="GitHub",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "github",
    "name": "GitHub",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## GitLab

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-gitlab.gif" alt="Create GitLab Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "gitlab",
    name: "GitLab",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
    oidcDiscoveryEndpoint: "https://gitlab.example.com/.well-known/openid-configuration",
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "gitlab",
		Name:         "GitLab",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
        OIDCDiscoveryEndpoint: "https://gitlab.example.com/.well-known/openid-configuration",
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="gitlab",
        name="Gitlab",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
        oidc_discovery_endpoint="https://gitlab.example.com/.well-known/openid-configuration"
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="gitlab",
    name="Gitlab",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
    oidc_discovery_endpoint="https://gitlab.example.com/.well-known/openid-configuration"
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "gitlab",
    "name": "GitLab",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ],
    "oidcDiscoveryEndpoint": "https://gitlab.example.com/.well-known/openid-configuration"
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## Twitter

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-twitter.gif" alt="Create Twitter Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "twitter",
    name: "Twitter",
    clients: [
      {
        clientId: "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
        clientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "twitter",
		Name:         "Twitter",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
				ClientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="twitter",
        name="Twitter",
        clients=[
            ProviderClientConfig(
                client_id="4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
                client_secret="BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="twitter",
    name="Twitter",
    clients=[
        ProviderClientConfig(
            client_id="4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
            client_secret="BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "twitter",
    "name": "Twitter",
    "clients": [
      {
        "clientId": " <TWITTER_OAUTH_CLIENT_ID>",
        "clientSecret": "<TWITTER_OAUTH_CLIENT_SECRET>"
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## LinkedIn

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-linkedin.gif" alt="Create LinkedIn Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "linkedin",
    name: "LinkedIn",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "linkedin",
		Name:         "LinkedIn",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="linkedin",
        name="LinkedIn",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="linkedin",
    name="LinkedIn",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "linkedin",
    "name": "LinkedIn",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## Okta

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-okta.gif" alt="Create Okta Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "okta",
    name: "Okta",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
    oidcDiscoveryEndpoint: "https://dev-<id>.okta.com/.well-known/openid-configuration",
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "okta",
		Name:         "Okta",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
        OIDCDiscoveryEndpoint: "https://dev-<id>.okta.com/.well-known/openid-configuration",
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="okta",
        name="Okta",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
        oidc_discovery_endpoint="https://dev-<id>.okta.com/.well-known/openid-configuration",
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="okta",
    name="Okta",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
        ),
    ],
    oidc_discovery_endpoint="https://dev-<id>.okta.com/.well-known/openid-configuration",
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "okta",
    "name": "Okta",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "..."
      }
    ],
    "oidcDiscoveryEndpoint": "https://dev-<id>.okta.com/.well-known/openid-configuration"
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>


## SAML

<DependentContent passive group="backend-language">
<ContentOption title="Dashboard" value="dashboard">
<img src="/docs-assets/img/dashboard/tenant-management/create-provider/create-saml.gif" alt="Create SAML Provider"/>
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "boxy-saml",
    name: "<provider-name>",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
        additionalConfig: {
          boxyURL: "<TODO: Example: http://domain.example.com:5225/>",
        },
      },
    ],
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "boxy-saml",
		Name:         "<provider-name>",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
                AdditionalConfig: map[string]interface{}{
                    "boxyURL": "<TODO: Example: http://domain.example.com:5225/>",
                },
			},
		},
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
<DependentContent group="python-io-style" label="I/O style">
<ContentOption title="Asyncio" value="asyncio">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="boxy-saml",
        name="<provider-name>",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
                additional_config={
                    "boxyURL": "<TODO: Example: http://domain.example.com:5225/>",
                },
            ),
        ],
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</ContentOption>
<ContentOption title="Syncio" value="syncio">
```python
from supertokens_python.recipe.multitenancy.syncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

tenant_id = "customer1"
result = create_or_update_third_party_config(tenant_id, ProviderConfig(
    third_party_id="boxy-saml",
    name="<provider-name>",
    clients=[
        ProviderClientConfig(
            client_id="...",
            client_secret="...",
            additional_config={
                "boxyURL": "<TODO: Example: http://domain.example.com:5225/>",
            },
        ),
    ],
))

if result.status != "OK":
    print("handle error")
elif result.created_new:
    print("Provider added to customer1")
else:
    print("Existing provider config overwritten for customer1")
```
</ContentOption>
</DependentContent>
</Tab>
<Tab title="cURL" value="curl">
```bash
curl --location --request PUT '<CORE_API_ENDPOINT>/<TENANT_ID>/recipe/multitenancy/config/thirdparty' \
--header 'api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "config": {
    "thirdPartyId": "boxy-SAML",
    "name": "<provider-name>",
    "clients": [
      {
        "clientId": "...",
        "clientSecret": "...",
        "additionalConfig": {
            "boxyURL": "<TODO: Example: http://domain.example.com:5225/>"
        }
      }
    ]
  }
}'
```
</Tab>
<Tab title="Dashboard" value="dashboard">

</Tab>
</CodeGroup>

## Active Directory

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
  let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
    thirdPartyId: "active-directory",
    name: "Active Directory",
    clients: [
      {
        clientId: "...",
        clientSecret: "...",
      },
    ],
    oidcDiscoveryEndpoint: "https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
  });

  if (resp.createdNew) {
    // Provider added to customer1
  } else {
    // Existing provider config overwritten for customer1
  }
}
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/multitenancy"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
)

func main() {
	tenantId := "customer1"

	resp, err := multitenancy.CreateOrUpdateThirdPartyConfig(tenantId, tpmodels.ProviderConfig{
		ThirdPartyId: "active-directory",
		Name:         "Active Directory",
		Clients: []tpmodels.ProviderClientConfig{
			{
				ClientID:     "...",
				ClientSecret: "...",
			},
		},
        OIDCDiscoveryEndpoint: "https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
	}, nil)

	if err != nil {
		// handle error
	}
	if resp.OK.CreatedNew {
		// Provider added to customer1
	} else {
		// Existing provider config overwritten for customer1
	}
}
```
</Tab>
<Tab title="Python" value="python">
```python
from supertokens_python.recipe.multitenancy.asyncio import create_or_update_third_party_config
from supertokens_python.recipe.thirdparty.provider import ProviderConfig, ProviderClientConfig

async def some_func():
    tenant_id = "customer1"
    result = await create_or_update_third_party_config(tenant_id, ProviderConfig(
        third_party_id="active-directory",
        name="Active Directoy",
        clients=[
            ProviderClientConfig(
                client_id="...",
                client_secret="...",
            ),
        ],
        oidc_discovery_endpoint="https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
    ))

    if result.status != "OK":
        print("handle error")
    elif result.created_new:
        print("Provider added to customer1")
    else:
        print("Existing provider config overwritten for customer1")
```
</Tab>
</CodeGroup>


</VariantContent>


---

## See also

<CardGroup cols={3}>
  <Card title="Custom providers" href="/authentication/social/custom-providers" />
  <Card title="Multiple clients on the same provider" href="/authentication/social/add-multiple-clients-for-the-same-provider" />
  <Card title="Invite based sign up" href="/authentication/social/custom-invite-flow" />
  <Card title="Hooks and overrides" href="/authentication/social/hooks-and-overrides" />
</CardGroup>
