Fansly API LogoFansly API
Chat messages

Send Message

Send a message to a specific chat.

https://v1.apifansly.com/api/fansly
POST
/{account_id}/chats/{chat_id}/messages

The chat_id parameter corresponds to the groupId returned by the List Chats endpoint.

Get Started

All requests to the Fansly API require an API Key. See the Authentication page for details.

Request Body

curl -X POST "https://v1.apifansly.com/api/fansly/{account_id}/chats/{chat_id}/messages" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Message content here",
    "mediaIds": ["mediaId": "MEDIA_ID"]
  }'
fetch("https://v1.apifansly.com/api/fansly/{account_id}/chats/{chat_id}/messages", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    content: "Message content here",
    mediaIds: [{"mediaId": "YOUR_MEDIA_ID"}]
  })
})
import requests

url = "https://v1.apifansly.com/api/fansly/{account_id}/chats/{chat_id}/messages"
headers = {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}
payload = {
    "content": "Message content here",
    "mediaIds": [{"mediaId": "YOUR_MEDIA_ID"}]
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
String json = "{\"content\": \"Message content here\", \"mediaIds\": [{\"mediaId\": \"YOUR_MEDIA_ID\"}]}";

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://v1.apifansly.com/api/fansly/{account_id}/chats/{chat_id}/messages"))
        .header("x-api-key", "YOUR_API_KEY")
        .header("Content-Type", "application/json")
        .POST(BodyPublishers.ofString(json))
        .build();

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println)
        .join();
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var json = "{\"content\": \"Message content here\", \"mediaIds\": [{\"mediaId\": \"YOUR_MEDIA_ID\"}]}";
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://v1.apifansly.com/api/fansly/{account_id}/chats/{chat_id}/messages", content);
var responseString = await response.Content.ReadAsStringAsync();

Console.WriteLine(responseString);
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    url := "https://v1.apifansly.com/api/fansly/{account_id}/chats/{chat_id}/messages"
    payload := []byte(`{"content": "Message content here", "mediaIds": [{"mediaId": "YOUR_MEDIA_ID"}]}`)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
    req.Header.Set("x-api-key", "YOUR_API_KEY")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

Path Parameters

account_id*
string
The unique identifier for the connected account.
chat_id*
string
The unique identifier for the chat.

Request Body Parameters

content*
string
The text content of the message to send.
mediaIds ?
array
Array of uploaded media IDs, or objects in the form {mediaId: ... and previewId (if needed, otherwise null)}, to attach to the message.

Media Permissions

Configure access rules for media attached to the message. Supports PPV pricing, subscription tiers, follower-only access, list-based restrictions, and time-limited availability. Multiple access types can be combined to create custom media access requirements.

access_type ?
string | string[]
Access rule(s) for the attached media. Accepts a single value or an array. One of: ppv, subscription, follow, list, limited_time.
price ?
number
The price to unlock the media in dollars. Used when access_type includes ppv.
subscriptionTierId ?
string
The subscription tier ID required to access the media. Used when access_type includes subscription.
subscriptionTierName ?
string
The name of the subscription tier required to access the media.
subscriptionTierBefore ?
number
Epoch timestamp before which the subscription tier rule is active.
subscriptionTierAfter ?
number
Epoch timestamp after which the subscription tier rule is active.
listId ?
string
The list ID required to access the media. Used when access_type includes list.
listLabel ?
string
The name of the list required to access the media. Required if access_type includes list.
validBefore ?
number
Epoch timestamp before which the media is accessible. Used when access_type includes limited_time.
validAfter ?
number
Epoch timestamp after which the media is accessible.
permissions ?
array
Array of custom permission rules for advanced access configurations. Each object defines its own rule using the same fields as above (access_type, price, subscriptionTierId, etc.). Rules are OR'd together. The media unlocks if any single rule's conditions are satisfied.

Sending Media & PPV

  • Free Media: To attach media for free, provide only content and mediaIds in the payload. Omit access_type and price.
  • Paid Media (PPV): To require users to pay to unlock the media, provide mediaIds and previewIds (if needed, otherwise null), set access_type to ["ppv"], and specify the price in dollars (not cents) min 1$ - max 500$.
  • follow same rule for other access types from Media Permissions section.

Response

{
    "statusCode": 201,
    "message": "Success",
    "data": {
        "status_code": 200,
        "data": {
            "success": true,
            "response": {
                "type": 1,
                "attachments": [
                    {
                        "contentType": 1,
                        "contentId": "CONTENT_ID"
                    }
                ],
                "content": "Message content here",
                "groupId": "GROUP_ID",
                "senderId": "SENDER_ID",
                "inReplyTo": "",
                "interactions": [
                    {
                        "groupId": "GROUP_ID",
                        "userId": "USER_ID",
                        "readAt": 0,
                        "deliveredAt": 0
                    }
                ],
                "id": "MESSAGE_ID",
                "createdAt": 1774754024.426
            }
        }
    },
    "timestamp": "2026-03-29T03:13:45.261Z"
}

Response Body

FieldTypeDescription
statusCodenumberThe HTTP status code of the response (201)
messagestringA human-readable message about the result
dataobjectThe main response payload
├─ status_codenumberThe internal status code of the Fansly operation
└─ dataobjectNested data container
└─ responseobjectThe details of the sent message
├─ idstringUnique identifier for the message
├─ typenumberThe type of message (1 for text)
├─ contentstringThe text content of the message
├─ senderIdstringThe ID of the user who sent the message
├─ groupIdstringThe ID of the chat group
├─ createdAtnumberUnix timestamp of the message creation
├─ attachmentsarrayA list of attached media or metadata
├─ contentTypenumberThe type of the attachment (e.g., 1 for media)
└─ contentIdstringThe ID of the attached content
└─ interactionsarrayDelivery and read status for participants
├─ groupIdstringThe ID of the group for this interaction
├─ userIdstringThe ID of the interacting user
├─ readAtnumberUnix timestamp of when read
└─ deliveredAtnumberUnix timestamp of when delivered
timestampstringThe ISO 8601 timestamp of when the response was generated

On this page