Learn how to send direct messages to fans using the OFAuth API.
Prerequisites
Send a Simple Text Message
const response = await fetch("https://api.ofauth.com/v2/access/chats/USER_ID/messages", {
method: "POST",
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123",
"Content-Type": "application/json"
},
body: JSON.stringify({
text: "Hey! Thanks for subscribing 💕"
})
})
const message = await response.json()
console.log("Message sent! ID:", message.id)
Replace USER_ID with the OnlyFans user ID of the recipient. You can get user IDs from the subscribers endpoint.
Find a User to Message
First, get your subscribers to find someone to message:
// Get active subscribers
const response = await fetch("https://api.ofauth.com/v2/access/subscriptions/subscribers?type=active&limit=10", {
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123"
}
})
const subscribers = await response.json()
// Get the first subscriber's ID
const userId = subscribers[0].id
console.log("Will message user:", subscribers[0].username, "(ID:", userId, ")")
Include images or videos in your message:
const response = await fetch("https://api.ofauth.com/v2/access/chats/USER_ID/messages", {
method: "POST",
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123",
"Content-Type": "application/json"
},
body: JSON.stringify({
text: "Check out this exclusive content 🔥",
mediaItems: [12345, 12346] // Media IDs from vault
})
})
For all accepted mediaItems values (vault IDs, upload references, URLs) and validation rules, see the mediaItems reference.
Send a PPV (Pay-Per-View) Message
Lock content behind a paywall:
const response = await fetch("https://api.ofauth.com/v2/access/chats/USER_ID/messages", {
method: "POST",
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123",
"Content-Type": "application/json"
},
body: JSON.stringify({
text: "Exclusive content just for you 💋",
mediaItems: [12345],
price: 9.99, // Price in USD ($3-$200)
previewMediaCount: 1 // First 1 item in mediaItems (left to right) is preview
})
})
| Option | Type | Description |
|---|
price | number | PPV price in USD (3min,200 max) |
previewMediaCount | number | How many mediaItems are previews. Uses the first N items from left to right. |
isLockedText | boolean | Also lock the text behind paywall |
Text Formatting
Messages support markdown formatting by default:
const response = await fetch("https://api.ofauth.com/v2/access/chats/USER_ID/messages", {
method: "POST",
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123",
"Content-Type": "application/json"
},
body: JSON.stringify({
text: "**Bold text** and *italic* work!\n\nNew paragraphs too.",
isMarkdown: true // Default is true
})
})
Supported formatting:
**bold** → bold
*italic* → italic
\n\n → New paragraph
To send raw text without markdown parsing:
{
"text": "This **won't** be bold",
"isMarkdown": false
}
Read Chat History
Before sending, you might want to see previous messages:
const response = await fetch("https://api.ofauth.com/v2/access/chats/USER_ID/messages?limit=20", {
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123"
}
})
const messages = await response.json()
messages.forEach(msg => {
const sender = msg.isFromMe ? "You" : "Fan"
console.log(`${sender}: ${msg.text}`)
})
Delete a Message
Made a mistake? Delete a sent message:
const response = await fetch("https://api.ofauth.com/v2/access/chats/USER_ID/messages/MESSAGE_ID", {
method: "DELETE",
headers: {
apikey: "YOUR_API_KEY",
"x-connection-id": "conn_abc123"
}
})
Complete Example
Here’s a full example that finds a subscriber and sends them a message:
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 sendWelcomeMessage() {
// 1. Get recent subscribers
const subsResponse = await fetch(
"https://api.ofauth.com/v2/access/subscriptions/subscribers?type=active&limit=1",
{ headers }
)
const subscribers = await subsResponse.json()
if (subscribers.length === 0) {
console.log("No subscribers found")
return
}
const fan = subscribers[0]
console.log(`Sending message to ${fan.username}...`)
// 2. Send welcome message
const msgResponse = await fetch(
`https://api.ofauth.com/v2/access/chats/${fan.id}/messages`,
{
method: "POST",
headers,
body: JSON.stringify({
text: `Hey ${fan.name}! 👋\n\nThanks so much for subscribing! Let me know if there's anything specific you'd like to see. 💕`
})
}
)
const message = await msgResponse.json()
console.log("Message sent! ID:", message.id)
}
sendWelcomeMessage()
Rate Limits
OnlyFans has rate limits on messaging. Avoid sending too many messages in quick succession.
Best practices:
- Space out individual messages by at least 1-2 seconds
- For bulk messaging, use the mass message queue instead
- Implement exponential backoff on 429 errors
Next Steps
Mass Messaging
Send to multiple fans at once
Upload Media
Upload content to include in messages