Appearance
Unlinking accounts
Privy enables you to unlink linked accounts from a user via their Privy DID and account type and handle. This means you can assist users who want to remove linked accounts by simply interacting with the Privy Dashboard or via an API call.
Note that embedded wallets and passkey accounts may not be unlinked. If an account is the only one linked to a user, it may not be unlinked either.
Using the dashboard
To unlink via the dashboard, navigate to the Users page and select the user. Unlink by clicking in the button besides the account to unlink and clicking Unlink account
. Note that this option won't show if unlinking is not available for the account.
Using the REST API
Make a POST
request to:
sh
https://auth.privy.io/api/v1/apps/<privy-app-id>/users/unlink
Replace <privy-app-id>
with your Privy app ID and pass in the following parameters:
Parameter | Type | Description |
---|---|---|
user_id | string | Privy DID of the user |
type | 'email' | 'google_oauth' | 'telegram' | ... | Linked account type |
handle | string | The field that identifies the account, for example the subject field in OAuth accounts, the address in wallet accounts or the telegram_user_id in Telegram accounts. |
provider | string (optional) | When unlinking cross_app type accounts, you also need to send a provider field that matches with the account's provider_app_id field. |
TIP
Looking for the types of LinkedAccount
s?
See a list of the different account types and the data they include
Note:
- Each account should be a JSON object including all the necessary fields for that account
type
.- Valid account
type
s areapple_oauth
,'custom_auth'
,'discord_oauth'
,'farcaster'
,'github_oauth'
,'google_oauth'
,'instagram_oauth'
,'linkedin_oauth'
,'spotify_oauth'
,'telegram'
,'tiktok_oauth'
,'twitter_oauth'
,'email'
,'phone'
and'wallet'
.
- Valid account
- If importing a user with a
custom_auth
account, thecustom_auth
account must be the only element of thelinked_accounts
array. It is not permitted to import a user with acustom_auth
account and otherlinked_accounts
. - You must exclude the
verifiedAt
field. - The SDK and REST API have different naming conventions. The SDK uses camelCase and the API uses snake_case.
CustomJwtAccount
Field | Type | Description |
---|---|---|
type | 'custom_auth' | N/A |
API: custom_user_id SDK: customUserId | string | ID of user from custom auth provider. |
DiscordAccount
Field | Type | Description |
---|---|---|
type | 'discord_oauth' | N/A |
subject | string | ID of user from Discord user API response. |
email | string | Email of user from Discord user API response. |
username | string | Username of user from Discord user API response. |
(See Discord docs)
EmailAccount
Field | Type | Description |
---|---|---|
type | 'email' | N/A |
address | string | Email address of user account. |
FarcasterAccount
Field | Type | Description |
---|---|---|
type | 'farcaster' | N/A |
fid | number | FID of the user from Farcaster user API response. |
API: owner_address SDK: ownerAddress | string | Wallet address of the user from Farcaster user API response. Note that this is the Farcaster wallet address, and not the Privy embedded wallet address. |
username | string | (Optional) Username of user from Farcaster user API response. Do not include the '@'. |
API: display_name SDK: displayName | string | (Optional) Display name of user from Farcaster user API response. |
bio | string | (Optional) Bio of user from Farcaster user API response. |
API: profile_picture_url SDK: profilePictureUrl | string | (Optional) Profile picture URL of the user from Farcaster user API response. Must be a valid image URL. |
API: homepage_url SDK: homepageUrl | string | (Optional) Profile URL of the user from Farcaster user API response. |
(See Farcaster docs. Note that the Privy import interface differs slightly from the Farcaster public interface in order to maintain consistency with other Privy LinkedAccount
types.)
GithubAccount
Field | Type | Description |
---|---|---|
type | 'github_oauth' | N/A |
subject | string | ID of user from GitHub user API response. |
email | string | Email of user from GitHub user API response |
name | string | Name of user from GitHub user API response |
username | string | Username of user from GitHub user API response |
(See GitHub docs)
GoogleAccount
Field | Type | Description |
---|---|---|
type | 'google_oauth' | N/A |
subject | string | sub pulled from Google-provided JWT with "openid" scope. |
email | string | email from Google-provided JWT with "email" scope. |
name | string | name from Google-provided JWT with "profile" scope. |
InstagramAccount
Field | Type | Description |
---|---|---|
type | 'instagram_oauth' | N/A |
subject | string | ID of user from Instagram user API response. |
username | string | The name displayed on a user's profile from Instagram's /me API response. |
(See Instagram docs)
LinkedinAccount
Field | Type | Description |
---|---|---|
type | 'linkedin_oauth' | N/A |
subject | string | ID of user from LinkedIn user API response. |
email | string | Email of user from LinkedIn user API response |
name | string | Name of user from LinkedIn user API response. Do not include the '@'. |
(See Linkedin docs)
PhoneAccount
Field | Type | Description |
---|---|---|
type | 'phone' | N/A |
number | string | Phone number of user account (non-international numbers default to US). |
While number
is accepted as input, phoneNumber
is returned in the response.
SmartWalletAccount
Field | Type | Description |
---|---|---|
type | 'smart_wallet' | N/A |
address | string | Checksummed smart wallet address. |
smart_wallet_type | SmartWalletType | One of 'kernel' , 'safe' , 'biconomy' or 'light_account' |
SpotifyAccount
Field | Type | Description |
---|---|---|
type | 'spotify_oauth' | N/A |
subject | string | ID of user from Spotify user API response. |
email | string | Email of user from Spotify user API. |
name | string | The name displayed on a user's profile from Spotify display_name API response. |
(See Spotify docs)
TelegramAccount
Field | Type | Description |
---|---|---|
type | 'telegram' | N/A |
telegram_user_id | string | ID of a user's telegram account. |
first_name | string | The first name displayed on a user's telegram account. |
last_name | string | (Optional) The last name displayed on a user's telegram account. |
username | string | (Optional) The username displayed on a user's telegram account. |
photo_url | string | (Optional) The url of a user's telegram account profile picture. |
(See Telegram docs)
TwitterAccount
Field | Type | Description |
---|---|---|
type | 'twitter_oauth' | N/A |
subject | string | ID of user from Twitter user API response. |
name | string | Name of user from Twitter user API response |
username | string | Username of user from Twitter user API response. Do not include the '@'. |
API: profile_picture_url SDK: profilePictureUrl | string | (Optional) Profile picture URL of the user from Twitter user API response. Must be a valid image URL. |
(See Twitter docs)
WalletAccount
Field | Type | Description |
---|---|---|
type | 'wallet' | N/A |
API: chain_type SDK: chainType | 'ethereum' | Type of chain for the wallet. EVM chains ('ethereum' ) and Solana ('solana' ) are currently supported. |
address | string | Checksummed wallet address. |
Below is a sample cURL command for unlinking a user's email
account:
bash
curl --request POST "https://auth.privy.io/api/v1/apps/<privy-app-id>/users/unlink" \
-u "<your-privy-app-id>:<your-privy-app-secret>" \
-H "privy-app-id: <your-privy-app-id>" \
-H 'Content-Type: application/json' \
-d '{
"user_id": "<user-did>",
"type": "email",
"handle": "[email protected]"
}'
Below is a sample cURL command for unlinking a user's cross_app
account:
bash
curl --request POST "https://auth.privy.io/api/v1/apps/<privy-app-id>/users/unlink" \
-u "<your-privy-app-id>:<your-privy-app-secret>" \
-H "privy-app-id: <your-privy-app-id>" \
-H 'Content-Type: application/json' \
-d '{
"user_id": "<user-did>",
"type": "cross_app",
"handle": "<account-subject>"
"provider": "<account-provider-app-id>"
}'
If the unlinking is successful, the API will return a 200 status code.
If there's no account associated with the Privy DID that matches the type and handle, the API will return a 400 status code.