Skip to main content
Publishing puts an experience on the creator’s profile for fans to open. Once it’s live you can update or unpublish it, and a guard checks every change that takes away access fans have paid for. You need an on-platform app with a fan surface, installed by the creator, and a creator token with write:experience. There are two ways to publish, and they differ in who has the final say.

Request token and creator confirmation

POST /experiences/request-token needs write:experience and counts against the default rate limit. The body is discriminated on action; a publish request takes these fields. suggestedPriceCents is only a prefill. The creator sets the amount a fan is charged, and may decline any action. An unpublish request carries action: "unpublish", experienceUuid, title (your label for the confirmation dialog) and appUuid. The response is { token }. The token is sealed and bound to your app and the acting creator. It’s valid for 20 minutes and isn’t single-use.
Your creator surface then posts the token to Fanvue and waits for the reply.
In the dialog, the creator can:
  • edit the title, description and type
  • pick an access mode, from the ones allowedAccessModes allows
  • set the price, prefilled at 5 USD and between 300 and 50000 cents
  • tick and price each proposed action
A cancelled result carries reason when the ending was not the creator’s own decision. It is absent on a plain dismissal and on every result from a Fanvue build that predates the field, so act on status first. experienceId and experience come only with published. Treat a reason you don’t recognise as a refusal: Fanvue may add values, and the SDK accepts any string. upstream_refused means one of these:
  • the experience is gone, or the app no longer matches it
  • the creator has not installed your app
  • your app is suspended or archived
  • your app is unapproved and the creator is not its owner with unpublished access
Check isFanvueOrigin on every reply. It accepts only https origins on fanvue.com or *.fanvue.com. The SDK ships mintPublishRequestToken, mintUnpublishRequestToken, isPublishResultMessage, isUnpublishResultMessage and isFanvueOrigin. The result does not include the per-action prices the creator set; read the live catalogue with GET /experiences/{experienceUuid}/actions. On 0.8.0 the result schema omits reason, so read it from the raw message.

Direct API

Direct writes set the access mode, prices and actions without a creator dialog, on the strength of the write:experience grant. Every call is scoped to your app and to the creator whose token is calling. Publish body fields: The per-action price field differs between the two paths. The request-token body calls it suggestedPriceCents, because the creator may change it in the dialog. The direct publish body calls it priceCents, because your app sets the amount that is charged. On PATCH, priceCents needs accessMode: "PAID" in the same call. actions re-prices the actions listed and withdraws every other active one, and declaring a new action takes a publish. An experience owned by another app answers 404.
An AppExperience has the fields uuid, appUuid, creatorUuid, externalExperienceId, title, description, imageUrl, accessMode, experienceType, deliveryMode, externalUrl, hidden, priceCents, priceRecurring and publishedAt. publishedAt is null while unpublished. impact is { affectedFanCount, activeSubscriptionCount, pendingSubscriptionInvoiceCount, oneTimePurchaseCount, pendingPurchaseCount }. After paid_impact_acknowledgement_required, retry with acknowledgePaidImpact: true and the impact echoed back as acknowledgedImpact.
The SDK exposes client.experiences.list, publish, update and unpublish. PublishExperienceResult is published, acknowledgement_required, blocked or refused.

Taking paid access away

A guard runs on every change that removes paid access, and what it does depends on the kind of access fans hold.
  • Recurring access blocks the change. When activeSubscriptionCount or pendingSubscriptionInvoiceCount is above 0, no acknowledgement is possible. Switch the experience to FREE and let the subscriptions run out instead.
  • One-off access needs acknowledging. When oneTimePurchaseCount or pendingPurchaseCount is above 0, echo every count back. A count that grew since the 409 is a fresh rejection.
Pending invoices older than 7 days are ignored. These changes trigger the guard: The creator’s dialog shows up to 50 affected subscriber handles, while the API returns counts only.

Test before approval

Install your draft app from App details, open it as the creator and publish. Other fans can’t reach a draft experience until the app is approved. If the creator’s account doesn’t have fan experience publishing enabled, writes answer 403 with an error saying publishing is not enabled for the creator, and the confirmation dialog leaves out proposed actions.

See also