curl --request POST \
--url https://api.studio.prisme.ai/v2/login/token-exchange \
--header 'Content-Type: application/json' \
--data '
{
"provider": "<string>",
"subject_token": "<string>"
}
'const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({provider: '<string>', subject_token: '<string>'})
};
fetch('https://api.studio.prisme.ai/v2/login/token-exchange', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.studio.prisme.ai/v2/login/token-exchange"
payload = {
"provider": "<string>",
"subject_token": "<string>"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"firstName": "<string>",
"token": "<string>",
"sessionId": "<string>",
"email": "foo@prisme.ai",
"status": "pending",
"language": "<string>",
"authData": {
"anonymous": {},
"prismeai": {},
"azure": {
"id": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"email": "<string>",
"language": "<unknown>"
}
},
"mfa": "totp",
"meta": {},
"orgSlugs": [
"<string>"
],
"platformRole": "<string>",
"groupAcls": {},
"createdAt": "<string>",
"updatedAt": "<string>",
"updatedBy": "<string>",
"lastName": "<string>",
"emailMasked": "<string>",
"photo": "<string>",
"groups": [
"<string>"
],
"identities": [
"<string>"
],
"membership": {
"roleSlug": "<string>",
"status": "active",
"joinedAt": "<string>",
"joinedVia": "direct",
"invitedAt": "<string>",
"invitedBy": "<string>"
},
"id": "<string>",
"expires": "<string>",
"organizations": [
{
"slug": "<string>",
"name": "<string>",
"roleSlug": "<string>",
"groups": [
"<string>"
]
}
]
}{
"error": "BadParameters",
"message": "<string>",
"details": "<unknown>"
}{
"error": "AuthenticationError",
"message": "Unauthenticated"
}{
"error": "ForbiddenError",
"message": "Forbidden"
}Token Exchange
Exchange an OIDC id_token issued by a configured external provider for a nominative Prisme access token, without any browser redirect. Intended for native/mobile or headless clients that already authenticated against their IdP (e.g. Entra External ID Native Auth). Loosely follows RFC 8693.
The target provider must have config.allowTokenExchange = true, which in turn makes config.issuer mandatory. The subject_token signature is verified against the provider JWKS, its iss claim must equal that issuer, and its aud claim must match one of config.tokenExchangeAudiences — or, when that list is left empty, the provider client_id, so that only tokens minted for the same OAuth client as the browser flow are accepted. The user is then matched or provisioned exactly like the browser callback (POST /v2/login/callback): pending invitations are claimed on first login and, when the provider is declared under an organization, the user automatically joins it — the returned profile therefore already carries its orgSlugs and organizations. Platform-wide providers grant no membership; organization access must then come from an invitation or a join rule. The organization is never taken from the request body.
curl --request POST \
--url https://api.studio.prisme.ai/v2/login/token-exchange \
--header 'Content-Type: application/json' \
--data '
{
"provider": "<string>",
"subject_token": "<string>"
}
'const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({provider: '<string>', subject_token: '<string>'})
};
fetch('https://api.studio.prisme.ai/v2/login/token-exchange', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.studio.prisme.ai/v2/login/token-exchange"
payload = {
"provider": "<string>",
"subject_token": "<string>"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"firstName": "<string>",
"token": "<string>",
"sessionId": "<string>",
"email": "foo@prisme.ai",
"status": "pending",
"language": "<string>",
"authData": {
"anonymous": {},
"prismeai": {},
"azure": {
"id": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"email": "<string>",
"language": "<unknown>"
}
},
"mfa": "totp",
"meta": {},
"orgSlugs": [
"<string>"
],
"platformRole": "<string>",
"groupAcls": {},
"createdAt": "<string>",
"updatedAt": "<string>",
"updatedBy": "<string>",
"lastName": "<string>",
"emailMasked": "<string>",
"photo": "<string>",
"groups": [
"<string>"
],
"identities": [
"<string>"
],
"membership": {
"roleSlug": "<string>",
"status": "active",
"joinedAt": "<string>",
"joinedVia": "direct",
"invitedAt": "<string>",
"invitedBy": "<string>"
},
"id": "<string>",
"expires": "<string>",
"organizations": [
{
"slug": "<string>",
"name": "<string>",
"roleSlug": "<string>",
"groups": [
"<string>"
]
}
]
}{
"error": "BadParameters",
"message": "<string>",
"details": "<unknown>"
}{
"error": "AuthenticationError",
"message": "Unauthenticated"
}{
"error": "ForbiddenError",
"message": "Forbidden"
}Body
Slug of the configured external auth provider.
The id_token (JWT) issued by the external provider.
Optional. Field name borrowed from RFC 8693 — this is a Prisme.ai JSON login endpoint, not a full RFC 8693 token endpoint. When provided, must be urn:ietf:params:oauth:token-type:id_token (the only supported subject token type).
urn:ietf:params:oauth:token-type:id_token Optional. Field name borrowed from RFC 8693. When provided, must be urn:ietf:params:oauth:grant-type:token-exchange.
urn:ietf:params:oauth:grant-type:token-exchange Optional session expiration in seconds
Response
Success Response
Name
The minted Prisme.ai access token (JWT).
"foo@prisme.ai"
pending, validated, deactivated Current MFA method (super admin only).
totp, none, * Name
Partially masked email (e.g. "j***@acme.com"), returned to non-elevated callers in place of the clear-text email to disambiguate homonyms without exposing the full address.
Profile picture URL
Denormalized ":" tuples (super admin only).
Organization membership info (only returned when includeOrgMembership is set)
Hide child attributes
Hide child attributes
Unique id
Was this page helpful?