> ## 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.

# Send Mass Messages

> Step-by-step guide to send messages to multiple fans at once

Learn how to send messages to multiple fans simultaneously using the OFAuth mass messaging API.

## Prerequisites

<Check>
  You have a [connected OnlyFans account](/guides/link) with a valid `connectionId`
</Check>

***

## Why Use Mass Messaging?

Instead of sending individual messages one-by-one (which hits rate limits), use mass messaging to:

* Send to multiple fans in a single API call
* Schedule messages for later delivery
* Target specific user lists
* Exclude certain user groups
* Track delivery and purchase stats

***

## Send to Specific Users

Send a message to a list of user IDs:

<CodeGroup>
  ```javascript Node.js theme={null}
  const response = await fetch("https://api.ofauth.com/v2/access/mass-messages", {
    method: "POST",
    headers: {
      apikey: "YOUR_API_KEY",
      "x-connection-id": "conn_abc123",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      text: "Hey everyone! New content dropping soon 🔥",
      userIds: [123, 456, 789, 1011, 1213]
    })
  })

  const result = await response.json()
  console.log("Mass message ID:", result.id)
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.ofauth.com/v2/access/mass-messages",
      headers={
          "apikey": "YOUR_API_KEY",
          "x-connection-id": "conn_abc123",
          "Content-Type": "application/json"
      },
      json={
          "text": "Hey everyone! New content dropping soon 🔥",
          "userIds": [123, 456, 789, 1011, 1213]
      }
  )

  result = response.json()
  print("Mass message ID:", result["id"])
  ```
</CodeGroup>

***

## Send to User Lists

Target OnlyFans user lists instead of individual IDs:

```javascript theme={null}
const response = await fetch("https://api.ofauth.com/v2/access/mass-messages", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": "conn_abc123",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    text: "Special message for my VIPs! 💕",
    userLists: [1, 2, 3]  // OnlyFans list IDs
  })
})
```

### Get Available Lists

First, fetch your user lists:

```javascript theme={null}
const response = await fetch("https://api.ofauth.com/v2/access/users/lists", {
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": "conn_abc123"
  }
})

const lists = await response.json()
lists.forEach(list => {
  console.log(`${list.name} (ID: ${list.id})`)
})
```

***

## Exclude Certain Users

Send to lists but exclude specific groups:

```javascript theme={null}
const response = await fetch("https://api.ofauth.com/v2/access/mass-messages", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": "conn_abc123",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    text: "Exclusive offer! 🎁",
    userLists: [1, 2],           // Send to these lists
    excludeUserLists: [3, 4]     // But not these lists
  })
})
```

***

## Target New Subscribers

Send only to users who subscribed after a certain date:

```javascript theme={null}
const response = await fetch("https://api.ofauth.com/v2/access/mass-messages", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": "conn_abc123",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    text: "Welcome to my page! Here's a special gift for new subscribers 🎉",
    userLists: [1],  // Active subscribers list
    subscribedAfterDate: "2024-01-01T00:00:00Z"
  })
})
```

***

## Send PPV Mass Message

Include pay-per-view content:

```javascript theme={null}
const response = await fetch("https://api.ofauth.com/v2/access/mass-messages", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": "conn_abc123",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    text: "Exclusive content you don't want to miss! 🔒",
    mediaItems: [12345, 12346],   // Media IDs from vault
    price: 14.99,                 // PPV price ($3-$200)
    previewMediaCount: 1,         // First 1 item in mediaItems (left to right) is preview
    userLists: [1]
  })
})
```

<Info>
  `mediaItems` accepts vault media IDs, upload references (`mediaUploadId`), and `http(s)` URLs. See the [`mediaItems` reference](/guides/media-items).
</Info>

***

## Schedule for Later

Schedule a message to send at a specific time:

```javascript theme={null}
const response = await fetch("https://api.ofauth.com/v2/access/mass-messages", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": "conn_abc123",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    text: "Happy New Year! 🎆",
    userLists: [1],
    scheduledDate: "2024-12-31T23:59:00Z"  // ISO 8601 format
  })
})

const result = await response.json()
console.log("Message scheduled for:", result.scheduledDate)
```

***

## List Sent Mass Messages

Check the stats of your sent mass messages:

```javascript theme={null}
// Get sent mass message stats
const response = await fetch(
  "https://api.ofauth.com/v2/access/analytics/mass-messages/sent?limit=10",
  { headers }
)

const massMessages = await response.json()
```

### Response

```json theme={null}
{
  "list": [
    {
      "id": 12345,
      "text": "Hey everyone!",
      "sentCount": 150,
      "purchasedCount": 23,
      "totalAmount": 344.77,
      "createdAt": "2024-01-15T10:30:00Z"
    }
  ],
  "hasMore": true
}
```

***

## Get Message Buyers

See who purchased a PPV mass message:

```javascript theme={null}
const response = await fetch(
  "https://api.ofauth.com/v2/access/analytics/mass-messages/MASS_MESSAGE_ID/buyers?limit=20",
  {
    headers: {
      apikey: "YOUR_API_KEY",
      "x-connection-id": "conn_abc123"
    }
  }
)

const buyers = await response.json()
buyers.list.forEach(buyer => {
  console.log(`${buyer.username} - $${buyer.amount}`)
})
```

***

## Update Scheduled Message

Modify a message before it sends:

```javascript theme={null}
const response = await fetch(
  "https://api.ofauth.com/v2/access/mass-messages/MASS_MESSAGE_ID",
  {
    method: "PUT",
    headers: {
      apikey: "YOUR_API_KEY",
      "x-connection-id": "conn_abc123",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      text: "Updated message content! 🔄",
      scheduledDate: "2024-12-26T12:00:00Z"  // Reschedule
    })
  }
)
```

***

## Cancel Scheduled Message

Delete a mass message before it sends:

```javascript theme={null}
const response = await fetch(
  "https://api.ofauth.com/v2/access/mass-messages/MASS_MESSAGE_ID",
  {
    method: "DELETE",
    headers: {
      apikey: "YOUR_API_KEY",
      "x-connection-id": "conn_abc123"
    }
  }
)

if (response.ok) {
  console.log("Mass message cancelled")
}
```

***

## Complete Example

Full workflow: get subscribers, filter, and send:

```javascript theme={null}
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 sendPromoToActiveSubscribers() {
  // Step 1: Get user lists
  const listsResponse = await fetch(
    "https://api.ofauth.com/v2/access/users/lists",
    { headers }
  )
  const lists = await listsResponse.json()
  
  // Find "Active" list (or create targeting logic)
  const activeList = lists.find(l => l.name.toLowerCase().includes("active"))
  
  if (!activeList) {
    console.log("No active list found, sending to all recent subscribers")
  }
  
  // Step 2: Create the mass message
  const messageResponse = await fetch(
    "https://api.ofauth.com/v2/access/mass-messages",
    {
      method: "POST",
      headers,
      body: JSON.stringify({
        text: "🎉 **Special Offer!**\n\nThanks for being an amazing subscriber! Here's 20% off my premium content this week only.\n\nUse code: VIP20 💕",
        userLists: activeList ? [activeList.id] : undefined,
        subscribedAfterDate: activeList ? undefined : "2024-01-01T00:00:00Z"
      })
    }
  )
  
  const result = await messageResponse.json()
  console.log("✅ Mass message created!")
  console.log("   ID:", result.id)
  
  return result
}

sendPromoToActiveSubscribers()
```

***

## All Queue Options

| Option                | Type                | Description                                                                               |
| --------------------- | ------------------- | ----------------------------------------------------------------------------------------- |
| `text`                | string              | Message content (supports [markdown](/guides/how-to/text-formatting))                     |
| `mediaItems`          | (number\|string)\[] | Media IDs, upload references, or URLs (see [`mediaItems` reference](/guides/media-items)) |
| `price`               | number              | PPV price ($3-$200)                                                                       |
| `previewMediaCount`   | number              | How many `mediaItems` are previews. Uses the first N items from left to right.            |
| `isLockedText`        | boolean             | Lock text behind paywall                                                                  |
| `userIds`             | number\[]           | Specific user IDs to target                                                               |
| `userLists`           | number\[]           | User list IDs to target                                                                   |
| `excludeUserLists`    | number\[]           | User list IDs to exclude                                                                  |
| `scheduledDate`       | string              | ISO date for scheduled sending                                                            |
| `subscribedAfterDate` | string              | Only target users subscribed after date                                                   |
| `isMarkdown`          | boolean             | Parse text as markdown (default: true)                                                    |

***

## Tips & Best Practices

<Tip>
  **Use lists for targeting**: Create user lists in OnlyFans (VIPs, top tippers, etc.) for easy targeting without managing individual IDs.
</Tip>

<Warning>
  **Don't spam**: OnlyFans monitors messaging patterns. Excessive mass messaging can result in account restrictions.
</Warning>

<Info>
  **Schedule strategically**: Schedule messages for when your audience is most active. Use analytics to find optimal times.
</Info>

<Tip>
  **A/B test**: Send different messages to different lists to see what performs better.
</Tip>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Upload Media" icon="cloud-arrow-up" href="/guides/how-to/upload-media">
    Upload content for PPV messages
  </Card>

  <Card title="Track Earnings" icon="chart-line" href="/guides/earnings">
    Monitor PPV revenue
  </Card>
</CardGroup>
