Fansly API documentation
Fansly API documentation for BetterFans Link: which routes and writes work on a linked Fansly account, API keys, linking, test mode and errors.
Product page: Fansly API
Fansly publishes no public developer API, API keys or documentation. BetterFans Link is independent of Fansly and works only with Fansly accounts linked to your workspace. For those accounts it gives you documented routes, API keys, account and action webhooks and an MCP server. The routes and objects are the same ones OnlyFans accounts use. This page covers what works on a Fansly account and where it differs from OnlyFans.
What works on a Fansly account
This table lists every route an API key can call and whether it works for a Fansly account. A route marked No returns 400 not_supported_on_platform for a Fansly account. Every response for one account names its platform in meta.platform.
| Route | Method and path | Fansly | Notes |
|---|---|---|---|
| Who am I | GET /v1/me | Yes | |
| List accounts | GET /v1/accounts | Yes | Add platform=fansly or platform=onlyfans to list one platform. |
| Create link | POST /v1/links | Yes | Set platform, or leave it out and the creator picks. |
| Get link | GET /v1/links/{linkId} | Yes | |
| Get account | GET /v1/accounts/{accountId} | Yes | |
| List fans | GET /v1/accounts/{accountId}/fans | Yes | |
| Get fan | GET /v1/accounts/{accountId}/fans/{fanId} | Yes | fresh=true reads the fan live on either platform. |
| Fan lists | GET /v1/accounts/{accountId}/lists | Yes | |
| List chats | GET /v1/accounts/{accountId}/chats | Yes | |
| List messages | GET /v1/accounts/{accountId}/chats/{fanId}/messages | Yes | On Fansly, fresh=true works for a chat the account already has. |
| Search messages | GET /v1/accounts/{accountId}/messages/search | Yes | |
| Revenue summary | GET /v1/accounts/{accountId}/revenue | Yes | |
| List transactions | GET /v1/accounts/{accountId}/transactions | Yes | |
| Mass messages | GET /v1/accounts/{accountId}/mass-messages | No, OnlyFans only | |
| Top content | GET /v1/accounts/{accountId}/posts | Yes | Tips per post are set on Fansly and null on OnlyFans. |
| Tracking links | GET /v1/accounts/{accountId}/links | Yes | url is null on Fansly, which does not say the address fans open. |
| Online fans | GET /v1/accounts/{accountId}/online-fans | No, OnlyFans only | |
| Vault | GET /v1/accounts/{accountId}/vault | Yes | |
| Call OnlyFans | GET /v1/accounts/{accountId}/onlyfans/{path} | No, OnlyFans only | |
| Call Fansly | GET /v1/accounts/{accountId}/fansly/{path} | Yes | |
| Create action | POST /v1/accounts/{accountId}/actions | Yes | Fansly takes send_message and unsend_message. |
| Get action | GET /v1/actions/{actionId} | Yes | |
| List actions | GET /v1/actions | Yes |
An account id is the creator's Fansly user id, and a fan id is the fan's Fansly user id. Fansly ids are too large for a JavaScript number to hold exactly, so keep every id as a string.
API keys for Fansly
Since Fansly issues no API keys, you call these routes with a BetterFans Link key. Owners, admins and developers create keys in the dashboard under Developers, then API keys. A bfl_test_ key reads the sandbox creators, and a bfl_live_ key reads the accounts linked to your workspace. One key works for OnlyFans and Fansly accounts alike. See keys and scopes.
curl "https://betterfans.link/v1/accounts?platform=fansly" \
-H "Authorization: Bearer $BFL_KEY"Link a Fansly account
Creators can link their own Fansly accounts on a page BetterFans Link hosts. Create the link with Create link and platform set to fansly, then send its url to the creator. The link works for 24 hours.
curl -X POST "https://betterfans.link/v1/links" \
-H "Authorization: Bearer $BFL_KEY" \
-H "Content-Type: application/json" \
-d '{ "note": "Rae Vale", "platform": "fansly" }'On that page the creator signs in with their Fansly username or email and password. If Fansly asks for a code, they type the one Fansly sent by email or the one from their authenticator app. Fansly has no selfie or human check.
- A Fansly account can be connected in one place at a time. If it is already connected to another workspace, the link fails with
account_in_use. Remove it there first, then send a new link. - When the account connects,
account.connectedfires and the account showssyncingfor up to 30 minutes while its history fills in. - A Fansly account uses five statuses:
healthy,syncing,awaiting_2fa,needs_relinkanddisconnected. It is neverawaiting_selfieorrestricted. See account status. - Removing the account from your workspace stops its sync and keeps the synced history. BetterFans Link does not sign the creator out at Fansly.
Link a creator covers following a link, failures and relinking.
Writes on a Fansly account
A Fansly account takes two action types, send_message and unsend_message. Create them with Create action and a key with the write scope, once writes are switched on for the account. Over MCP, the send_message and unsend_message tools create the same actions.
send_messagesends a fan a free message in the chat the account already has with that fan. It attaches free vault media only. Leave outpriceCents, since a price above 0 returns400invalid_parameter.unsend_messagetakes back a message the account sent.
If the account has no chat with the fan yet, or a media item is not free, nothing is sent and the action ends failed with the reason in error.
| Write | Action type | Fansly | Notes |
|---|---|---|---|
| Send message | send_message | Yes | On Fansly it is free, goes to a chat the account already has and attaches free vault media only. |
| Send mass message | send_mass_message | No, OnlyFans only | |
| Unsend message | unsend_message | Yes | On OnlyFans it can take back every copy of a mass message. |
| Add fan to list | add_fan_to_list | No, OnlyFans only | |
| Remove fan from list | remove_fan_from_list | No, OnlyFans only |
AI clients that sign in with OAuth wait for your team to approve each write. See writes and approvals for how an action runs.
What is OnlyFans only
Mass messages, paid messages, online fans and fan list changes work on OnlyFans only. The two tables above mark each route and action type.
- The Mass messages, Online fans and Call OnlyFans routes return
400not_supported_on_platformfor a Fansly account. - The
send_mass_message,add_fan_to_listandremove_fan_from_listaction types return the same error when you create one for a Fansly account, witherror.paramset totype. No action is created. - A paid message is a
send_messagewithpriceCentsabove 0. On a Fansly account that returns400invalid_parameterinstead.
Sending the same request again fails the same way, so check the account's platform with List accounts before you call.
How fresh Fansly data is
A Fansly account syncs about every 30 minutes, and reads come from that synced copy by default. meta.asOf on each response says when the data was last synced.
Two routes read live from Fansly with fresh=true:
- List messages, for a chat the account already has with that fan.
- Get fan, which returns the fan's profile.
Every other Fansly read comes from synced data, except Call Fansly, which always reads live. A live read is slower and calls Fansly with the creator's session, so use it for the one answer that must be current. See synced and live reads.
Fansly accounts send the account.connected, account.status_changed, account.removed and link.failed webhook events, and the action events. They do not send message.received, transaction.created or subscriber.new, so read new messages, sales and subscribers for a Fansly account from the API. See platforms in the event reference.
Test mode with Sloane
Test mode has one Fansly sandbox creator, Sloane, next to Ivy, Juniper and Wren on OnlyFans. Every workspace sees the same four, and you do not link them. With a bfl_test_ key, GET /v1/accounts?platform=fansly lists Sloane.
Every account route except Call OnlyFans and Call Fansly works against Sloane, with the same Fansly rules as a linked account. Mass messages, Online fans and the action types that are OnlyFans only return not_supported_on_platform for her, as they do for a linked Fansly account. Responses have meta.source set to sandbox.
A test action never calls Fansly, and its result is only {"simulated": true}. See test mode.
Reads the routes do not cover
Call Fansly runs a read-only Fansly API GET for a linked Fansly account, with the account's session. For example, GET /v1/accounts/{accountId}/fansly/account/me reads Fansly's account/me, and data holds the response part of Fansly's answer.
- It always reads live, so
meta.sourceislive. - Only
GETworks. To change anything on Fansly, create an action. - It needs a live key. With a test key it returns
404resource_not_found. - Over MCP,
search_apianddescribe_endpointhelp find a path, andcall_apireads it.
Fansly errors
These are the errors to plan for on a Fansly account. The first three come from live reads, which can fail where a synced read would not.
| Code | Status | When | What to do |
|---|---|---|---|
fansly_error | 502 | Fansly answered a live read with an error. | Retry after a short wait. If it keeps failing, read the account with GET /v1/accounts/{accountId}, since its status may have changed. |
fansly_timeout | 502 | Fansly did not answer in time. | Retry later, or read without fresh=true to get synced data. |
account_unavailable | 409 | The account's status stops live calls. error.accountStatus holds the status. | Read without fresh=true for the synced copy. Do not retry in a loop. See account status. |
not_supported_on_platform | 400 | The route or action type works on OnlyFans only. | See what is OnlyFans only. |
OnlyFans is a registered trademark of Fenix International Limited. Fansly is a trademark of its owner. BetterFans Link is not affiliated with, sponsored by, or endorsed by either.