The Only API docs

OnlyFans & Fansly

Which surfaces support which platform, and what gets rejected.

Every connected account has a platform of either onlyfans or fansly. All three connection routes accept a platform field in the request body ("onlyfans" | "fansly", default "onlyfans").

Once connected, the account ID is returned as of_user_id regardless of platform. That same value is the {of_user_id} path parameter and the user-id header on the /api2/v2/* passthrough — the only route that reads it.

Support matrix

SurfaceOnlyFansFansly
Most CRM data routes (/accounts/…, /fans, /events, /webhooks, /automations, /exports)yesyes
Transparent passthrough (/api2/v2/*)yesno — 501
POST /accounts/{of_user_id}/payout-requestsyesno — 501
GET /accounts/{of_user_id}/campaigns/{campaign_id}/claimersyesno — 501
POST /accounts/{of_user_id}/campaigns (create)yesno — 501
PATCH /accounts/{of_user_id}/subscription-priceyesno — 501 (GET works)
GET /accounts/{of_user_id}/ppv-statsyesno — 501
The three /referrals routesyesno — 501
POST /accounts/{of_user_id}/request (raw proxy)yesno — 501
Real-time WebSocketyesno — Fansly is polling-only
POST /accounts/{of_user_id}/messages/mass (mass DM)yesno — 501

What rejection looks like

Nearly every rejection is a 501 from one shared helper, with a lowercase code plus the feature name:

{ "success": false, "code": "platform_not_supported",
  "error": "\"referrals\" is not available for fansly accounts yet.",
  "platform": "fansly", "feature": "referrals" }

Mass messaging is the one exception — it hand-rolls an uppercase code, so compare case-insensitively:

{
  "success": false,
  "code": "PLATFORM_NOT_SUPPORTED",
  "error": "mass messaging is OnlyFans-only for now"
}

Write platform-agnostic code

Prefer the normalized CRM routes. They are Fansly-aware, they project both platforms' rows to the same shape, and several of them are server-side aggregations with no platform equivalent at all:

/accounts/{of_user_id}/notifications
/accounts/{of_user_id}/balances
/accounts/{of_user_id}/chats
/accounts/{of_user_id}/purchases
/accounts/{of_user_id}/subscribers/cached
/accounts/{of_user_id}/transactions/cached
/earnings/summary
/fans

Reach for the passthrough only when you need an OnlyFans capability the CRM layer does not expose — and branch before you do. GET /accounts returns a per-account capabilities object, which is the authoritative matrix; prefer it over hard-coding this table. do.

Money scale differs between platforms

Fansly reports monetary amounts at a different scale than OnlyFans. The normalized CRM routes handle the conversion for you; raw passthrough responses do not, because they are OnlyFans' own bytes. See Earnings & transactions.

Fansly-specific helpers

GET /accounts/{of_user_id}/fansly-credentials

Returns the stored Fansly credential block for a connected account.

On this page