# How to Use exchangeToken with Organizations for Multi-Tenant Authentication

> Learn how to use exchangeToken with organizations for multi-tenant authentication in Auth0. Pass the organization parameter to scope access tokens to specific tenants.

- Repository: [Auth0/auth0-auth-js](https://github.com/auth0/auth0-auth-js)
- Tags: how-to-guide
- Published: 2026-02-25

---

**To use exchangeToken with organizations for multi-tenant authentication, pass the optional `organization` parameter when calling `exchangeToken()` in the Auth0 JavaScript SDK, which Auth0 validates and embeds into the resulting access token payload to scope the request to a specific tenant.**

The `auth0/auth0-auth-js` repository provides a JavaScript SDK that supports OAuth 2.0 Token Exchange (RFC 8693) and Token Vault flows for secure token conversion. When building multi-tenant applications, you can leverage the **`organization`** parameter to ensure exchanged tokens contain the specific tenant context, enabling a single application to securely serve users across different Auth0 organizations.

## Understanding Token Exchange Flows

The Auth0 JavaScript SDK implements two distinct flows that support the `organization` parameter for multi-tenant scenarios. Both flows allow you to exchange existing tokens while applying organization-specific policies and claims to the resulting session.

### Token Exchange Profiles (RFC 8693)

This flow converts tokens from custom identity providers or legacy systems into Auth0-issued tokens. According to the source code in [`packages/auth0-auth-js/src/auth-client.ts`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/auth-client.ts), the SDK appends the `organization` parameter to the grant request body at lines 737-739 when invoking the internal `#exchangeProfileToken` method.

The TypeScript interface `ExchangeProfileOptions` in [`packages/auth0-auth-js/src/types.ts`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/types.ts) (lines 440-447) defines the optional `organization` field as a string, accepting either an organization ID (e.g., `org_abc123`) or the organization name.

### Token Vault Exchanges

For scenarios where you exchange Auth0 tokens for third-party provider tokens (such as Google or Salesforce), the Token Vault flow applies. The SDK includes the `organization` parameter in the request body at [`auth-client.ts`](https://github.com/auth0/auth0-auth-js/blob/main/auth-client.ts) lines 921-922 when constructing Token Vault exchange parameters.

The `TokenVaultExchangeOptions` interface in [`types.ts`](https://github.com/auth0/auth0-auth-js/blob/main/types.ts) (lines 407-414) provides the equivalent type definition for this flow, ensuring type safety when specifying the organization context.

## Implementing Organization-Aware Token Exchange

To implement multi-tenant authentication, instantiate the `AuthClient` and include the `organization` property in your exchange options. The SDK automatically propagates this value to Auth0's authorization server.

### Exchanging Custom Tokens with Organization Context

When integrating with external identity systems, use the Token Exchange Profile flow with an organization ID to ensure the new token is scoped correctly:

```typescript
import { AuthClient } from '@auth0/auth0-auth-js';

const authClient = new AuthClient({ 
  domain: 'your-domain.auth0.com',
  clientId: 'your-client-id'
});

async function exchangeCustomTokenWithOrg() {
  const response = await authClient.exchangeToken({
    subjectTokenType: 'urn:acme:custom-token',
    subjectToken: '<CUSTOM_TOKEN_FROM_YOUR_BACKEND>',
    audience: 'https://api.example.com',
    scope: 'openid profile read:data',
    organization: 'org_abc123', // Organization ID or name
  });

  console.log('Access token scoped to org:', response.accessToken);
}

```

### Exchanging Auth0 Tokens for External Provider Access

For Token Vault scenarios where you exchange an Auth0 access token for a third-party provider token, maintain the organization context to ensure consistent tenant isolation:

```typescript
async function exchangeForGoogleWithOrg() {
  const response = await authClient.exchangeToken({
    connection: 'google-oauth2',
    subjectToken: '<AUTH0_ACCESS_TOKEN>',
    organization: 'org_xyz789', // Maintains organization context
  });

  console.log('Google access token for org:', response.accessToken);
}

```

### Maintaining Organization Context During Refresh

While `exchangeToken` handles initial conversions, you can preserve organization context during token refresh operations using `getTokenByRefreshToken`:

```typescript
async function refreshTokenForOrg() {
  const response = await authClient.getTokenByRefreshToken({
    refreshToken: '<REFRESH_TOKEN>',
    organization: 'org_abc123', // Preserves organization claim
    scope: 'openid profile email',
  });

  console.log('Refreshed token includes org claim:', response.accessToken);
}

```

## How Auth0 Validates Organization Context

When you supply the `organization` parameter, Auth0 performs validation before issuing the new token. The authorization server verifies that the specified organization exists and that the authenticated user is a member of that organization (or is authorized via an organization login hint). Upon successful validation, Auth0 embeds the organization ID directly into the access token payload, allowing your downstream APIs to identify the tenant context without requiring additional database lookups.

## Summary

- The **`organization`** parameter enables multi-tenant authentication across both **Token Exchange Profiles** and **Token Vault** flows in the `auth0-auth-js` SDK.
- Source code in [`packages/auth0-auth-js/src/auth-client.ts`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/auth-client.ts) (lines 737-739 and 921-922) automatically appends this parameter to the respective grant request bodies.
- Type definitions in [`packages/auth0-auth-js/src/types.ts`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/types.ts) expose `organization` as an optional string in both `ExchangeProfileOptions` (lines 440-447) and `TokenVaultExchangeOptions` (lines 407-414).
- Auth0 validates organization membership and embeds the organization ID into the exchanged token's payload for downstream tenant identification.
- The parameter maintains consistency across initial token exchange and refresh token flows via `getTokenByRefreshToken`.

## Frequently Asked Questions

### What is the difference between Token Exchange Profiles and Token Vault in Auth0?

Token Exchange Profiles implement RFC 8693 to convert external or legacy tokens into Auth0-issued tokens. Token Vault performs the inverse operation, exchanging valid Auth0 tokens for third-party provider tokens (such as Google OAuth2 or Salesforce) to call external APIs on behalf of your users. Both flows support the `organization` parameter as implemented in [`auth-client.ts`](https://github.com/auth0/auth0-auth-js/blob/main/auth-client.ts).

### Can I use an organization name instead of an organization ID with exchangeToken?

Yes. The `organization` parameter accepts either an organization ID (formatted as `org_` followed by alphanumeric characters) or the organization name. The TypeScript definitions in [`types.ts`](https://github.com/auth0/auth0-auth-js/blob/main/types.ts) specify this as a flexible string type for both `ExchangeProfileOptions` and `TokenVaultExchangeOptions`.

### Does the organization parameter work with refresh token flows?

Yes. While `exchangeToken` handles initial token conversion, the `getTokenByRefreshToken` method also accepts an `organization` parameter to ensure refreshed tokens maintain the same organization context and claims as the original session.

### What happens if the user does not belong to the specified organization?

Auth0 validates the user's organization membership before issuing the token. If the user is not a member of the specified organization (and no valid login hint is provided), the token exchange request fails with an authorization error, preventing unauthorized cross-tenant access.