Skip to main content

Merging Provisional Accounts

When a player wants to link their account to your game, merging will convert their provisional account to a full Discord account via authenticating with their Discord account. We start a special version of the access token request flow where the provisional user’s external identity is included.
Unlike other API rate limits, the merge operation has a strict per-user limit since account merging is not something we expect to happen frequently. Under normal circumstances, a player will only ever link their account once.If you are testing your merge integration, make sure to add your QA users to your application’s App Testers list to avoid hitting rate limits during testing.

How Merging Works

Regardless of whether you merge server-side or from a public client, the flow starts with the standard Client::Authorize step and ends with Discord migrating the provisional account’s data into the full Discord account.

Merging Provisional Accounts for Servers

Merging still begins on the client with Client::Authorize, but the token exchange must run on your backend because it requires your client secret — which must never ship in the game client. The client drives the authorization flow; the backend holds the secret and performs the exchange.
  1. The client creates a PKCE verifier and calls Client::Authorize with its code challenge. The SDK opens the Discord login UI and handles the redirect at http://127.0.0.1/callback itself, then returns the authorization code and the redirectUri to your callback.
  2. The client sends the code, the PKCE code_verifier, the redirectUri, and the provisional account’s external_auth_token to your backend.
  3. Your backend exchanges the code at /oauth2/token — authenticated with your client ID and secret — adding external_auth_type and external_auth_token, and returns Discord’s token JSON to the client.
  4. The client passes the returned access token to Client::UpdateToken and calls Client::Connect. The token exchange completes immediately, but Discord migrates the account’s data asynchronously (see Data Migration During Merging) to the newly linked Discord account.

Client: Start the Authorization Flow

On the client, create a PKCE verifier, call Client::Authorize, and in the callback hand the code — along with the code_verifier, redirectUri, and the provisional account’s external_auth_token — to your backend. Pass the merged access token your backend returns to Client::UpdateToken, then Client::Connect:

Backend: Exchange the Code for a Merged Token

Extend the standard OAuth2 token exchange by posting to /oauth2/token with two additional parameters — external_auth_type and external_auth_token. Discord uses these to identify the provisional account and merge it into the full Discord account associated with the provided authorization code or device code. If you created the provisional account using the Bot Token Endpoint, use DISCORD_BOT_ISSUED_ACCESS_TOKEN as the external_auth_type and the access_token returned by that endpoint (see Bot Token Endpoint Response) as the external_auth_tokennot the external_user_id. If you used External Credentials Exchange, the external_auth_token is the same credential you provided when creating the provisional account — for example, your OIDC identity token, Steam session ticket, or EOS access token. See the External Auth Types table for the full list of supported external_auth_type values.
The bot-issued external_auth_token is the access token, because the merge runs through the OAuth2 /oauth2/token endpoint and the token is what proves the external identity. This differs from the bot unmerge endpoint, which is authenticated by your bot token and therefore identifies the account by external_user_id instead.

Desktop & Mobile

Request Body Parameters

Console

Request Body Parameters

Merge Request Response


Merging Provisional Accounts for Public Clients

This method requires enabling Public Client for your app. Most games will not want to ship with this enabled. Learn more
If you do not have a backend, leverage the Client::GetTokenFromProvisionalMerge (Desktop & Mobile) or Client::GetTokenFromDeviceProvisionalMerge (Console) method, which will handle the entire process for you. You’ll want to first enable Public Client on your Discord application’s OAuth2 tab on the Discord developer portal. You can then leverage the Client::GetTokenFromProvisionalMerge or Client::GetTokenFromDeviceProvisionalMerge method using just the client. This function should be used with the Client::Authorize function whenever a user with a provisional account wants to link an existing Discord account, merging their provisional account into that full Discord account. The account merging process starts like the normal login flow, invoking the Client::Authorize method to get an authorization code back. Instead of calling GetToken, call this function and pass on the provisional user’s identity. Discord can then find the provisional account with that identity and the new Discord account and merge any data as necessary. See the documentation for Client::GetToken for more details on the callback. Note that the callback will be invoked when the token exchange is complete, but merging accounts happens asynchronously and will not be complete yet.

Data Migration During Merging

The endpoint validates, mints and returns the OAuth2 access token immediately, then the actual account-data merge runs in the background When a user merges their provisional account with a Discord account, a new OAuth2 access token immediately for the Discord account is created and returned immediately. The provisional account’s data is transferred onto the full Discord account asynchronously, and the provisional account is deleted once the merge completes. If the user later unlinks, a new provisional account with a new unique ID is created (see Unmerging Accounts). The following data is automatically transferred:
  • ✅ Friends: All In-game and Discord friendships made through the provisional account
  • ✅ Lobby Memberships: Active and historical lobby participation
  • ✅ DM Messages: Direct messages and history
This migration ensures users don’t lose their social connections built while using the provisional account.

Merge Request Failures

You may receive a merge specific error code while attempting this operation:
Error 530017 is most commonly seen after a successful link: when a previously linked Discord account is banned, that user’s identity is severed back into a new provisional account in a restricted state, and that restricted provisional account cannot be merged into a different Discord account until the ban expires (temp ban) or is lifted. See Ban-Driven Unmerge for the full lifecycle.

Next Steps

Unmerging Accounts

Sever the link between a Discord account and a provisional account.

Designing for Provisional Accounts

Design guidelines for implementing provisional accounts in your game.

Account Linking from Your Game

The standard OAuth2 flow for players who already have a Discord account.
Need help? Join the Discord Developers Server and share questions in the #social-sdk-dev-help channel for support from the community. If you encounter a bug while working with the Social SDK, please report it here: https://dis.gd/social-sdk-bug-report

Change Log