OnlyFans API
and MCP server for agencies
There is no official public OnlyFans API for agencies. OnlyX is an independent one: the inbox, fans, vault, revenue and the AI chatter, through the creator accounts you have connected.
59 REST operations and a remote MCP server with 60 tools, so your own code, Claude or ChatGPT can run the agency with you.
Does OnlyFans have an API?
Not a public one. So we built one
OnlyFans does not publish an API for agencies. The OnlyX API is unofficial and independent, and it only ever acts on accounts a creator has connected to your workspace.
Creator-authorised
Accounts are signed in by the creator or her agency and connected to your workspace. The API reaches only those, and a key can be limited to the creators you choose.
Real, not simulated
There is no sandbox. A send reaches a real fan, so writes take an Idempotency-Key (sends require one) and a retry never acts twice.
Independent
OnlyX is not affiliated with, endorsed by or sponsored by OnlyFans. You use it within OnlyFans’ terms and the law.
What the OnlyFans API covers
59 operations, one OpenAPI spec
Everything below is live at https://api.onlyx.ai/v1 and described in the OpenAPI document.
inbox:readinbox:writemessages:sendfans:readfans:writestats:readmoney:readmedia:readcreators:readcreators:writeai:readai:writelinks:readlinks:writeworkspace:readInbox and messages
- GET/v1/conversationsList conversations
- GET/v1/conversations/countsCount conversations
- GET/v1/conversations/{conversationId}Get a conversation
- PUT/v1/conversations/{conversationId}/aiSwitch the AI on or off for a conversation
- POST/v1/conversations/{conversationId}/readMark a conversation read
- POST/v1/conversations/{conversationId}/releaseRelease a conversation to the AI
- POST/v1/conversations/{conversationId}/takeoverTake over a conversation
- POST/v1/conversations/{conversationId}/unreadMark a conversation unread
- GET/v1/conversations/{conversationId}/messagesList messages
- POST/v1/conversations/{conversationId}/messagesSend a message
- GET/v1/conversations/{conversationId}/messages/{messageId}Get a message
- POST/v1/conversations/{conversationId}/handoff/resolveResolve a hand-off
- GET/v1/handoffsList open hand-offs
Fans
- GET/v1/fan-listsList fan lists
- GET/v1/fansList fans
- GET/v1/fans/{fanId}Get a fan
- PATCH/v1/fans/{fanId}Update a fan
- GET/v1/fans/{fanId}/purchasesList a fan's purchases
Stats and revenue
- GET/v1/creators/{creatorId}/transactionsList a creator's transactions
- GET/v1/stats/audienceGet the audience
- GET/v1/stats/overviewGet the overview report
- GET/v1/stats/revenueGet revenue
- GET/v1/stats/todayGet today's numbers
Vault
- GET/v1/creators/{creatorId}/mediaList vault media
- GET/v1/creators/{creatorId}/media/{mediaId}/thumbnailGet a thumbnail
Creators and connection
- GET/v1/creatorsList creators
- POST/v1/creatorsAdd a creator
- GET/v1/creators/{creatorId}Get a creator
- PATCH/v1/creators/{creatorId}Update a creator
- GET/v1/creators/{creatorId}/connect-linkGet the connect link
- POST/v1/creators/{creatorId}/connect-linkCreate a connect link
- DELETE/v1/creators/{creatorId}/connect-linkRevoke the connect link
- GET/v1/creators/{creatorId}/connectionGet the connection status
AI chatter setup
- GET/v1/creators/{creatorId}/personaGet the AI persona
- PATCH/v1/creators/{creatorId}/personaUpdate the AI persona
- GET/v1/creators/{creatorId}/ai-settingsGet AI settings
- PATCH/v1/creators/{creatorId}/ai-settingsUpdate AI settings
- GET/v1/creators/{creatorId}/welcome-messageGet the welcome message
- PUT/v1/creators/{creatorId}/welcome-messageReplace the welcome message
- GET/v1/creators/{creatorId}/ai-contentGet the AI content board
- POST/v1/creators/{creatorId}/ai-content/collectionsCreate a ladder
- PATCH/v1/creators/{creatorId}/ai-content/collections/{collectionId}Update a ladder
- DELETE/v1/creators/{creatorId}/ai-content/collections/{collectionId}Delete a ladder
- PUT/v1/creators/{creatorId}/ai-content/collections/{collectionId}/orderReorder a ladder's levels
- POST/v1/creators/{creatorId}/ai-content/foldersCreate a folder
- PATCH/v1/creators/{creatorId}/ai-content/folders/{folderId}Rename a folder
- DELETE/v1/creators/{creatorId}/ai-content/folders/{folderId}Delete a folder
- POST/v1/creators/{creatorId}/ai-content/levelsCreate a level
- PATCH/v1/creators/{creatorId}/ai-content/levels/{levelId}Update a level
- DELETE/v1/creators/{creatorId}/ai-content/levels/{levelId}Delete a level
- POST/v1/creators/{creatorId}/ai-content/levels/{levelId}/mediaAdd media to a level
- PUT/v1/creators/{creatorId}/ai-content/levels/{levelId}/media/orderReorder a level's media
- DELETE/v1/creators/{creatorId}/ai-content/levels/{levelId}/media/{mediaId}Remove media from a level
Tracking links
- GET/v1/creators/{creatorId}/tracking-linksList tracking links
- POST/v1/creators/{creatorId}/tracking-linksCreate a tracking link
- GET/v1/creators/{creatorId}/tracking-links/creations/{creationId}Get a tracking link creation
- GET/v1/creators/{creatorId}/tracking-links/{linkId}Get a tracking link
- PATCH/v1/creators/{creatorId}/tracking-links/{linkId}Update a tracking link
Workspace
- GET/v1/meGet the current workspace and credential
OnlyFans MCP server
For Claude, ChatGPT, Cursor and more
One URL, https://mcp.onlyx.ai/mcp, with 60 tools and 6 ready-made prompts over Streamable HTTP. Clients that speak OAuth register themselves and ask you to sign in; the rest send an API key.
https://mcp.onlyx.ai/mcpCustomize → Connectors → Add custom connector. Name it OnlyX, paste the URL, leave Advanced settings empty, then sign in to OnlyX and approve. Works on claude.ai, Claude Desktop and the mobile apps.
https://mcp.onlyx.ai/mcpSettings → Apps & Connectors → switch on Developer mode, then create an app with this URL and OAuth sign-in. Needs ChatGPT on the web with a paid plan.
claude mcp add --transport http onlyx https://mcp.onlyx.ai/mcpThen run /mcp inside Claude Code to sign in.
{
"mcpServers": {
"onlyx": {
"url": "https://mcp.onlyx.ai/mcp"
}
}
}~/.cursor/mcp.json. Cursor registers itself with OnlyX and asks you to sign in the first time.
code --add-mcp '{"name":"onlyx","type":"http","url":"https://mcp.onlyx.ai/mcp"}'Adds OnlyX for GitHub Copilot agent mode, in every workspace. Then sign in to OnlyX when VS Code asks.
{
"mcpServers": {
"onlyx": {
"serverUrl": "https://mcp.onlyx.ai/mcp"
}
}
}mcp_config.json, opened from Cascade’s MCP settings.
gemini mcp add --transport http --scope user onlyx https://mcp.onlyx.ai/mcpThen /mcp auth onlyx inside Gemini CLI. In a settings file use httpUrl, not url.
codex mcp add onlyx --url https://mcp.onlyx.ai/mcp
codex mcp login onlyxOr set bearer_token_env_var = "ONLYX_API_KEY" in ~/.codex/config.toml to use an API key.
Three fans are waiting, biggest spender first. Drafts:
- Mike“just got home, perfect timing. how was the gym”
- Andre W.“you remembered the beach set. want the rest of it?”
- Ken H.“morning! did the interview go ok?”
Nothing is sent until you approve.
The 6 prompts
daily_briefingToday’s numbers, open hand-offs and fans waiting for a reply, with proposed actions. Read-only, nothing is sent.
reply_to_unread_fansDrafts replies for fans waiting on an answer, shows every draft for approval, then sends only what you approve.
onboard_a_creatorAdds a creator, produces the connect link she signs in with, and walks through connection and first setup.
build_ai_personaInterviews you for the persona the AI chatter uses to talk as the creator, then saves it after your approval.
build_content_ladderLooks at the vault and proposes a free opener plus priced levels for the AI to sell; builds it after your approval.
weekly_revenue_reportRevenue for the last 7 days against the week before, by type, day, AI against team, and traffic source. Read-only.
All 60 tools
list_conversationsget_conversation_countsget_conversationlist_messagesget_messagesend_messagemark_conversation_readmark_conversation_unreadtake_over_conversationrelease_conversationset_conversation_ailist_handoffsresolve_handofflist_fansget_fanlist_fan_purchasesupdate_fanlist_fan_listslist_vault_mediaview_vault_mediaget_today_statsget_revenueget_audienceget_overviewlist_transactionsget_workspacelist_creatorsget_creatoradd_creatorupdate_creatorget_connection_statuscreate_connect_linkget_connect_linkrevoke_connect_linkget_personaupdate_personaget_ai_contentcreate_content_folderupdate_content_folderdelete_content_foldercreate_content_ladderupdate_content_ladderdelete_content_ladderreorder_content_levelscreate_content_levelupdate_content_leveldelete_content_leveladd_media_to_levelremove_media_from_levelreorder_level_mediaget_ai_settingsupdate_ai_settingsget_welcome_messageupdate_welcome_messagelist_tracking_linksget_tracking_linkupdate_tracking_linkcreate_tracking_linkget_tracking_link_creationsearch_docs OnlyFans chat and messages API
Text, media and PPV, one fan at a time
- Text up to 4,000 characters, with free media or none
- Paid messages: up to 20 locked media at $3 to $5,000, plus free previews as the teaser
- An Idempotency-Key is required on every send, so a retry returns the first answer
- Take over a conversation from the AI chatter, then release it back
- Read and resolve hand-offs: the threads the AI passed to a person
curl -X POST "https://api.onlyx.ai/v1/conversations/cnv_3d9e7b1a5c2f4e8d6a0b/messages" \
-H "Authorization: Bearer $ONLYX_API_KEY" \
-H "Idempotency-Key: 5f1c2a9e-7b1d-4c0e-9a4f-2d8e6b3c1a70" \
-H "Content-Type: application/json" \
-d '{
"text": "Made this one just for you",
"previewMediaIds": ["4012345678"],
"mediaIds": ["4012345679"],
"priceCents": 1500
}'Answers 202 Accepted. Send the same Idempotency-Key again and you get the first answer back, not a second message.
import os, uuid
import requests
r = requests.post(
"https://api.onlyx.ai/v1/conversations/cnv_3d9e7b1a5c2f4e8d6a0b/messages",
headers={
"Authorization": f"Bearer {os.environ['ONLYX_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()), # keep it for retries
},
json={
"text": "Made this one just for you",
"previewMediaIds": ["4012345678"],
"mediaIds": ["4012345679"],
"priceCents": 1500,
},
)
print(r.status_code) # 202Reuse the same key when you retry, so a timeout never becomes a double send.
Fans, earnings, vault and links
The rest of the agency, in JSON
OnlyFans fans API
Every fan across your creators: segment, spend, subscription and last activity, their purchase history, and the custom name and notes your team keeps.
GET /v1/fansEarnings and stats API
Today’s numbers, revenue for a date window (net and gross, with paid-message sales split between the AI and your team), the audience, the overview report and each creator’s transaction ledger.
GET /v1/stats/revenueVault media
List what is in a creator’s vault and fetch thumbnails, so a script or an assistant can pick the media for a message or a ladder.
GET /v1/creators/{creatorId}/mediaTracking links API
Create OnlyFans tracking links per creator, record what a campaign cost, and read back its clicks, subscribers, earnings and ROI.
POST /v1/creators/{creatorId}/tracking-linksAI chatter setup
The persona the AI chatter writes as, its settings, the welcome message and the content ladders it sells from, all editable from code.
PATCH /v1/creators/{creatorId}/personaThe full reference
Every parameter, response and error, with the scope each call needs.
Open the docs Quickstart
cURL, Python or JavaScript
- 1Create a key
In OnlyX, Settings → API & MCP. Owners and admins can create one. It is shown once.
- 2Check who you are
GET /v1/mereturns the workspace and the scopes the key carries. - 3Read the inbox
List the fans waiting on a reply, then page through with
nextCursor.
# Fans waiting on a reply, biggest spenders first
curl "https://api.onlyx.ai/v1/conversations?unread=true&sort=spend&limit=20" \
-H "Authorization: Bearer $ONLYX_API_KEY"import os
import requests
API = "https://api.onlyx.ai/v1"
headers = {"Authorization": f"Bearer {os.environ['ONLYX_API_KEY']}"}
# Fans waiting on a reply, biggest spenders first
page = requests.get(
f"{API}/conversations",
params={"unread": "true", "sort": "spend", "limit": 20},
headers=headers,
).json()
for c in page["data"]:
print(c["fan"]["displayName"], c["unreadCount"])const API = 'https://api.onlyx.ai/v1'
// Fans waiting on a reply, biggest spenders first
const res = await fetch(`${API}/conversations?unread=true&sort=spend&limit=20`, {
headers: { Authorization: `Bearer ${process.env.ONLYX_API_KEY}` }
})
const { data, hasMore, nextCursor } = await res.json()
for (const c of data) {
console.log(c.fan.displayName, c.unreadCount)
} API keys, OAuth and scopes
Access as narrow as you want it
OnlyFans API keys
onx_sk_…as a Bearer token or an X-API-Key header- Limited to the creators you choose
- Expire after 30, 90 or 365 days, or never
- Stored hashed and shown once; up to 25 active per workspace
OAuth 2.1
- PKCE (S256) and dynamic client registration, no client secret to paste
- An owner or admin approves each app on a consent screen
- Access tokens last an hour, refresh tokens 60 days
- Disconnect an app at any time
15 scopes
Pick them one by one, or start from Read only or Full access. Scopes that change something are marked.
workspace:readcreators:readcreators:writewriteinbox:readinbox:writewritemessages:sendwritefans:readfans:writewritemedia:readstats:readmoney:readai:readai:writewritelinks:readlinks:writewriteRate limits and conventions
- Default limit
- 120 requests a minute per key or token
- Sending
- 30 sends a minute per key or token, 300 an hour per creator
- Over the limit
- 429 with Retry-After, and X-RateLimit-* on every response
- Format
- JSON, camelCase, ISO-8601 UTC timestamps
- Money
- Integer US cents, in fields that end in Cents
- Lists
- Cursor pages: data, hasMore, nextCursor
- Errors
- code, message and requestId, plus X-Request-Id
Built for OnlyFans agencies
What teams wire it into
A morning briefing in Claude
Run the daily_briefing prompt: today’s numbers, open hand-offs and the fans still waiting, with proposed actions. Read-only.
Your own dashboard
Pull revenue, audience and transactions per creator into a sheet or your BI tool, on your own schedule.
Replies from your own tools
Take over a thread, send from your system, and release it back to the AI chatter when you are done.
Creator onboarding by script
Add a creator, create her connect link, and poll the connection until she has signed in.
AI setup from code
Write the persona, the welcome message and the content ladders once, and roll them out across creators.
Promo ROI per link
A tracking link for every promo, its cost recorded against it, and clicks, subscribers, earnings and ROI read back into your reporting.
What it does not do yet
Listed up front
- Mass messages. Every send goes to one fan.
- Scheduled messages
- Unsending a message
- Uploading to the vault
- Posts and stories
- Blocking fans or editing fan lists
- Payouts
- Webhooks
- SDKs
- A sandbox. Every call acts on real accounts.
No separate charge for API or MCP access today
It comes with every OnlyX workspace. The CRM is free, and OnlyX takes 10% only of the sales its AI chatter closes.
OnlyFans API questions
There is no official public OnlyFans API for agencies. OnlyX is an independent, unofficial API: it is not affiliated with or endorsed by OnlyFans, and it works through each creator’s own connected account.
Yes. https://mcp.onlyx.ai/mcp is a remote MCP server over Streamable HTTP with 60 tools and 6 prompts. Clients sign in with OAuth, or send an API key.
Add https://mcp.onlyx.ai/mcp as a custom connector in Claude, or as a Developer mode app in ChatGPT, then sign in to OnlyX and approve. It works the same way in Claude Code, Cursor, VS Code, Windsurf, Gemini CLI and Codex.
Yes. One call sends one fan a message with up to 20 locked media at a price from $3 to $5,000, plus free previews. An Idempotency-Key header is required, so a retry never sends twice.
Not yet. Every send goes to one fan, and there is no scheduling in the API today.
There is no separate charge for API or MCP access today; it comes with every OnlyX workspace. The CRM is free, and OnlyX takes 10% only of the sales its AI chatter closes.
120 requests a minute per key or token. Sends are also capped at 30 a minute per key and 300 an hour per creator. Over a limit you get a 429 with Retry-After.
With a workspace API key (onx_sk_…) sent as a Bearer token or an X-API-Key header, or with OAuth 2.1: PKCE and dynamic client registration, which is how AI clients connect.
Yes. A key can be limited to the creators you choose, to any of the 15 scopes, and to 30, 90 or 365 days. Owners and admins can revoke it at any time.
Not yet. Any HTTP client works, and the full OpenAPI description is at https://api.onlyx.ai/v1/openapi.json.
Not yet. To react to new messages, poll the conversation list with unread=true and follow the cursor.
No. Every call acts on real connected accounts, and a send reaches a real fan. While you build, use a Read only key.
OnlyX is an independent product. It is not an official OnlyFans API and is not affiliated with, endorsed by or sponsored by OnlyFans. OnlyFans is a trademark of its respective owner, used here only to describe compatibility. OnlyX acts only on accounts a creator has connected and authorised; you are responsible for using it in line with OnlyFans’ terms and the law. Questions: developers@onlyx.ai.