> ## Documentation Index
> Fetch the complete documentation index at: https://docs.discord.com/llms.txt
> Use this file to discover all available pages before exploring further.

# External Credentials Exchange

> Exchange an external provider token (OIDC, Steam, EOS, and more) server-side to create a provisional account.

export const WrenchIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" d="M7.8 15.77c.7.43 1.2 1.14 1.2 1.96V21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-3.27c0-.82.5-1.53 1.2-1.96a8.06 8.06 0 0 0 .12-13.63c-.6-.39-1.32.09-1.32.8v5.98a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V2.94c0-.71-.72-1.19-1.32-.8a8.06 8.06 0 0 0 .12 13.63Z" /></svg>;

export const UserPlatformIcon = props => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="currentColor" fill-rule="evenodd" d="M16 6a4 4 0 1 1-8 0 4 4 0 0 1 8 0ZM2 20.53A9.53 9.53 0 0 1 11.53 11h.94c1.28 0 2.5.25 3.61.7.41.18.36.77-.05.96a7 7 0 0 0-3.65 8.6c.11.36-.13.74-.5.74H6.15a.5.5 0 0 1-.5-.55l.27-2.6c.02-.26-.27-.37-.41-.16-.48.74-1.03 1.8-1.32 2.9a.53.53 0 0 1-.5.41h-.22C2.66 22 2 21.34 2 20.53Z" clip-rule="evenodd" /><path fill="currentColor" d="M23.66 16.47c.13.57.34 1.69.34 3.23v2.23a1.4 1.4 0 0 1-2.66.63l-.8-1.6a.5.5 0 0 0-.56-.25c-.26.06-.62.12-.98.12s-.72-.06-.98-.12a.5.5 0 0 0-.56.25l-.8 1.6a1.4 1.4 0 0 1-2.66-.63V19.7c0-1.54.2-2.66.34-3.23.31-1.3 1.36-1.55 2.46-1.79.23-.05.46.03.62.18.16.16.35.33.58.32a19.25 19.25 0 0 1 2 0c.23 0 .42-.16.58-.32a.68.68 0 0 1 .62-.18c1.1.24 2.15.5 2.46 1.8Z" /></svg>;

## Server Authentication with External Credentials Exchange

<Warning>
  **Use the [Bot Token Endpoint](/developers/discord-social-sdk/development-guides/provisional-accounts/bot-token-endpoint) if your game has an account system that uniquely identifies users.** It is simpler, requires no identity provider configuration, and is the recommended approach for most integrations.

  Use External Credentials Exchange only if you have a hard requirement for a server-side custom OIDC integration. If you don't have a server-authoritative backend, use [Public Client Integration](/developers/discord-social-sdk/development-guides/provisional-accounts/public-client) instead.
</Warning>

Before using this method, you must [configure your identity provider](/developers/discord-social-sdk/development-guides/provisional-accounts/identity-providers) in the Developer Portal. Exchange the external provider's token for a Discord access token from your game server:

```python theme={"system"}
# filepath: your_game/server/auth.py
import requests

def get_provisional_token(external_token: str):
  response = requests.post(
    'https://discord.com/api/v10/partner-sdk/token',
    json={
      'client_id': CLIENT_ID,
      'client_secret': CLIENT_SECRET,
      'external_auth_type': EXTERNAL_AUTH_TYPE,  # See External Auth Types
      'external_auth_token': external_token
    }
  )
  return response.json()
```

See the [External Auth Types](/developers/discord-social-sdk/development-guides/provisional-accounts/identity-providers#external-auth-types) table for the full list of supported `external_auth_type` values.

#### External Credentials Exchange Response

```python theme={"system"}
{
  "access_token": "<access token>",
  "id_token": "<id token>",
  "token_type": "Bearer",
  "expires_in": 604800,
  "scope": "sdk.social_layer"
}
```

<Warning>
  If you are using OIDC, you may see a `refresh_token` in this response. Using it via the OAuth2 `refresh_token` grant is **deprecated** — re-authenticate using a fresh provider token instead. See [Refreshing Access Tokens](/developers/discord-social-sdk/development-guides/provisional-accounts/managing-accounts#refreshing-access-tokens) for details.
</Warning>

### How the Flow Works

```mermaid theme={"system"}
sequenceDiagram
    autonumber
    actor P as Player
    participant Prov as External Provider<br/>(OIDC, Steam, EOS)
    participant G as Your Game Server
    participant D as Discord API

    P->>Prov: Authenticate
    Prov-->>G: External auth token
    G->>D: POST /partner-sdk/token<br/>{ client_id, client_secret,<br/>external_auth_type, external_auth_token }
    alt No account for identity
        D->>D: Create provisional account
        D-->>G: 200 { access_token, id_token, ... }
    else Provisional account exists
        D-->>G: 200 { access_token, id_token, ... }
    else Full Discord account exists
        D-->>G: Error 530010 (use OAuth2 flow)
    end
```

Once authentication is complete, you can use the access token as you would a full Discord user's access token. See [Managing Provisional Accounts](/developers/discord-social-sdk/development-guides/provisional-accounts/managing-accounts) for token refresh, storage, and display names.

## Error Handling

Common error codes and solutions when creating a provisional account:

| Code   | Meaning                      | Solution                                                                    |
| ------ | ---------------------------- | --------------------------------------------------------------------------- |
| 530000 | Application not configured   | Contact Discord support to enable provisional accounts for your application |
| 530001 | Expired ID token             | Request a new token from your identity provider                             |
| 530004 | Token too old                | Request a new token (tokens over 1 week old are rejected)                   |
| 530006 | Username generation failed   | Retry the operation (temporary error)                                       |
| 530007 | Invalid client secret        | Verify or regenerate your client secret in the Developer Portal             |
| 530010 | User account non-provisional | User already linked to Discord account - use standard OAuth2 flow           |

If you are using OIDC, you may encounter more specific errors:

| Code   | Meaning                      | Solution                                                                                                               |
| ------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 530002 | Invalid issuer               | Verify the `iss` claim in your ID token exactly matches the issuer URL in your OIDC configuration                      |
| 530003 | Invalid audience             | Verify the `aud` claim in your ID token includes the client ID in your OIDC configuration                              |
| 530008 | OIDC configuration not found | Verify your issuer URL is correct, accessible over HTTPS, and serves a valid discovery document without HTTP redirects |
| 530009 | OIDC JWKS not found          | Verify your JWKS endpoint is accessible over HTTPS without HTTP redirects                                              |
| 530020 | Invalid OIDC JWT token       | Verify your ID token is properly signed and uses a supported algorithm                                                 |
| 530027 | Missing `kid` header         | Ensure your ID token includes a `kid` (Key ID) header in the JWT header identifying the signing key                    |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Configuring Identity Providers" href="/developers/discord-social-sdk/development-guides/provisional-accounts/identity-providers" icon={<UserPlatformIcon />}>
    Set up OIDC, Steam, EOS, and other providers, and review the OIDC requirements.
  </Card>

  <Card title="Managing Provisional Accounts" href="/developers/discord-social-sdk/development-guides/provisional-accounts/managing-accounts" icon={<WrenchIcon />}>
    Refresh access tokens and set display names.
  </Card>
</CardGroup>

Need help? Join the [Discord Developers Server](https://discord.gg/discord-developers) 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](https://dis.gd/social-sdk-bug-report)

***

## Change Log

| Date           | Changes                                                   |
| -------------- | --------------------------------------------------------- |
| July 14, 2026  | Split the provisional accounts guide into its own section |
| March 17, 2025 | Initial release                                           |
