Guides
Learn how to integrate with Fanbase API 2.1
Contents
Release Notes
8 October 2026 — Removed signup calls
POST /fan/email/signup and POST /fan/signup
are not supported on Fanbase API 2.1. Both return not found.
Start signup with POST /fan/signup-start. Complete it
with POST /fan/signup-confirm, using the token from the
confirmation email.
8 October 2026 — Asynchronous writes
Fanbase API writes are now asynchronous so the API can scale for the biggest events. Writes are queued. At extremely busy times, a fan may not be created for several minutes. Some responses have changed because of this. The changes are listed below, and they may be breaking changes depending on what your client expects.
Some calls now return as soon as the request is accepted. The write is stored afterwards. A successful response means the request was accepted. A read made immediately afterwards can still return the previous data.
Where the response includes the new values, use that body. Read the resource again only after the write has completed.
PATCH /fan
The response is an optimistic fan record. It includes the fields you
sent and a new updatedAt. Those fields are stored after
the response. GET /fan can still return the previous
profile.
When the fan record does not exist yet, the call succeeds and the
response contains role, email, and
token only.
POST /fan/signup-start
The fan record is created after the response, and the confirmation
email is sent after the response. The response flags
(hasFullName, hasLocation, and the rest)
describe the fan as stored before this call.
consentEmail includes the value sent on this call.
A new fan may not exist when you receive the token. A later write that needs that fan, such as a profile update, telemetry, or an attribute, is accepted and applied once the fan exists.
Captcha, email, return URL, and unique-code checks still reject the request.
POST /fan/signup-confirm
registeredAt and emailVerifiedAt in the
response are the values that will be stored. They are written after
the response. A friend link from friendId is created
after the response.
When signup has not finished creating the fan, the response contains
role, email, and token only.
id and the profile fields are included once the fan
record exists.
POST /fan/verify-phone-start
The SMS, and any consentMessaging update, happen after
the response. Production still returns
{"status":"OK"}.
An invalid phone number, a page that belongs to another artist, or a
bad returnUrl still rejects the request.
POST /fan/verify-phone-complete
The response includes countryCallingCode,
nationalPhoneNumber, and phoneNumber for
the number being verified. Those values are stored after the
response. phoneValidatedAt on this response is the value
already stored. A later GET /fan includes the new
phoneValidatedAt once the write has completed.
An invalid phone number, a page mismatch, or a missing fan still rejects the request.
POST /fan/attribute
The response is {"status":"OK"} before the attribute is
stored. GET /fan/attribute can omit the value you just
sent. When the fan record does not exist yet, the call succeeds and
the attribute is stored once the fan exists.
POST /telemetry
The response is {"status":"OK"} before the event is
stored. This includes link-click-post and
link-click-page. GET /telemetry can omit
the event. When the fan record does not exist yet, the call succeeds
and the event is stored once the fan exists.
POST /poll/answers
The response is {"status":"OK"} before the vote is
stored. GET /poll/results can omit it. When the fan
record does not exist yet, or the poll cannot be saved, the call
still succeeds. The body must be valid JSON, and the caller must be
authenticated.
POST /ugc
The response is {"status":"OK"} before the content is
stored. When the fan record does not exist yet, the call succeeds
and the content is stored once the fan exists.
POST /ugc/upload-url still returns the signed upload URL
in the response.
POST /presave
Spotify, Deezer, and Apple credentials are still checked before the
response. A credential that cannot be exchanged still rejects the
call. The presave is stored after that check. A following
GET /fan can still report
receivesSpotify, receivesApple, or
receivesDeezer as false until the save completes. When
the fan record does not exist yet, a call with accepted credentials
succeeds and the presave is stored once the fan exists.
Getting Started
Fanbase API is available exclusively to artists on the Legendary plan. If you are on Legendary and ready to get started, everything you need is in this documentation.
Your Artist ID is available from your Artist Success Account Manager. No additional provisioning is required to access the staging environment. When you are ready to go live, switch to the live base URL.
For questions, contact your Artist Success Account Manager. Technical escalations are handled internally by our engineering team and routed through your dedicated Slack channel or outreach to your Artist Success Account Manager.
Support
For questions about the API, contact your Artist Success Account Manager. Technical questions are routed internally to our engineering team. If you are on Legendary, you will have access to a dedicated Slack channel where both your Account Manager and engineering team have visibility.
If you do not know who your Artist Success Account Manager is, email support@openstage.live.
For production issues, reach out through the same channels and flag urgency in your message. We do not have a separate critical support path at this time but will respond as a priority.
Onboarding
As part of your Fanbase API access, you will receive onboarding sessions with the Openstage team to help you scope your build, work through integration, and get to launch. Your Account Manager will coordinate scheduling.
Base URLs
-
Live:
https://api.openstage.live/fan2.1 -
Stage:
https://api-stage.openstage.live/fan2.1
(stage has a copy of the live data, and is overwritten every day)
ArtistId
All APIs require an artistId. Your artistId is available on the Artist Settings page of your Openstage Manager Console.
Access Tokens
Most APIs require an Access Token identifying the Fan.
New Fans
fan/email/signup and fan/signup are not
supported on Fanbase API 2.1. Use fan/signup-start and
fan/signup-confirm. See the
release notes.
A new Access Token is obtained in a two-step process:
-
Call
fan/signup-start(no auth required). WithconfirmEmailset, this sends a confirmation email. The email contains a token appended to the returnUrl you supply. -
Call
fan/signup-confirmusing the token acquired in step 1. This returns a fan record containing an access token. Store it and use it for subsequent requests.
Existing Fans
Existing Fans can obtain an Access Token in two ways:
- Use
fan/loginAPI -
Use
fan/email/magic-linkto receive an email containing a Magic Link token which can be exchanged for an Access Token by callingfan/login/magic-linkAPI.
FAQ
How do I get access to Fanbase API?
Fanbase API is available exclusively on the Legendary plan. Everything you need to get started is in this documentation. Your Artist ID is in your Openstage Manager Console under Artist Settings.
What is the difference between the staging and live environments?
Staging (https://api-stage.openstage.live/fan2.1) runs a
copy of live data and is overwritten daily. Use it for testing.
Switch to the live URL
(https://api.openstage.live/fan2.1) when you are ready
for production.
Are there rate limits?
There are no hard rate limits. Under heavy load, non-critical tasks such as tagging are queued and processed within minutes. For the vast majority of use cases this is not a concern.
What is the versioning policy?
We will introduce versioning when breaking changes are made. You will be notified in advance of any breaking changes. Non-breaking updates are made without version changes.
What if I find a bug in production?
Contact your Artist Success Account Manager and flag it as a production issue. Technical issues are triaged internally and addressed as a priority.
Do I need to do anything to move from staging to production?
No. Switch to the live base URL when you are ready. No additional provisioning is required.
Who do I contact for technical support?
Start with your Artist Success Account Manager via email or your dedicated Slack channel if you have one. Technical questions are routed to our engineering team internally.
Are there known limitations I should be aware of?
Push notifications are not currently supported via the API. XP and badges are in development. Any additional limitations will be documented here as they are identified.
Openstage Fan vs FanArtist
Fan login details (email and password, or magic link token) are shared between artists' platforms on Openstage. The email address field is unique and required, but your frontend can decide which set of the other fan detail fields are required for your fans to use your platform. Note that a fan having a valid login does not guarantee the existence of the other fan detail fields. We recommend implementing a "Missing details" view or popup to collect these after login.
The email and SMS consent fields are specific consents to your artists and are not shared between Openstage artists. If a fan with an existing account from another artist logs in to your account, they will not have given consent to your artist yet, so you must collect the appropriate consent from them, detailing the terms and conditions and privacy policy in the process.
User Creation Flow
-
First call the
/signupendpoint with the new fan's email address. - If a fan login account with this email address already exists on Openstage (for any artist), the API will respond with 500 and an appropriate message. You should prompt your fans to log in with their existing login details.
- Otherwise, the response is 200 and the API will send an email with a signup token to the given email address.
-
The fan clicks on the link in the email. This takes them to
/signup?token=..., at which point your frontend should display the required fan details form fields along with the password (and password repeat) field. Validate these details first, then:-
Call
/signupwith the signup token auth header, the artistId and the password in the body payload. -
Then call
/fanPATCH with the fan details to submit the form data. -
Then call
/loginto log the fan in with the auth from the/fanresponse.
-
Call
- At this point your fan's account is created and the fan is logged in, so you can move to the membership selection step if needed.
Payments and Card Details with Stripe
Set Up Payment Methods in Stripe Dashboard
- Log into the Stripe Dashboard.
- Go to Settings > Payments > Payment methods.
- Optional: Use Stripe's test mode to check your integration and customer flow without placing production orders. You can do this by toggling Test mode in your Stripe dashboard before enabling the payment method.
- On the list of payment methods, find the desired payment method and click Turn on.
- After successful testing, make sure to use your live account instead of sandbox mode.
Install Dependencies
Make sure you have the required dependencies installed:
npm install @stripe/stripe-js
Environment Setup
First, you need to set up the following environment variables in
your .env file:
VITE_STRIPE_PK=your_stripe_publishable_key
VITE_STRIPE_CONNECT_ID=your_stripe_connect_account_id
Both keys can be found in your Stripe Dashboard's main screen.
Creating a Stripe Instance
We call getStripeInstance when mounting our component
(StripePaymentForm.vue), which uses the
VITE_STRIPE_CONNECT_ID from the .env file.
This method calls Stripe's loadStripe function which
creates the instance with the given Connect ID.
After the instance has been created, we call
fanStore.subscribe(selectedTierId). If Openstage is
able to use existing (Stripe) payment details for this fan, the
endpoint returns "ok" to indicate success. If the fan needs to enter
payment details it returns a clientSecret.
With the returned clientSecret, we can create a Stripe
Element, and with that we can mount the payment form in our
component using Stripe's mount function.
It is also possible to change the tier a user is subscribed to using the fanStore.subscribe(selectedTierId) method (with a different tier ID than their current one).
Submit Payment Form
-
We have to call Stripe Element's
submitfunction on our Stripe Element, only move forward if that doesn't return an error. -
After that, use Stripe's
confirmPayment, with the params:-
elements: previously created Stripe Element -
clientSecret: the clientSecret returned fromfanStore.subscribe() -
confirmParams:{
return_url: window.location.href + '?tierId=' + selectedTierId,
} redirect: 'if_required'
-
After a successful payment, our application communicates with Stripe
via a webhook. Until that doesn't finish, we need to call
fanStore.fanGet() to see whether the
subscriptionId has been set to the fan by our backend.
(Create a loop for that call until the endpoint returns the
subscriptionId.)
Testing the redirect flow should work the same, with the addition to
only call fanStore.fanGet() when the
return_url has redirect_status=succeeded.
Redirection logic example component:
StripeRedirectDialog.vue
Test Payment Methods
- Use Stripe's test mode and test card numbers
-
Test different payment scenarios:
- Successful payment
- Failed payment
- Card decline
- 3D Secure authentication
- Test the redirect flow
Production Deployment
- Before going live, switch to production Stripe keys
- Set up proper webhook endpoints
- Test the entire payment flow in production mode
Video Playback with MUX Player
We use Mux for video playback because it delivers content via adaptive bitrate streaming, ensuring smooth, high-quality experiences across devices and network conditions.
Unlike static video files, Mux dynamically adjusts video quality, supports global delivery at scale, and simplifies encoding, compatibility and access management.
To secure access, we use signed playback URLs, which restrict where and when videos can be viewed—preventing unauthorized sharing and enforcing access rules. This approach balances performance, scalability, and security while offering a seamless viewing experience.
Required Parameters
<mux-player> expects playback-id,
playback-token, and thumbnail-token for
successful playback. Grab these from
/post/playAsset for your given id. The
tokens have an expiration time of 2 hours, so we recommend fetching
them when they are needed.
Metadata Tracking
Additionally, for better metrics tracking, please also set the following attributes:
-
metadata-video-id
The id of the content the video belongs to (uuid string) -
metadata-video-title
The title of the content the video belongs to (string) -
metadata-viewer-user-id
The viewing user's Openstage identifier (uuid string) -
metadata-sub-property-id
The name of your project (string)
Domain Setup
Please contact Openstage to set up your domain for signed URL playback.
Documentation
Official documentation: https://www.mux.com/docs/guides/play-your-videos
Fan Pass (Alpha)
Fan Pass is in alpha. Speak to your account manager if you are interested in enabling it for your account.
A Fan Pass is the artist's wallet card. Fans add it to Apple Wallet
or Google Wallet. The artist publishes the design in Openstage
Manager. Adding a pass requires a fan Access Token in the
auth header, and the fan must have finished signup
for this artist.
Check that a pass is published
No auth header is required.
GET /fan/wallet/status?artistId={artistId}
{ "available": true }
Hide the Fan Pass UI when available is
false. That includes artists still on a legacy wallet
pass.
Preview
GET /fan/wallet/pass
-
Signed out: pass
artistId. Fan fields are sample data. -
Signed in: send the
authheader and omitartistId. The response uses that fan's details.
The response is 404 when no Fan Pass is published.
Otherwise it is payload (the design) and
sampleFan (name and dates) for rendering the card.
Field names are in the API reference.
Add the pass on a phone
Request the save URL and send the browser there.
GET /fan/wallet?platform=apple&redirect=false
GET /fan/wallet?platform=google&redirect=false
Send the auth header. The artist is taken from that
token. The response is { "url": "…" }. Apple's URL is
a .pkpass file. Google's URL is a Google Wallet save
link. Without redirect=false the same call is a
307 to that URL.
Add the pass from a desktop
A desktop browser cannot open the wallet apps. Mint a one-hour link and show it as a QR code.
GET /fan/wallet/handoff?origin=https://artist.os.fan
Send the auth header. origin is this
artist's fan site origin (scheme and host only). The phone returns
there when it cannot add the pass directly.
{ "url": "https://api.openstage.live/fan2.1/fan/wallet/handoff?token=…", "expiresAt": "2026-10-02T15:00:00Z" }
Encode url in the QR code and refresh it before
expiresAt. Opening the link is a 307:
- iPhone or iPad goes to Apple Wallet. Android goes to Google Wallet.
-
Any other device goes to
{origin}/pass/add?token={token}. -
An expired link goes to
{origin}/pass/add?handoff=expired. A link that cannot create the pass goes to{origin}/pass/add?handoff=failed.
Host /pass/add on that origin. With
?token=, link each wallet badge to the handoff URL
with platform=apple or platform=google.
No auth header is required. With
handoff=expired or handoff=failed, send
the fan back to a signed-in page to mint a new link.
After the pass is saved
Openstage updates installed passes when the artist publishes a design change or sends a pass notification. The fan does not call the API again for those updates.