Fansly API LogoFansly API
Guides

Composing Messages

Learn how to send direct messages, attach media, and set up paywalls (PPV) in chats using the Fansly API.

Sending direct messages to fans is one of the most effective ways for creators to engage, share content, and earn revenue on Fansly. Messages can consist of simple text, attached media, or paid media locked behind a Pay-Per-View (PPV) paywall.

This guide walks you through the step-by-step process of preparing your assets and sending messages in chats using the Send Message endpoint.

The Workflow Overview

To send a message, you will follow these general steps:

Identify the Target Chat

Obtain the correct chat_id (this corresponds to the groupId of the active conversation).

Obtain Media IDs (If attaching images or videos)

Upload new files or retrieve existing media from the creator's vault to get their unique identifiers.

Choose Message Type & Paywall Settings

Determine if the message will include free media attachments or paid media locked behind a PPV price.

Send the Message

Post the final payload to the target chat endpoint.


Step 1: Identify the Target Chat

Before sending a message, you need the ID of the chat group (chat_id).

You can retrieve the list of active chat conversations for the account by calling the List Chats endpoint:

GET /api/fansly/{account_id}/chats

From the response, grab the groupId parameter of the conversation you want to send the message to. This groupId will be used as the {chat_id} path parameter in the messaging endpoint.


Step 2: Handling Media Attachments

If you are sending a text-only message, you can skip this step. If your message contains images or videos, you must supply an array of mediaIds. You can obtain these in one of two ways:

Scenario A: Uploading New Media

If you want to send media that is not yet on Fansly, use the Upload Media endpoints:

  1. Initiate the Upload: Make a POST request to the Initiate Upload endpoint with the file binary:

    POST /api/fansly/{accountId}/media/upload

    This returns a jobId identifying the queued background upload job.

  2. Poll the Job Status: Periodically call the Track Upload Status endpoint using your jobId:

    GET /api/fansly/media/upload/{jobId}/status
  3. Grab the Media ID: Once the response state changes to "completed", retrieve the unique ID from mediaId (e.g., 123456789). Use this ID in your message payload.

For a complete reference on this flow, visit the Upload Media documentation.

Scenario B: Selecting from Vault Albums

If the creator wants to reuse existing content, you can retrieve media from their Vault:

  1. List Vault Albums: Fetch the creator's albums to find the right container:

    GET /api/fansly/vault/albums
  2. Fetch Album Media: Retrieve all media files inside a selected album:

    GET /api/fansly/vault/albums/{albumId}/media
  3. Get the Media ID: Copy the mediaId of the target media item from the list response to include in your message.


Step 3: Configure Message Settings & Paywalls

When attaching media, you can decide whether to send it for free or locked behind a paywall:

1. Free Media Messages

To attach media that is free for the recipient to view, simply include content and the mediaIds array. Do not include the access_type or price parameters in the payload.

2. Pay-Per-View (PPV) Messages

To require the recipient to pay to unlock the media:

  • Include the mediaIds of the files you are locking.
  • Set access_type to ["ppv"].
  • Set price to a whole or decimal number in dollars (e.g., 10 for $10.00).

PPV Limits

The minimum price for PPV messages is $1.00, and the maximum is $500.00. Setting a price outside this range will result in an API error.


Step 4: Send the Message

Send a POST request to the message endpoint:

POST /api/fansly/{account_id}/chats/{chat_id}/messages

Example Request Payload

Here is a full example of a Pay-Per-View message containing locked media:

{
  "content": "Check out this exclusive video! Only $15.00 to unlock! 😉",
  "mediaIds": ["media_123456789"],
  "access_type": ["ppv"],
  "price": 15
}

Example Response

{
  "statusCode": 201,
  "message": "Success",
  "data": {
    "success": true,
    "response": {
      "id": "msg_987654321",
      "type": 1,
      "content": "Check out this exclusive video! Only $15.00 to unlock! 😉",
      "groupId": "chat_group_12345",
      "senderId": "sender_acc_67890",
      "attachments": [
        {
          "contentType": 1,
          "contentId": "media_123456789"
        }
      ],
      "createdAt": 1774754024.426,
      "interactions": [
        {
          "groupId": "chat_group_12345",
          "userId": "recipient_acc_54321",
          "readAt": 0,
          "deliveredAt": 0
        }
      ]
    }
  },
  "timestamp": "2026-06-05T20:10:00.000Z"
}

On this page