curl --request GET \
--url https://api.fanvue.com/v1/experiences/{experienceUuid}/action-purchases/{purchaseReference} \
--header 'Authorization: Bearer <token>' \
--header 'X-Fanvue-API-Version: <x-fanvue-api-version>'import requests
url = "https://api.fanvue.com/v1/experiences/{experienceUuid}/action-purchases/{purchaseReference}"
headers = {
"X-Fanvue-API-Version": "<x-fanvue-api-version>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'X-Fanvue-API-Version': '<x-fanvue-api-version>',
Authorization: 'Bearer <token>'
}
};
fetch('https://api.fanvue.com/v1/experiences/{experienceUuid}/action-purchases/{purchaseReference}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"purchaseReference": "expact_5c9a1f0e-9f3f-4c2a-8f31-1d0f6a2b7c44",
"experienceUuid": "00000000-0000-4000-8000-000000000010",
"externalActionId": "spin",
"clientReferenceId": "round-42",
"buyerUuid": "00000000-0000-4000-8000-000000000003",
"amount": 700,
"currency": "USD",
"status": "succeeded",
"invoiceNumber": "FVE-20260904-1234",
"createdAt": "2026-09-04T10:00:00.000Z",
"paidAt": "2026-09-04T10:00:02.000Z"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"message": "<string>"
}{
"error": "<string>",
"message": "<string>",
"nextVersion": "<string>"
}{
"error": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}Get one action purchase by its purchase reference
Fetches a single action purchase by the expact_… reference your webhook carried.
Fulfil on the webhook, never on the bridge result. Grant the action when you receive app.experience.action.payment.succeeded, keyed on purchase_reference so a redelivery grants nothing twice. The purchaseResult message your iframe receives from Fanvue is UX only — it tells your surface to stop showing a spinner, and it is never proof that money moved. This read is the reconciliation path: poll it when you think you missed a webhook, or to confirm one you are unsure about.
Owner app only. A reference that belongs to another app, to another experience, or to nothing at all all answer 404 alike — the read never confirms that a reference exists somewhere you cannot see.
curl --request GET \
--url https://api.fanvue.com/v1/experiences/{experienceUuid}/action-purchases/{purchaseReference} \
--header 'Authorization: Bearer <token>' \
--header 'X-Fanvue-API-Version: <x-fanvue-api-version>'import requests
url = "https://api.fanvue.com/v1/experiences/{experienceUuid}/action-purchases/{purchaseReference}"
headers = {
"X-Fanvue-API-Version": "<x-fanvue-api-version>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'X-Fanvue-API-Version': '<x-fanvue-api-version>',
Authorization: 'Bearer <token>'
}
};
fetch('https://api.fanvue.com/v1/experiences/{experienceUuid}/action-purchases/{purchaseReference}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"purchaseReference": "expact_5c9a1f0e-9f3f-4c2a-8f31-1d0f6a2b7c44",
"experienceUuid": "00000000-0000-4000-8000-000000000010",
"externalActionId": "spin",
"clientReferenceId": "round-42",
"buyerUuid": "00000000-0000-4000-8000-000000000003",
"amount": 700,
"currency": "USD",
"status": "succeeded",
"invoiceNumber": "FVE-20260904-1234",
"createdAt": "2026-09-04T10:00:00.000Z",
"paidAt": "2026-09-04T10:00:02.000Z"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"message": "<string>"
}{
"error": "<string>",
"message": "<string>",
"nextVersion": "<string>"
}{
"error": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}read:experience— Exchange a fan’s experience token for the resolved experience and the fan’s identity, so an embedded fan-facing experience can render the right content.
Authorizations
OAuth 2.0 access token, presented as a JWT bearer token in the Authorization header. Obtain a token via the authorization-code flow; the scopes granted to the token determine which operations it may call.
Headers
API version to use for the request
"2025-06-26"
Path Parameters
"00000000-0000-4000-8000-000000000010"
1 - 200"expact_5c9a1f0e-9f3f-4c2a-8f31-1d0f6a2b7c44"
Response
The action purchase
The expact_… reference minted with the purchase attempt. THE fulfilment idempotency key: grant the action at most once per reference, and only for a purchase whose status is succeeded.
"expact_5c9a1f0e-9f3f-4c2a-8f31-1d0f6a2b7c44"
The experience the action belongs to.
"00000000-0000-4000-8000-000000000010"
The app's own stable key for the action that was bought.
"spin"
The app-supplied reference carried through the purchase, or null when the app supplied none.
"round-42"
UUID of the fan who bought the action. The only identifier of the buyer this surface carries — no handle, no display name, no email.
"00000000-0000-4000-8000-000000000003"
Price in minor currency units (cents), frozen at the purchase attempt. A later re-pricing of the action does not move it.
700
ISO 4217 code of the amount. USD only today.
"USD"
Where the money for this purchase attempt ended up. Fulfil only on succeeded. refunded, disputed and cancelled all mean the money is not the creator's, so revoke on any of them — the difference between them only records how the reversal was written, not whether to act. refunded is a reversal carrying a refund reference (a settled payment paid back, or an authorisation voided before capture); disputed is a chargeback that was lost and reversed; cancelled is a reversal carrying neither reference (a delayed capture that failed, or the uncaptured-invoice sweeper). An open dispute that has not been lost is still succeeded here — the money has not moved — so watch app.experience.action.dispute.* for that, not this field. A refund the processor accepted and then rejected also reports succeeded again: this field is where the money ended up, not what was attempted.
pending, succeeded, failed, refunded, disputed, cancelled Fanvue invoice number for the charge. For support and accounting, not fulfilment.
"FVE-20260904-1234"
When the purchase attempt was opened.
"2026-09-04T10:00:00.000Z"
When the charge settled, or null while it has not.
"2026-09-04T10:00:02.000Z"
Was this page helpful?