OnlyFans API

Endpoint Data Sources

Where the data on each OFAPI endpoint comes from — OnlyFans, OFAPI's own database, or a mix of both.

We classify every endpoint as one of three types:

Hybrid

We make a live request to OnlyFans and then enriches the response with fields from the our database (timestamps, tags, computed classifications, etc.).

Computed

We never call OnlyFans during the request. The response is built entirely from data we have stored, synced, or calculated.

Live passthrough

Anything not listed as Hybrid or Computed. The response is straight from OnlyFans, with no enrichment.

Quick answers to common questions

  • GET /{account}/statistics/overviewLive passthrough. The numbers come straight from OnlyFans.
  • GET /{account}/fans/activeHybrid. OnlyFans response plus a lastReplyAt timestamp on each fan, sourced from the OFAPI database.
  • GET /{account}/transactionsHybrid. OnlyFans response plus a computed type field (subs, tips, post, chat_messages, stream).

Hybrid endpoints

These endpoints call OnlyFans live and then enrich the response with extra fields from the OFAPI database. The "Enriched with" column lists exactly what OFAPI adds on top of the OnlyFans payload.

HTTPPathEnriched by OFAPI
GET/{account}/chatslastReplyAt per chat
GET/{account}/chats/{chat_id}/messageslastReplyAt per participant
GET/{account}/fans/alllastReplyAt per fan
GET/{account}/fans/activelastReplyAt per fan
GET/{account}/fans/expiredlastReplyAt per fan
GET/{account}/fans/latestlastReplyAt per fan
GET/{account}/fans/toplastReplyAt per fan
GET/{account}/users/{username}lastReplyAt (if the user is a fan)
GET/{account}/transactionsComputed type (subs / tips / post / chat_messages / stream), derived from the OF description
GET/{account}/tracking-linksTags, cached revenue & spender counts, full campaign URL prefixed with the creator's profile URL
GET/{account}/trial-linksTags, cached revenue & spender counts, full campaign URL
GET/{account}/engagement/messages/top-messageEngagement stats joined onto the message metadata

Computed endpoints

These endpoints never hit OnlyFans during the request. The response is built entirely from data OFAPI has stored, synced, or calculated.

HTTPPathNotes
GET/smart-linksList smart links
POST/smart-linksCreate a smart link
GET/smart-links/{smart_link_id}Fetch a single smart link
DELETE/smart-links/{smart_link_id}Delete a smart link
GET/smart-links/{smart_link_id}/statsClicks, subs, revenue, spenders aggregated from OFAPI tables
GET/smart-links/{smart_link_id}/cohort-arpsARPS by acquisition cohort
GET/smart-links/{smart_link_id}/fansAttributed fans with aggregate metrics
GET/smart-links/{smart_link_id}/spendersFans where spend > 0
GET/smart-links/{smart_link_id}/clicksRaw click rows
GET/smart-links/{smart_link_id}/conversionsRaw conversion rows

Explicitly free — these never call OnlyFans.

HTTPPathNotes
GET/{account}/stored/tracking-linksCached tracking links
GET/{account}/stored/trial-linksCached free trial links
GET/{account}/stored/shared-tracking-linksCached shared tracking links
GET/{account}/stored/shared-trial-linksCached shared free trial links

Webhooks

HTTPPathNotes
GET/{account}/webhooksList webhooks
POST/{account}/webhooksCreate a webhook
GET/{account}/webhooks/{webhook_id}Fetch a single webhook
PUT/{account}/webhooks/{webhook_id}Update a webhook
DELETE/{account}/webhooks/{webhook_id}Delete a webhook
GET/{account}/webhooks/eventsEnum of available event types
GET/{account}/webhooks/{webhookEventType}/example-payloadStatic payload generator

Data exports

HTTPPathNotes
GET/data-exportsList data exports
POST/data-exportsCreate a data export
GET/data-exports/{data_export_id}Fetch a single data export
POST/data-exports/{data_export_id}/startStart a data export
DELETE/data-exports/{data_export_id}Delete a data export
POST/data-exports/{data_export_id}/retryRetry a data export

Tags live entirely in the OFAPI database — none of these endpoints touch OnlyFans.

HTTPPathNotes
GET/link-tagsList every tag in your org
GET/{account}/tracking-links/{tracking_link_id}/tagsList tags on a tracking link
POST/{account}/tracking-links/{tracking_link_id}/tagsAdd tags to a tracking link
DELETE/{account}/tracking-links/{tracking_link_id}/tagsRemove tags from a tracking link
GET/{account}/trial-links/{trial_link_id}/tagsList tags on a free trial link
POST/{account}/trial-links/{trial_link_id}/tagsAdd tags to a free trial link
DELETE/{account}/trial-links/{trial_link_id}/tagsRemove tags from a free trial link
GET/{account}/shared-tracking-links/{shared_tracking_link_id}/tagsList tags on a shared tracking link
POST/{account}/shared-tracking-links/{shared_tracking_link_id}/tagsAdd tags to a shared tracking link
DELETE/{account}/shared-tracking-links/{shared_tracking_link_id}/tagsRemove tags from a shared tracking link
GET/{account}/shared-trial-links/{shared_trial_link_id}/tagsList tags on a shared free trial link
POST/{account}/shared-trial-links/{shared_trial_link_id}/tagsAdd tags to a shared free trial link
DELETE/{account}/shared-trial-links/{shared_trial_link_id}/tagsRemove tags from a shared free trial link

Auth & accounts

The request itself only reads or writes OFAPI rows; the actual OnlyFans login runs asynchronously in a queued job.

HTTPPathNotes
GET/whoamiIdentify the current API key
GET/accountsList connected OF accounts
DELETE/accounts/{account}Disconnect an OF account
POST/authenticateStart an authentication attempt
GET/authenticate/{attempt_id}Poll attempt status
PUT/authenticate/{attempt_id}Submit credentials / 2FA
POST/authenticate/{attempt_id}/send-email-to-creatorTrigger the OF email-code helper
POST/authenticate/{account_id}/reauthenticateRe-auth an existing account
POST/client-sessionsMint a short-lived client session

Media upload status

HTTPPathNotes
GET/{account}/media/upload/{upload}/statusPoll an in-progress media upload

Important clarifications

A couple of endpoints sound like they should be Hybrid or Computed, but aren't. Calling them out here to preempt confusion:

These sound calculated, but are Live passthrough

The following endpoints return numbers and metrics, but the response is a straight passthrough of what OnlyFans returns — OFAPI does not compute or enrich them:

  • /statistics/overview
  • /statistics/total-transactions
  • /statistics/subscriber-metrics
  • /me/model-start-date
  • /me/top-percentage
  • /payouts/balances
  • /payouts/eligibility
  • /payouts/list-earning-statistics
  • /payouts/list-payout-requests

Media URLs & file downloads

Media files from both platforms — everything served from https://cdn*.onlyfans.com/ and https://cdn*.fansly.com/ — get special handling. Once we have our own copy of a file, subsequent requests for it are served from our own CDN at https://cdn.fansapi.com/ instead of contacting OnlyFans or Fansly.

Two reasons this matters for you:

  • It saves credits. Once a file is cached, fetching it again does not consume any credits — the upstream platform is never contacted.
  • It's significantly faster. Our CDN is geographically distributed, so cached files are served from a location close to your end users instead of round-tripping through OnlyFans or Fansly every time.

The two platforms differ in when a file enters the cache. OnlyFans caches eagerly (any endpoint that surfaces a CDN URL starts saving a copy); Fansly caches on demand (only an explicit download populates the cache). The sections below spell out both.

Automatic media caching is a team setting

Eager caching on OnlyFans follows the Automatic media caching switch in your team settings in the dashboard, which is on by default. Turning it off stops us caching media just because a URL appeared in a response; media you download explicitly is still cached on demand. It does not change Fansly behaviour, which is on-demand either way.

Downloading or scraping media files

The endpoints that hand you back actual media bytes — Download Media and the deprecated Scrape Media — first check whether we already have that file in our own CDN.

  • If we have it cached → you get a URL on our own cdn.fansapi.com. Download Media returns a 302 redirect to it (most HTTP clients follow redirects automatically; curl needs -L). Scrape Media returns it as temporary_url in the response body. No credits are charged in this case, because OnlyFans is never contacted.
  • If we don't have it cached yet → Download Media returns a 302 redirect to dl.fansapi.com, which streams the bytes from OnlyFans. We also queue a background cache download. Once caching completes, later requests can be served from our CDN.

Non-DRM downloads support Range and HEAD requests. Range downloads are billed for the bytes streamed; HEAD returns metadata without a body, download credits, or a background cache download. DRM downloads use a separate endpoint and do not support Range or HEAD.

Download Media from the Fansly CDN always answers with a 302 redirect — it never streams bytes through us. Where it points depends on whether the file is cached:

  • If we have it cached → a 302 to a signed cdn.fansapi.com URL, valid for 1 hour. Fansly is never contacted.
  • If we don't have it cached yet → a 302 to the original signed cdn*.fansly.com URL, so your download starts immediately, and we queue a background job to save our own copy. The next call for that same file gets the cdn.fansapi.com redirect instead.

Because it is always a redirect, your HTTP client must follow redirects (curl needs -L).

Pass the signed URL through unchanged

Fansly CDN URLs are signed and time-limited. On a cache miss we need Expires, Key-Pair-Id and Signature intact to fetch the file — if any are missing the endpoint returns a 422 listing which ones. Fetch the URL from the API and download it promptly rather than storing it and retrying later.

Streaming manifests (.m3u8 and .mpd) are redirected but never cached — a manifest is a playlist of separately-signed segment URLs rather than a media file, so a cached copy would be useless.

Endpoints that return media URLs in their response

Any endpoint that returns OnlyFans CDN URLs in its response body — List Chat Messages, List Posts, List Vault Media, and so on — follows the same caching pattern, applied per-URL:

  • Each https://cdn*.onlyfans.com/* URL in the response is checked against our CDN.
  • URLs we already have cached are replaced with the equivalent https://cdn.fansapi.com/* URL before the response is returned to you.
  • URLs we don't have cached yet are left as the original https://cdn*.onlyfans.com/* URL, and we start saving our own copy. Future responses that include the same URL will return the cdn.fansapi.com version instead.

This rewriting is applied per-URL, so a single response can contain any mix of OnlyFans CDN URLs and rewritten cdn.fansapi.com URLs depending on what we've already cached.

These Fansly endpoints rewrite https://cdn*.fansly.com/* URLs in their response body:

HTTPPath
GET/fansly/{fanslyAccount}/chats
GET/fansly/{fanslyAccount}/chats/{chat_id}
GET/fansly/{fanslyAccount}/chats/{chat_id}/messages
POST/fansly/{fanslyAccount}/chats/{chat_id}/messages
GET/fansly/{fanslyAccount}/account-media/{ids}
GET/fansly/{fanslyAccount}/followers
GET/fansly/{fanslyAccount}/subscribers
GET/fansly/{fanslyAccount}/subscription-tiers
GET/fansly/{fanslyAccount}/top-supporters
GET/fansly/{fanslyAccount}/top-supporters/{account_id}
GET/fansly/{fanslyAccount}/lists
GET/fansly/{fanslyAccount}/lists/{list_id}/items
GET/fansly/{fanslyAccount}/users/{usernames}
  • URLs we already have cached are replaced with a signed https://cdn.fansapi.com/* URL, valid for 15 minutes.
  • URLs we don't have cached yet are passed through untouched, as the original signed cdn*.fansly.com URL.

Rewriting does not trigger caching on Fansly

Unlike OnlyFans, seeing a URL in a response does not start saving a copy. A Fansly file only enters our CDN when you explicitly fetch it through Download Media from the Fansly CDN. Until then, every response keeps returning the raw Fansly URL.

The one exception is the avatar of a connected Fansly account, which we cache when the account is connected.

Rewriting is per-URL, so a single response can mix both kinds. Treat every media URL as opaque and download it promptly either way — both the raw Fansly URLs and our rewritten ones expire.

Anything not listed here

If an endpoint isn't listed on this page, treat it as a Live passthrough. The response is the OnlyFans or Fansly payload, unmodified by OFAPI — apart from the media URL rewriting described above.

On this page