---
title: "Exchange a fan experience launch token"
method: POST
path: "/experiences/token/exchange"
---

# Exchange a fan experience launch token

`POST /experiences/token/exchange`

Exchanges the opaque experience token an app's fan-experience surface received in its iframe URL for the resolved experience, the fan's identity, and the fan's entitlement to the experience.

    The token is bound to the app that owns the experience: a token minted for one app cannot be exchanged with another app's credentials (403).

    Returns 400 if the token is invalid or expired, and 404 if the experience no longer exists.

## Headers

- `X-Fanvue-API-Version` string, required

## Request body

- object
  - `token` string, required — The opaque experience launch token appended to the surface iframe URL.

## Response `200`

The resolved experience, fan identity, and entitlement

- object
  - `experience` object, required
    - `uuid` string, uuid, required
    - `appUuid` string, uuid, required
    - `creatorUuid` string, uuid, required
    - `externalExperienceId` string, required
    - `title` string, required
    - `description` string, required
    - `accessMode` 'FREE' | 'SUBSCRIPTION' | 'PAID' | 'HIDDEN', required
    - `hidden` boolean, required
  - `fanUuid` string, uuid, required
  - `entitlement` object, required
    - `isEntitled` boolean, required
    - `mode` 'FREE' | 'SUBSCRIPTION' | 'PAID' | 'HIDDEN', required
    - `reason` string, required
  - `walletBalance` integer, nullable, required — The fan's Fanvue wallet balance in minor units (cents, USD), so you can show their spending power as the surface loads. `null` when the wallet is not available to this fan at all, which is not the same as an empty balance — do not offer a wallet charge then. A snapshot, never an authorisation: charge with `POST /experiences/{experienceUuid}/action-purchases` and read the fresh balance off that response.

## Other responses

- `400` — Bad Request - API version not supported OR validation failed
- `401` — Unauthorized Response
- `403` — Unauthorized Response
- `404` — Experience not found
- `410` — API version no longer supported (sunset)
- `429` — Too many requests - rate limit exceeded
- `502` — Failed to exchange the experience token with the upstream
- `503` — Developer API upstream is not configured

## Changes

- **2026-09-25** `431868e8a264` — 1 info
  - added the required property `walletBalance` to the response with the `200` status

[Change history](https://skmtc.dev/fanvue/apis/fanvue-api/changes/experiences/token/exchange/post.md)

---

[API](https://skmtc.dev/fanvue/apis/fanvue-api.md) · [All operations](https://skmtc.dev/fanvue/apis/fanvue-api/llms.txt) · [OpenAPI document](https://skmtc.dev/fanvue/apis/fanvue-api/revisions/431868e8a264?raw)
