OnlyFans API
OnlyFansChat Messages

Send Message

Send a new message to a chat.

Idempotency. Pass an Idempotency-Key header to make retries safe. The first request with a given key is executed normally and its response is stored for 24 hours; any later request with the same key returns that stored response, plus an Idempotent-Replayed: true header, without contacting OnlyFans and without consuming credits. The replayed body is the original response with its _meta._credits block rewritten to show used: 0 and your current balance.

Keys are scoped to your team, this endpoint and the account in the URL, so the same value can be reused safely against a different account. Use a fresh, unique value (a UUID works well) for each message you send; it must be 1-255 printable ASCII characters.

  • 400 IDEMPOTENCY_KEY_INVALID — the header value is empty, too long, or contains non-ASCII characters.
  • 409 IDEMPOTENCY_CONFLICT — an earlier request with this key is still running. Retry once it finishes.
  • 422 IDEMPOTENCY_KEY_MISMATCH — this key was already used with a different request body or chat.

Responses with a 5xx status (and 408/429) are never stored, so a failed send can be retried with the same key. The header is optional: omit it and the endpoint behaves exactly as before.

POST
/api/{account}/chats/{chat_id}/messages
AuthorizationBearer <token>

Get your API Key from OnlyFansAPI Console - https://app.onlyfansapi.com/api-keys

In: header

Path Parameters

account*string

The Account ID

chat_id*string

The ID of the chat (usually a fan's OnlyFans User ID)

Header Parameters

Idempotency-Key?string

Request Body

application/json

text?string

The message text content. Required unless a media file is present.

replyToMessageId?integer

Mark this message as a reply to another (can be either your own, or the recipient's)

lockedText?boolean

Whether the text should be shown or hidden

price?number

Price for paid content in USD (0 or between 3-200). In case this is not zero, mediaFiles is required

mediaFiles?array<file[]|string>

Direct file uploads, OFAPI ofapi_media_ IDs, or OF vault IDs. Will be hidden if price is provided.

previews?array<file[]|string[]|int>

Direct file uploads, OFAPI ofapi_media_ IDs, OF vault IDs, or integer indices referencing uploaded files in mediaFiles. Will be shown if price is provided.

giphyId?string

The ID of the Giphy GIF to attach to the message. Get IDs from the Giphy listing endpoints (/giphy/trending, /giphy/search).

rfTag?string

Array of OnlyFans Creator User IDs to tag in your message

rfPartner?string

Array of OnlyFans Release Form Partners IDs to tag in your message

rfGuest?string

Array of OnlyFans Release Form Guest IDs to tag in your message

blockBannedWords?string

Screen text for OnlyFans banned words and block the send if any are found (returns a 422 listing the offending words). strict_ban blocks all tiers, risky blocks Risky + Replace/soften, replace_soften blocks Replace/soften only. Omit to disable screening.

Value in"strict_ban" | "risky" | "replace_soften"

Response Body

application/json

application/json

application/json

curl -X POST "https://app.onlyfansapi.com/api/acct_XXXXXXXXXXXXXXX/chats/123/messages" \  -H "Idempotency-Key: a1b2c3d4-5e6f-4789-a0b1-c2d3e4f5a6b7" \  -H "Content-Type: application/json" \  -d '{}'
{
  "data": {
    "responseType": "message",
    "text": "<p>Message text</p>",
    "giphyId": null,
    "lockedText": true,
    "isFree": true,
    "price": 0,
    "isMediaReady": true,
    "mediaCount": 0,
    "media": [],
    "previews": [],
    "isTip": false,
    "isReportedByMe": false,
    "isCouplePeopleMedia": false,
    "queueId": 123,
    "isMarkdownDisabled": true,
    "releaseForms": [],
    "fromUser": {
      "id": 339543013,
      "_view": "s"
    },
    "isFromQueue": false,
    "id": 123,
    "isOpened": false,
    "isNew": true,
    "createdAt": "2025-02-03T23:29:53+00:00",
    "changedAt": "2025-02-03T23:29:53+00:00",
    "cancelSeconds": 119,
    "isLiked": false,
    "canPurchase": false,
    "canPurchaseReason": "free",
    "canReport": false,
    "canBePinned": true,
    "isPinned": false
  },
  "_pagination": {
    "next_page": "https://app.onlyfansapi.com/api/acct_XXXXXXXXXXX/chats/XXXXXXXXX/messages?limit=10&id=XXXXXXXXX"
  },
  "_meta": {
    "_credits": {
      "used": 1,
      "balance": 1,
      "note": "Always"
    },
    "_cache": {
      "is_cached": false,
      "note": "Cache disabled for this endpoint"
    },
    "_rate_limits": {
      "limit_minute": 1000,
      "limit_day": 50000,
      "remaining_minute": 999,
      "remaining_day": 49999
    }
  }
}
{
  "error": "IDEMPOTENCY_CONFLICT",
  "message": "A request with this Idempotency-Key is already in progress.",
  "description": "An earlier request using this Idempotency-Key has not finished yet. Wait for it to complete, then retry with the same key to receive the original response."
}
{
  "error": "VALIDATION_ERROR",
  "message": "The text field is required.",
  "description": "The request parameters failed validation.",
  "errors": {
    "text": [
      "The text field is required."
    ]
  },
  "_meta": {
    "_credits": {
      "used": 0,
      "balance": 9554,
      "note": "Always"
    },
    "_cache": {
      "is_cached": false,
      "note": "Cache disabled for this endpoint"
    },
    "_rate_limits": {
      "limit_minute": 1000,
      "limit_day": 50000,
      "remaining_minute": 999,
      "remaining_day": 49999
    }
  }
}