Chat messages
Send Message
Send a message to a specific chat.
https://v1.apifansly.com
POST
/api/fansly/{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",
"mediaId": "YOUR_MEDIA_ID",
"access_type": "ppv",
"price": 4
}'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",
mediaId: "YOUR_MEDIA_ID",
access_type: "ppv",
price: 4
})
})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",
"mediaId": "YOUR_MEDIA_ID",
"access_type": "ppv",
"price": 4
}
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\", \"mediaId\": \"YOUR_MEDIA_ID\", \"access_type\": \"ppv\", \"price\": 4}";
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\", \"mediaId\": \"YOUR_MEDIA_ID\", \"access_type\": \"ppv\", \"price\": 4}";
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", "mediaId": "YOUR_MEDIA_ID", "access_type": "ppv", "price": 4}`)
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*
stringThe unique identifier for the connected account.
chat_id*
stringThe unique identifier for the chat.
Request Body Parameters
content*
stringThe text content of the message to send.
mediaId ?
stringThe ID of the media to attach. Obtainable from Vault Media or Upload Media endpoint. If you want to send the media for free, do not include `access_type` and `price`.
access_type ?
stringSet to `"ppv"` if you want to charge for viewing the attached media. Only `"ppv"` is supported currently, but this will be expanded to cover more types in the future.
price ?
numberThe price for the PPV message in dollars (e.g., `1` for $1.00). Minimum price is $1, Maximum is $500. Required if `access_type` is set to `"ppv"`.
Sending Media & PPV
- Free Media: To attach media for free, provide only
contentandmediaIdin the payload. Omitaccess_typeandprice. - Paid Media (PPV): To require users to pay to unlock the media, provide
mediaId, setaccess_typeto"ppv", and specify thepricein dollars (not cents) min 1$ - max 500$.
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
| Field | Type | Description |
|---|---|---|
statusCode | number | The HTTP status code of the response (201) |
message | string | A human-readable message about the result |
data | object | The main response payload |
├─ status_code | number | The internal status code of the Fansly operation |
└─ data | object | Nested data container |
└─ response | object | The details of the sent message |
├─ id | string | Unique identifier for the message |
├─ type | number | The type of message (1 for text) |
├─ content | string | The text content of the message |
├─ senderId | string | The ID of the user who sent the message |
├─ groupId | string | The ID of the chat group |
├─ createdAt | number | Unix timestamp of the message creation |
├─ attachments | array | A list of attached media or metadata |
├─ contentType | number | The type of the attachment (e.g., 1 for media) |
└─ contentId | string | The ID of the attached content |
└─ interactions | array | Delivery and read status for participants |
├─ groupId | string | The ID of the group for this interaction |
├─ userId | string | The ID of the interacting user |
├─ readAt | number | Unix timestamp of when read |
└─ deliveredAt | number | Unix timestamp of when delivered |
timestamp | string | The ISO 8601 timestamp of when the response was generated |