Publish an experience for this creator

Changed on

Publishes an experience for the creator whose token is calling, without the confirmation dialog: your app declares the whole experience — type, access mode, price and priced actions included — and Fanvue writes it. The creator consented to this when they granted your app write:experience.

Publishing the same `externalExperienceId` again for the same creator updates the existing experience. A republish that would take paid access away from fans (switching to `HIDDEN`, or hiding a published experience) answers 409 with the impact; retry with `acknowledgePaidImpact` and the impact echoed as `acknowledgedImpact` to proceed, unless fans hold live recurring access, which blocks it outright.

Prefer `POST /request-token` when you want the creator to confirm or price the experience themselves in Fanvue's dialog.
post/experiences

Request

  • Base URL
    https://api.fanvue.com
  • URL
    https://api.fanvue.com/experiences
  • Auth
    OAuth 2
    Authorization code: https://auth.fanvue.com/oauth2/auth
    Token URL: https://auth.fanvue.com/oauth2/token scopes: write:experience

Headers

X-Fanvue-API-Versionstring required
Example:2025-06-26

API version to use for the request

Request body

appUuidstring uuid required

Your app's UUID.

externalExperienceIdstring required

Your own stable id for the experience. Publishing the same id again for the same creator updates the existing experience.

titlestring required
descriptionstring required
imageUrlstring uri nullable

Public https URL of the cover image. Fanvue downloads and re-hosts it; one that cannot be fetched is dropped and the experience keeps no cover.

accessMode'FREE' | 'SUBSCRIPTION' | 'PAID' | 'HIDDEN' required

FREE, SUBSCRIPTION (the creator's subscribers), PAID (needs priceCents) or HIDDEN (share-link only).

deliveryMode'EMBEDDED' | 'EXTERNAL'

EMBEDDED (default) renders your fan_experience surface on Fanvue; EXTERNAL opens externalUrl.

externalUrlstring uri nullable

Where an EXTERNAL experience opens. Must be https (checked here). The platform additionally refuses Fanvue, localhost, IP and dev-tunnel hosts; such a URL answers 400 with a message naming the field.

hiddenboolean

Keep the experience off the creator's profile. Implied by HIDDEN.

priceCentsinteger

Price in USD cents, between 300 and 50000.

priceRecurringboolean

With priceCents: bill monthly as an app subscription instead of a one-off unlock.

experienceType'LIVE_STREAM' | 'LIVE_AUDIO' | 'VIDEO' | 'AUDIO' | 'GAME' | 'CHALLENGE' | 'QUIZ' | 'EVENT' | 'OTHER'

What kind of experience this is. Decides how it presents itself where it is embedded (for example the category tag on a chat card). Omit for the generic OTHER.

acknowledgePaidImpactboolean

Set to true on a retry to accept the paid impact a previous attempt answered 409 with. Send the 409's impact alongside as acknowledgedImpact.

Example request

{
  "externalExperienceId": "course-photography-101",
  "title": "Photography 101",
  "description": "Six lessons, shot on film.",
  "imageUrl": "https://example.com/covers/photography-101.jpg",
  "externalUrl": "https://example.com/experiences/photography-101",
  "priceCents": 1500,
  "experienceType": "GAME",
  "actions": [
    {
      "externalActionId": "spin",
      "title": "Spin the wheel",
      "priceCents": 1500
    }
  ],
  "acknowledgePaidImpact": true,
  "acknowledgedImpact": {
    "affectedFanCount": 3,
    "oneTimePurchaseCount": 3
  }
}

Response

The experience as published, with the type and price Fanvue recorded

Example response

{
  "experience": {
    "externalExperienceId": "course-photography-101",
    "priceCents": 1500,
    "publishedAt": "2026-10-07T10:00:00.000Z",
    "reviewStatus": "approved",
    "reviewRejection": {
      "reasonCodes": [
        "7.3"
      ],
      "message": "The cover and title do not match what the experience shows fans."
    },
    "url": "https://www.fanvue.com/ava/experiences/summer-yoga-course"
  }
}

Changes