Documentation Index Fetch the complete documentation index at: https://docs.ofauth.com/llms.txt
Use this file to discover all available pages before exploring further.
Learn how to create posts on OnlyFans using the OFAuth API, including adding media, scheduling, PPV pricing, and polls.
Prerequisites
Media uploaded to vault (see Upload Media ) if including images/videos
Create a Simple Text Post
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "Just posted something new! 🔥"
})
})
const post = await response . json ()
console . log ( "Post created! ID:" , post . id )
Create Post with Media
Include images or videos in your post:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "New content just dropped! 📸" ,
mediaItems: [ 12345 , 12346 , 12347 ] // Media IDs from vault
})
})
For all accepted mediaItems values (vault IDs, upload references, URLs) and validation rules, see the mediaItems reference .
Create a PPV (Pay-Per-View) Post
Lock content behind a paywall:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "Exclusive content! 🔒 Unlock to see more..." ,
mediaItems: [ 12345 , 12346 ],
price: 14.99 , // Price in USD ($3-$200)
previewMediaCount: 1 // First 1 item in mediaItems (left to right) is preview
})
})
PPV Options
Option Type Description pricenumber PPV price in USD (3 m i n , 3 min, 3 min , 200 max) previewMediaCountnumber How many mediaItems are previews. Uses the first N items from left to right. isLockedTextboolean Also hide the caption until purchased
Schedule a Post
Create a post to publish later:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "This will go live tomorrow! 🎉" ,
mediaItems: [ 12345 ],
scheduledDate: "2024-12-25T12:00:00Z" // ISO 8601 format
})
})
const post = await response . json ()
console . log ( "Scheduled for:" , post . scheduledDate )
Scheduled posts are stored in OnlyFans’ queue. Use an ISO 8601 date string for scheduledDate.
Create a Poll Post
Attach a poll to a managed post request:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "Which set should I shoot next?" ,
poll: {
options: [ "Beach set" , "Studio set" ],
type: 1 ,
dueDays: 7
}
})
})
Poll Options
Option Type Description poll.optionsstring[] Poll answer options. Minimum 2 items. poll.typenumber OnlyFans poll type. poll.dueDaysnumber Number of days before the poll closes.
OFAuth maps the managed poll object to OnlyFans’ upstream poll fields automatically. You do not need to send raw votingOptions, votingType, or votingDue.
Create Expiring Post
Post that auto-deletes after a set period:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "Limited time only! ⏰" ,
mediaItems: [ 12345 ],
expireAfter: 7 // Days until post expires (1-30)
})
})
Create Fundraising Post
Create a post with fundraising goal:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "Help me reach my goal! 🎯" ,
fundRaisingTargetAmount: 500 , // Target in USD (min $10)
fundRaisingTipsPresets: [ 5 , 10 , 25 , 50 ] // Suggested tip amounts (max 4)
})
})
Text Formatting
Posts support markdown formatting:
{
"text" : "**Bold headline** \n\n *Italic text* and regular text. \n\n New paragraph here!" ,
"isMarkdown" : true // Default
}
Supported:
**bold** → bold
*italic* → italic
\n\n → New paragraph
Edit an Existing Post
Update a post’s content:
const response = await fetch ( "https://api.ofauth.com/v2/access/posts/POST_ID" , {
method: "PUT" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123" ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
text: "Updated caption! ✨" ,
mediaItems: [ 12345 , 12346 ] // Can add/remove media
})
})
Delete a Post
const response = await fetch ( "https://api.ofauth.com/v2/access/posts/POST_ID" , {
method: "DELETE" ,
headers: {
apikey: "YOUR_API_KEY" ,
"x-connection-id" : "conn_abc123"
}
})
if ( response . ok ) {
console . log ( "Post deleted!" )
}
Complete Example
Full workflow: upload media, then create post:
const API_KEY = "YOUR_API_KEY"
const CONNECTION_ID = "conn_abc123"
const headers = {
apikey: API_KEY ,
"x-connection-id" : CONNECTION_ID ,
"Content-Type" : "application/json"
}
async function createPostWithMedia ( imageBuffer , caption ) {
// Step 1: Initialize upload
const initResponse = await fetch ( "https://api.ofauth.com/v2/access/uploads/init" , {
method: "POST" ,
headers ,
body: JSON . stringify ({
filename: "photo.jpg" ,
filesize: imageBuffer . length ,
mimeType: "image/jpeg"
})
})
const { mediaUploadId } = await initResponse . json ()
// Step 2: Upload the file
await fetch ( `https://api.ofauth.com/v2/access/uploads/ ${ mediaUploadId } ` , {
method: "PUT" ,
headers: {
... headers ,
"Content-Type" : "image/jpeg"
},
body: imageBuffer
})
// Step 3: Complete upload
const completeResponse = await fetch ( "https://api.ofauth.com/v2/access/uploads/complete" , {
method: "POST" ,
headers ,
body: JSON . stringify ({ mediaUploadId })
})
const { media } = await completeResponse . json ()
console . log ( "Media uploaded! ID:" , media . id )
// Step 4: Create post with the uploaded media
const postResponse = await fetch ( "https://api.ofauth.com/v2/access/posts" , {
method: "POST" ,
headers ,
body: JSON . stringify ({
text: caption ,
mediaItems: [ media . id ]
})
})
const post = await postResponse . json ()
console . log ( "Post created! ID:" , post . id )
return post
}
// Usage
const imageBuffer = fs . readFileSync ( "photo.jpg" )
createPostWithMedia ( imageBuffer , "New photo! 📸" )
All Post Options
Option Type Description textstring Post caption (supports markdown ) mediaItemsnumber[] Array of media IDs from vault pricenumber PPV price (3 − 3- 3 − 200) isLockedTextboolean Lock caption behind paywall previewMediaCountnumber How many mediaItems are previews. Uses the first N items from left to right. scheduledDatestring ISO date for scheduled posting pollobject Poll configuration with options, type, and dueDays expireAfternumber Days until auto-delete (1-30) fundRaisingTargetAmountnumber Fundraising goal (min $10) fundRaisingTipsPresetsnumber[] Suggested tip amounts (max 4) isMarkdownboolean Parse text as markdown (default: true) userTagsnumber[] Tag users in post releaseFormsobject Release form attachments
Next Steps
Upload Media Learn the full media upload flow
Send Message Share content via DM