Skip to main content

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, and PPV pricing.

Prerequisites

You have a connected OnlyFans account with a valid connectionId
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

OptionTypeDescription
pricenumberPPV price in USD (3min,3 min, 200 max)
previewMediaCountnumberHow many mediaItems are previews. Uses the first N items from left to right.
isLockedTextbooleanAlso 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 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:
See Text Formatting Guide for the full formatting reference.
{
  "text": "**Bold headline**\n\n*Italic text* and regular text.\n\nNew 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

OptionTypeDescription
textstringPost caption (supports markdown)
mediaItemsnumber[]Array of media IDs from vault
pricenumberPPV price (33-200)
isLockedTextbooleanLock caption behind paywall
previewMediaCountnumberHow many mediaItems are previews. Uses the first N items from left to right.
scheduledDatestringISO date for scheduled posting
expireAfternumberDays until auto-delete (1-30)
fundRaisingTargetAmountnumberFundraising goal (min $10)
fundRaisingTipsPresetsnumber[]Suggested tip amounts (max 4)
isMarkdownbooleanParse text as markdown (default: true)
userTagsnumber[]Tag users in post
releaseFormsobjectRelease form attachments

Next Steps

Upload Media

Learn the full media upload flow

Send Message

Share content via DM