OnlyFans PPV API
Pay-per-view is a priced message: a fan pays to unlock locked text or media. The onlyfans ppv api is the send-and-read side of that flow — attach a price and vault media to a DM, then read back whether each fan unlocked it. It's built on the same messaging endpoint you already use, with three extra fields: price, lockedText, and previews.
Sending a PPV message
POST /api/public/v1/chats/{chatId}/messages
# account-scoped (agencies)
POST /api/public/v1/accounts/{accountId}/chats/{chatId}/messages
The relevant body fields:
| Field | Type | Meaning |
|---|---|---|
price |
int | Unlock price in cents (500 = $5.00) |
lockedText |
bool | Lock the text as PPV — requires price > 0 |
mediaFiles |
long[] | Vault media ids to lock behind the price |
previews |
long[] | Vault media ids shown as free preview thumbnails |
curl -X POST \
https://api.ofapis.com/api/public/v1/chats/98765/messages \
-H "Authorization: Bearer ofapis_sk_..." \
-H "Content-Type: application/json" \
-d '{"text":"New set just for you","price":1200,"mediaFiles":[777888999],"previews":[777889000]}'
The mediaFiles ids come from the media upload API — upload the content first, then reference the ids here.
Reading unlock state
Read a conversation's messages to see how a PPV performed. Each message exposes price, isFree, isLockedText, canPurchase, and isOpened. A message with price > 0 where isOpened is true was unlocked by the fan; canPurchase tells you it's still buyable.
curl "https://api.ofapis.com/api/public/v1/chats/98765/messages?limit=50" \
-H "Authorization: Bearer ofapis_sk_..."
Use cases
- Automated PPV drops. After a welcome flow, send a priced set to new subscribers, then poll unlock state to trigger a follow-up to fans who didn't buy.
- Mass PPV. Send the same locked offer to a segment via the mass DM API, which carries the same
lockedTextpricing. - Scheduled PPV. Queue a priced message ahead of time with the scheduling API so drops go out at peak hours.
Gotchas
- Price is in cents.
1200means $12.00, not $1,200. A common bug is a 100x mispriced set. lockedTextneeds a price. Locking withprice: 0is invalid — set a real price or the lock does nothing.- Upload media first.
mediaFilesandpreviewstake existing vault ids; upload the content before you send, and confirmisMediaReadybefore relying on it. - Billing. One successful send is one credit; each message read page is one credit. Failed sends (expired session, upstream error) are free.
- Rate limits follow your plan's requests-per-minute — pace mass or scheduled PPV so a burst doesn't trip them. See pricing.
FAQ
How do I price a PPV message?
Set price in cents on the send body — 500 is $5.00 — and include the vault ids you want locked in mediaFiles. To lock the text itself, also set lockedText: true, which requires price > 0.
How do I know if a fan unlocked my PPV?
Read the conversation's messages and inspect the priced one. When isOpened is true on a message with price > 0, the fan paid to unlock it; canPurchase indicates it's still available to buy.
Can I send the same PPV to many fans at once?
Yes. Mass mailings support the same lockedText pricing, so you can drop a priced offer to a whole segment rather than one chat at a time.
What's the difference between mediaFiles and previews?
mediaFiles are the locked assets a fan pays to unlock; previews are free thumbnail teasers shown before purchase. Both reference vault media ids you uploaded beforehand.