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*
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.
mediaIds ?
arrayArray 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 ?
numberThe price to unlock the media in dollars. Used when
access_type includes ppv.subscriptionTierId ?
stringThe subscription tier ID required to access the media. Used when
access_type includes subscription.subscriptionTierName ?
stringThe name of the subscription tier required to access the media.
subscriptionTierBefore ?
numberEpoch timestamp before which the subscription tier rule is active.
subscriptionTierAfter ?
numberEpoch timestamp after which the subscription tier rule is active.
listId ?
stringThe list ID required to access the media. Used when
access_type includes list.listLabel ?
stringThe name of the list required to access the media. Required if
access_type includes list.validBefore ?
numberEpoch timestamp before which the media is accessible. Used when
access_type includes limited_time.validAfter ?
numberEpoch timestamp after which the media is accessible.
permissions ?
arrayArray 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
contentandmediaIdsin the payload. Omitaccess_typeandprice. - Paid Media (PPV): To require users to pay to unlock the media, provide
mediaIdsandpreviewIds(if needed, otherwise null), setaccess_typeto["ppv"], and specify thepricein 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
| 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 |