> ## 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 a Message

> Step-by-step guide to send your first message via the OFAuth API

Learn how to send direct messages to fans using the OFAuth API.

## Prerequisites

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

***

## Send a Simple Text Message

<CodeGroup>
  ```javascript Node.js theme={null}
  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)
  ```

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

  response = requests.post(
      "https://api.ofauth.com/v2/access/chats/USER_ID/messages",
      headers={
          "apikey": "YOUR_API_KEY",
          "x-connection-id": "conn_abc123",
          "Content-Type": "application/json"
      },
      json={
          "text": "Hey! Thanks for subscribing 💕"
      }
  )

  message = response.json()
  print("Message sent! ID:", message["id"])
  ```

  ```bash cURL theme={null}
  curl -X POST "https://api.ofauth.com/v2/access/chats/USER_ID/messages" \
    -H "apikey: YOUR_API_KEY" \
    -H "x-connection-id: conn_abc123" \
    -H "Content-Type: application/json" \
    -d '{"text": "Hey! Thanks for subscribing 💕"}'
  ```
</CodeGroup>

<Info>
  Replace `USER_ID` with the OnlyFans user ID of the recipient. You can get user IDs from the [subscribers endpoint](/guides/fans).
</Info>

***

## Find a User to Message

First, get your subscribers to find someone to message:

```javascript theme={null}
// Get active subscribers
const response = await fetch("https://api.ofauth.com/v2/access/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, ")")
```

***

## Send Message with Media

Include images or videos in your message:

```javascript theme={null}
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
  })
})
```

<Info>
  For all accepted `mediaItems` values (vault IDs, upload references, URLs) and validation rules, see the [`mediaItems` reference](/guides/media-items).
</Info>

***

## Send a PPV (Pay-Per-View) Message

Lock content behind a paywall:

```javascript theme={null}
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 ($3 min, $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:

<Tip>
  See [Text Formatting Guide](/guides/how-to/text-formatting) for the full formatting reference.
</Tip>

```javascript theme={null}
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:

```javascript theme={null}
{
  "text": "This **won't** be bold",
  "isMarkdown": false
}
```

***

## Read Chat History

Before sending, you might want to see previous messages:

```javascript theme={null}
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:

```javascript theme={null}
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:

```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 sendWelcomeMessage() {
  // 1. Get recent subscribers
  const subsResponse = await fetch(
    "https://api.ofauth.com/v2/access/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

<Warning>
  OnlyFans has rate limits on messaging. Avoid sending too many messages in quick succession.
</Warning>

Best practices:

* Space out individual messages by at least 1-2 seconds
* For bulk messaging, use the [mass message queue](/guides/how-to/mass-message) instead
* Implement exponential backoff on 429 errors

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Mass Messaging" icon="envelopes-bulk" href="/guides/how-to/mass-message">
    Send to multiple fans at once
  </Card>

  <Card title="Upload Media" icon="cloud-arrow-up" href="/guides/how-to/upload-media">
    Upload content to include in messages
  </Card>
</CardGroup>
