# Frequently Asked Questions (/faq) import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; ## Getting Started Follow the steps at [app.onlyfansapi.com/register](https://app.onlyfansapi.com/register). It takes less than 1 minute. Yes! You can use our no-code integrations with [Make](/integrations/make), [n8n](/integrations/n8n), or [Zapier](/integrations/zapier). If you need hands-on help, email us at [hello@onlyfansapi.com](mailto:hello@onlyfansapi.com). No sandbox environment is available. However, you can simply create a new account on OnlyFans.com and connect it to OnlyFans API for testing purposes. All of our API endpoints can be used with any programming language. Click on any endpoint in our [API Reference](/api-reference) to view code examples in cURL, JavaScript/TypeScript, Go, Python, Java, and C#. Yes, absolutely. Having your account connected to OnlyFans API doesn't affect your ability to use any other OnlyFans CRM and vice versa. ## API Capabilities & Features Yes, our API fully supports reading and sending messages. Refer to our [List Chats](/api-reference/chats/list-chats) and [Send Message](/api-reference/chat-messages/send-message) endpoints for more details. Image generation is not natively supported at this time. However, we recommend third-party solutions like [fanscreator.ai](https://fanscreator.ai) for this functionality. Direct vault uploads aren't supported by OnlyFans. However, you have a few options: * **Recommended:** Upload media exactly when and where it needs to be posted — for example, directly to a post, message, or scheduled post — instead of preloading it into the vault. This keeps your workflow simple and avoids unnecessary steps. * If you still want to store media in the vault ahead of time, you can: * Upload media using our [OnlyFans CDN upload](/api-reference/media/upload-media-to-the-only-fans-cdn) endpoint. * [Create a post](/api-reference/posts/send-post) with the media, then delete it immediately - the media will remain in your vault * Use our [Send Message](/api-reference/chat-messages/send-message) endpoint to include the media in a message, then delete the message — again, the media will stay in your vault. Yes! Many customers successfully use tools like [n8n](https://n8n.io) and [Supabase](https://supabase.com) for faster development and deployment. Use [Send Mass Message](/api-reference/mass-messaging/send-mass-message) with a `scheduledDate`. Include one user ID in `userIds` to schedule a message for an individual chat. To change it before it sends, get its ID from [List Mass Message Queue](/api-reference/mass-messaging/list-mass-message-queue), then call [Update Mass Message](/api-reference/mass-messaging/update-mass-message). You can update the content, recipients, media, price, or scheduled send time. Refer to our dedicated guide on [setting a price for PPV content](/introduction/guides/composing-messages#setting-a-price-ppv). This will be available in our upcoming Advanced Endpoints feature. You're likely missing the account prefix. * ❌ Wrong: `/api/fans/active` * ✅ Correct: `/api/acct_XXXXXXXX/fans/active` Use our [Search Profiles](/api-reference/public-profiles/search-profiles) endpoint with the `sort` query parameter to list and sort creators. For more frequent data updates on individual creators, use [Get Profile Details](/api-reference/public-profiles/get-profile-details). You can also use our [Create Data Export](/api-reference/data-exports/create-data-export) tool for bulk exports. Not currently. When you add text, questions, or stickers to a story on OnlyFans, the browser actually renders those elements onto the image locally using an HTML Canvas, then uploads the composed image as a separate file. To achieve this through the API, you would need to compose the image yourself before uploading. You can use image processing libraries to render text onto your image, then upload the result via our media upload endpoint: * **PHP** — GD (built-in) or Imagick * **Node.js** — sharp, @napi-rs/canvas, node-canvas * **Python** — Pillow, pyvips * **Ruby** — MiniMagick, ruby-vips Once you've composed the image with your overlays, upload it normally and use the returned `ofapi_media_` ID in your story request. ## Security & Safety Yes, absolutely. We have a 5-year track record with: * Zero accounts banned * Zero accounts red-flagged * Enterprise-grade security measures No. We have a track record of zero account bans over the past 5 years, including many customers using OnlyFans API to build chatbots. Your security is our priority: * All passwords and cookies are hashed in our database * We use OpenSSL with AES-256-CBC encryption * All data is signed with MAC (Message Authentication Code) We implement robust proxy protection: * Each connected account gets a dedicated IP address * Public endpoints use rotating residential proxies * This prevents detection and ensures account safety For more information, refer to our dedicated [proxies guide](introduction/essentials/proxies). No. We do not store any data from authenticated accounts on our servers. All credentials are encrypted using OpenSSL with the AES-256-CBC cipher and signed with a message authentication code (MAC) to prevent tampering. When a session expires, we automatically attempt to re-login up to 3 times within a one-hour period. This ensures minimal disruption to your API usage without requiring any manual intervention. ## API Stability & Performance Our API infrastructure includes: * Web Application Firewall (WAF) * Proxy management * Built-in rate limiting * No stability issues reported to date Check our real-time status at: [status.onlyfansapi.com](https://status.onlyfansapi.com) Website updates have minimal impact: * Downtime only occurs if OnlyFans itself is down * We typically adapt to changes within minutes * No extended service interruptions Cache duration varies per endpoint, though most endpoints are not cached. Check our [response structure guide](/introduction/essentials/response-structure) for specific cache durations. ## Rate Limiting & Best Practices **Recommended approach:** Implement exponential backoff 1. When you receive a 429 error, wait 1 second 2. If it happens again, double the wait time (2s → 4s → 8s) 3. Continue up to a maximum wait time 4. Use queuing systems like AWS SQS, Laravel Queues, or Ruby Sidekiq Email us at [hello@onlyfansapi.com](mailto:hello@onlyfansapi.com) for code examples. Rate limits are documented in our [Rate Limits](/introduction/essentials/rate-limits) guide. ## API Keys Management **Best practice:** One API key per service/integration * Create separate keys for different features * Assign dedicated keys to external developers * This improves security and tracking No, you can create as many API keys as you want, regardless of your subscription plan. Yes, a single API key can access all available endpoints. No. Every API key has full access to every account you've connected to OnlyFans API, including every endpoint. ## Account Authentication & Management **Through our [Console](https://app.onlyfansapi.com):** 1. Go to Dashboard -> Accounts 2. Find the relevant account 3. Click on the Account ID to copy it **Through our API:** 1. Call our [List Accounts](/api-reference/account/list-accounts) endpoint 2. The response includes the account ID in the `id` field OnlyFans API account IDs **always** start with `acct_` Always use the format: `acct_XXXXXXXX` * Include the `acct_` prefix * Endpoint URL example: `https://app.onlyfansapi.com/api/acct_abc123/chats` Yes! Use these endpoints for authentication: * [Start Authentication](/api-reference/connect-onlyfans-account/start-authentication) * [Poll Authentication Status](/api-reference/connect-onlyfans-account/poll-authentication-status) * Optionally, [Submit 2FA](/api-reference/connect-onlyfans-account/submit2fa) Use our [Get Current Account](/api-reference/account/get-current-account) endpoint to retrieve the authenticated account details. No need to use our UI - integrate these endpoints directly with your platform. Yes! Use our [Start Authentication](/api-reference/connect-onlyfans-account/start-authentication) endpoint. We also have an authentication library available on NPM — see our [Login with OnlyFans documentation](/auth). Follow the "Option 2: By providing cURL request" step in our [connect OnlyFans account guide](/introduction/guides/connect-onlyfans-account#option-2-by-providing-curl-request). It is currently not possible to retrieve the user agent that OnlyFans API uses to make requests. Unfortunately, no — not without risking a red-flag from OnlyFans. Our authentication process is already optimized to be as fast as possible while maintaining safety. The experience is nearly identical to OnlyFans' native process: 1. The QR code that the model normally scans during OF login will appear in our dashboard and via email (sent to both the OnlyFans API user and the model) 2. After scanning the code and completing the selfie check, the account will be authenticated You're probably adding the account again instead of re-connecting it. Use the [Re-authenticate Account](/api-reference/connect-onlyfans-account/re-authenticate-account) endpoint instead of [Start Authentication](/api-reference/connect-onlyfans-account/start-authentication). Yes! Use our [List Accounts](/api-reference/account/list-accounts) endpoint. You can retrieve this through: * The [Get Current Account](/api-reference/account/get-current-account) endpoint under `subscribersCount` * Or the [List User Lists](/api-reference/user-list-collections/list-user-lists) endpoint under `fans.usersCount` The "top X percentage of all creators" value can be retrieved through: * [Get Top Percentage](/api-reference/account/get-top-percentage) endpoint * Or [Get Current Account](/api-reference/account/get-current-account) under `performerTop` Go to our dashboard at [app.onlyfansapi.com](https://app.onlyfansapi.com) and click on "Invite & manage members" in the sidebar. ## Fan Data & Analytics This is normal behavior: * Chat lists return immediately * Fan details are scraped in the background (usually takes 2-3 seconds) Either call our [Get User Details](/api-reference/users/get-user-details) endpoint, or retry the original endpoint after 10 seconds. Use the lastSeen field from our [Get Profile Details](/api-reference/public-profiles/get-profile-details) or [Get User Details](/api-reference/users/get-user-details) endpoints. If the `lastSeen` value is recent, the fan is likely online. ```json { "lastSeen": "2025-05-01T15:01:07+00:00" ... } ``` [-> Read more about caching](/introduction/essentials/response-structure#cache-control) **On Fansly**, use the `lastSeenAt` field from our [Get User Details](/api-reference/fansly/users/get-user-details) endpoint instead. Note that it's a Unix timestamp in milliseconds rather than an ISO 8601 string. There is [no Fansly presence webhook](#is-there-a-fansly-webhook-for-when-a-fan-comes-online), so polling is the only option. There's two options available: * **Calculate manually:** Use `subscribedOnData.subscribeAt` on endpoints like [List Active Fans](/api-reference/fans/list-active-fans) or [Get User Details](/api-reference/users/get-user-details). * **Human-readable format:** Use `subscribedOnData.duration` (e.g., "3 months") Access comprehensive spending data through these fields: | Field | Description | | ---------------- | ------------------------------ | | `totalSumm` | Combined total of all spending | | `subscribesSumm` | Total spent on subscriptions | | `tipsSumm` | Total spent on tips | | `messagesSumm` | Total spent on paid messages | | `postsSumm` | Total spent on paid posts | | `streamsSumm` | Total spent on streams | * [Get User Details](/api-reference/users/get-user-details) * [List Active Fans](/api-reference/fans/list-active-fans) Filter by fan spendings in our [List Active Fans](/api-reference/fans/list-active-fans), [List All Fans](/api-reference/fans/list-all-fans), and [List Expired Fans](/api-reference/fans/list-expired-fans) endpoints by adding `filter.total_spent` to the query parameters. You can even filter by minimum tips. Use our [Search Profiles](/api-reference/public-profiles/search-profiles) endpoint with the `sort` query parameter set to `subscribers`. Retrieve it through the [List User Lists](/api-reference/user-list-collections/list-user-lists) endpoint under `following.usersCount`. Use the [Get User List](/api-reference/user-list-collections/get-user-list) endpoint with `rebill_on` as the `{userListId}`. Call the [List User Lists](/api-reference/user-list-collections/list-user-lists) endpoint and calculate the difference between `rebill_on.usersCount` and `rebill_off.usersCount`. Use our [Set Fan's Custom Name](/api-reference/fans/set-fans-custom-name) endpoint. Sadly, OnlyFans doesn't store language preferences. Workaround: 1. Fetch chat messages from the fan 2. Use a third-party language detection API 3. Store the detected language in your database No direct endpoint exists, but you can: 1. Retrieve chat messages using the [List ChatMessage](/api-reference/chat-messages/list-chat-messages) endpoint 2. Check if `isOpened = true` AND `price > 0`, which indicates a purchased PPV Yes. Any data that you can retrieve through our API endpoints, you can programmatically scrape. `data.fan.id` is the OnlyFans User ID of the fan, which you can also use to get the chat's messages in the [List Chat Messages](/api-reference/chat-messages/list-chat-messages) endpoint. Use our [List Chats](/api-reference/chats/list-chats) endpoint, where `data.fan.id` is the `chat_id` you need for the [List Chat Messages](/api-reference/chat-messages/list-chat-messages) endpoint. Currently, OnlyFans API doesn't support removing multiple users from a list in a single request. You have two options: 1. Clear the entire list using [Clear User List](/api-reference/user-list-collections/clear-user-list) 2. Send one DELETE request per user via [Remove User from a User List](/api-reference/user-list-collections/remove-user-from-a-user-list) Use the `isNew` field from the [List Chat Messages](/api-reference/chat-messages/list-chat-messages) endpoint: * `isNew: true` — the message has **not** been seen yet * `isNew: false` — the fan has read the message A real-time read-receipt webhook is not available, as OnlyFans does not expose message-read events in real time. Polling the `isNew` field is the recommended workaround. ## Webhooks & Media Handling * 📚 Documentation: [docs.onlyfansapi.com/webhooks](/webhooks) * 🎥 Video Demo: [cap.so/s/p2wfkj072yt2x96](https://cap.so/s/p2wfkj072yt2x96) When `"isReady": false`, the media is still processing. **Solution:** 1. Get the chat ID from the webhook 2. Poll the [List ChatMessage](/api-reference/chat-messages/list-chat-messages) endpoint every 10-20 seconds 3. Wait for `"isReady": true` 4. The URL will then be available **Alternatively:** Download and store vault content internally for reverse searching by media ID, once the media is ready. Yes, you can use webhooks with no-code tools like Make, n8n or Zapier. Just set up a webhook listener in your tool and configure it to receive data from our API. We have most webhook events available as Make and Zapier modules, which you can find in our [Make](/integrations/make/available-modules#instant-triggers) and [Zapier](/integrations/zapier/available-modules#instant-triggers) directories. Click on the webhook in your dashboard. It will take you to a details page where you can view all events that have recently been sent to your webhook URL. No. Here's how OnlyFans handles typing indicators: * When `users.typing` is received, OnlyFans shows a typing indicator for exactly 5 seconds * If a user continues typing, consecutive `users.typing` events are sent every \~3 seconds, resetting the timer * If no new `users.typing` event is received after 5 seconds, the indicator is hidden * If a `messages.received` event is received while the indicator is active, it is hidden You can replicate this logic in your own UI. You may need to adjust the timing slightly due to webhook delivery delays. Your endpoint can receive an event more than once. For example, it may accept a request but take too long to respond, causing a retry. Automatic delivery is limited to **3 attempts in total**, with exponential backoff. Successful delivery is not guaranteed. Automatic retries stop after the attempt limit, and events that occur while an endpoint is [paused](/webhooks/delivery-and-retries#endpoints-that-keep-failing) are not buffered. **Best practices:** * Save the event durably before returning a 2xx response, then process it asynchronously * Deduplicate on the `X-OFAPI-Idempotency-Key` header when present; some ephemeral events do not include one * Check the "Attempts" column in the dashboard to confirm if retries are occurring See [Delivery & retries](/webhooks/delivery-and-retries) for the full schedule and behaviour. OnlyFans uses the term "follow" when a user subscribes to a free account. There is no separate "follow" action — it's the same as subscribing, just with a $0 price. To get notified about new followers, use the [subscriptions webhooks](/webhooks/available-events#subscriptions) (e.g. `subscriptions.new`). These fire for both paid and free subscriptions. No. OnlyFans does not expose message-read events in real time — even their own UI only updates read indicators on page refresh, not via websockets. **Workaround:** Poll the `isNew` field on the [List Chat Messages](/api-reference/chat-messages/list-chat-messages) endpoint. When `isNew` changes from `true` to `false`, the fan has read the message. No. Fansly exposes no fan presence signal at all, so there is no Fansly equivalent of the OnlyFans [`users.online`](/webhooks/available-events#usersonline) and [`users.offline`](/webhooks/available-events#usersoffline) events. See our [Fansly webhook events](/webhooks/fansly-events#users) for the full catalog. **Workaround:** Poll our [Get User Details](/api-reference/fansly/users/get-user-details) endpoint and check the `lastSeenAt` field. If the value is recent, the fan is likely online. ```json { "lastSeenAt": 1700000000000 ... } ``` Unlike the OnlyFans `lastSeen` field, which is an ISO 8601 string, Fansly returns epoch **milliseconds**. Divide by `1000` before passing it to a seconds-based date parser. You can look up several fans in one call — pass a comma-separated list of usernames, or account IDs via the `ids` query parameter. Bulk requests still only cost one API credit, which keeps polling cheap. ## Media & Downloads `cdn*.onlyfans.com` URLs cannot be accessed directly due to OnlyFans' security — they are tied to specific IPs (in this case, our proxy IP). Use our [Download Media from the OnlyFans CDN](/api-reference/media/download-media-from-the-only-fans-cdn) endpoint to successfully download media files. Use our [Download Media from the Fansly CDN](/api-reference/fansly/media/download-media-from-the-fansly-cdn) endpoint: GET `https://app.onlyfansapi.com/api/fansly/{fanslyAccount}/media/download/{FANSLY_CDN_URL}`. Unlike the OnlyFans endpoint, this one always answers with a **`302` redirect** rather than a binary body — either to a cached copy on our own `cdn.fansapi.com`, or to the original Fansly URL while we cache it in the background. Make sure your HTTP client follows redirects (`curl` needs `-L`). Pass the CDN URL through **with its signed query parameters intact** (`Expires`, `Key-Pair-Id`, `Signature`). If any are missing you'll get a `422` listing them. See the [Downloading Media guide](/introduction/guides/downloading-media#downloading-media-from-the-fansly-cdn) for examples. Because we already have that file cached. Fansly endpoints that return media URLs — List Chat Messages, Get Account Media, List Followers, and others — rewrite any URL we've cached to a short-lived signed `cdn.fansapi.com` URL, which is faster and served from a location near your users. Files we haven't cached yet are returned as the original `cdn*.fansly.com` URL. Both kinds are fetchable and both expire, so treat every media URL as opaque and download it promptly. See [Endpoint Data Sources](/introduction/essentials/endpoint-data-sources#media-urls--file-downloads) for which endpoints do this. When a 403 occurs: 1. Call the endpoint again that you retrieved the `cdn*.onlyfans.com` URL from 2. Call the download endpoint again with the newly retrieved CDN URL **Important checks:** * Always use the **same Account ID** for both retrieving and downloading. For example, if you got the URL from `/api/acct_ABC123/chats/123/messages`, you must use `acct_ABC123` in your download request * Use the CDN URL immediately — don't wait longer than 1 minute, as CDN URLs expire quickly No distinction between public vs. premium or owned vs. subscribed content. The only limitation is that the authenticated account must have access to view the media file on OnlyFans. No. Any account type can download media as long as the authenticated account has access to view the media file. This happens when `convertedToVideo` is set to `false`. The file is still being converted. Once the conversion completes and the status changes to `true`, you'll be able to download the video successfully. You can only view content that is accessible to the connected account — either your own content (if it's a creator account) or content from creators the account is subscribed to. **TL;DR:** Through our API, you can view all content you can also see when logging into onlyfans.com. Our API does not bypass any subscription or PPV pricing. ## Tracking & Free Trial Links Yes! In our dashboard at [app.onlyfansapi.com](https://app.onlyfansapi.com), click on "Trial & Tracking Links" in the sidebar. You'll see an overview with clicks, subscribers, revenue, spender count, ARPS, creation date, and expiration date. You can also create links and generate shareable URLs with optional revenue visibility. For calculation logic details, see our [Free Trial Links documentation](/api-reference/free-trial-links). No limits! We've created hundreds to thousands of links per day via our API with no restrictions: * 🎁 Free Trials: No limit per day * 🔗 Tracking Links: No limit per day Different services calculate tracking and free trial link revenue differently, since OnlyFans doesn't provide this data natively. Some discrepancies between tools (e.g., Infloww, FansMetrics) are expected and normal. We are continuously improving our calculation logic to be as accurate as possible. Yes. By default, a smart link can send events to more than one pixel at the same time. This is configured directly on the individual smart link itself. Open **Smart Links → Links**, edit the Smart Link, and select each connection in **Tracking Pixels**. You can also manage connections, source scope, test events, and delivery logs from **Smart Links → Tracking Pixels**. ## API Troubleshooting A 401 error indicates an authorization problem — usually an invalid API key. Verify that: * Your API key is correct * The authorization header is set up correctly in your request Check your API key status at [app.onlyfansapi.com/api-keys](https://app.onlyfansapi.com/api-keys). You're using the wrong HTTP method. Check our [API Reference](/api-reference) to see which HTTP method (GET, POST, DELETE, etc.) is required for the endpoint. The API URL doesn't exist. This usually means: * You're missing the account prefix (use `/api/acct_XXXXXXXX/...`) * The endpoint URL is incorrect Check our [API Reference](/api-reference) for valid endpoint URLs. If the body also contains `"code": "account_not_found"`, the URL is fine but the `acct_` ID isn't — that account is disconnected, deleted, or not on your team, so you'll need to reconnect the creator. See [Error responses](/introduction/essentials/response-structure#error-responses). Double-check that the URL has the correct parameters and there are no network issues on your side. In our dashboard, click on "Logs" in the sidebar to see an overview of all requests and any errors. Click on a specific request to view the full details and response. A `400 Bad Request` with the message "Input contains restricted words" is an error returned by OnlyFans itself — not by our API. It means your message contains words that OnlyFans has blocked. Review your message content and remove or rephrase any terms that may be flagged. The error response includes a `textHighLight` field showing which part of your message triggered the restriction. ## Billing & Subscriptions All of our subscription plans, account pricing, and credit pricing are explained at [onlyfansapi.com/pricing](https://onlyfansapi.com/pricing). For as long as you want, until you've consumed all of your 10 free credits. Afterwards, you'll need to subscribe to a plan. Pricing depends on your needs — the more accounts or credits you need, the better our pricing. Schedule a call at [cal.com/onlyfansapi/15min](https://cal.com/onlyfansapi/15min). We offer dynamic pricing for additional accounts, explained at [onlyfansapi.com/pricing](https://onlyfansapi.com/pricing). You can also pre-purchase account seats. View and change your current plan at [app.onlyfansapi.com/billing](https://app.onlyfansapi.com/billing). You currently cannot pause your subscription. To cancel, go to [app.onlyfansapi.com/billing](https://app.onlyfansapi.com/billing). ## Documentation & Resources Yes! Our OpenAPI schema is available at [app.onlyfansapi.com/scribe-docs/openapi.yaml](https://app.onlyfansapi.com/scribe-docs/openapi.yaml). No. Please refer to our [API Reference](/api-reference) for a complete list of available endpoints. Yes! Visit [docs.onlyfansapi.com/llms.txt](https://docs.onlyfansapi.com/llms.txt) for the canonical AI-friendly version of our documentation. We also keep [docs.onlyfansapi.com/llms-full.txt](https://docs.onlyfansapi.com/llms-full.txt) for backward compatibility. # Login with OnlyFans (/auth) import { Card, Cards } from "fumadocs-ui/components/card"; import { ShieldCheckIcon, ZapIcon, CodeIcon, MonitorSmartphoneIcon, FeatherIcon, HeartHandshakeIcon, DownloadIcon, RocketIcon } from "lucide-react"; import {SiNextdotjs, SiTypescript} from "@icons-pack/react-simple-icons"; @onlyfansapi/auth - Official Authentication Library The official authentication library for OnlyFans API provides a seamless, secure way to authenticate users with their OnlyFans accounts directly from your application. ## Features } title="Secure & Responsive"> Built with enterprise-grade security and works seamlessly on both desktop and mobile devices. } title="Lightning Fast"> 1.5kB script loads in just 2ms on 4G internet, ensuring your users never wait for authentication. } title="Developer Experience"> Developer-friendly with TypeScript support, comprehensive docs, and intuitive APIs. ## Why choose @onlyfansapi/auth? }> Built with industry-standard security practices to protect user credentials and authentication flows. Trusted by developers who prioritize security. }> Seamlessly works across all devices—desktop, mobile, and tablet. Your users get a consistent authentication experience regardless of their platform. }> Minimal footprint at just 1.5kB ensures lightning-fast load times. Authenticate users in under 2ms even on slower 4G connections. }> Full TypeScript definitions included for better developer experience, type safety, and autocomplete support in your IDE. }> Use with any framework or no framework at all. Works seamlessly with React, Vue, Svelte, Angular, and vanilla JavaScript with zero dependencies. }> Intuitive APIs designed for ease of use with comprehensive documentation, clear examples, and straightforward integration patterns. ## Getting started Ready to integrate authentication into your application? Check out our installation guide and quickstart to get started in minutes. }> Learn how to install and set up @onlyfansapi/auth in your project. }> Get up and running with our auth package in just a few minutes. }> Explore a complete example of using @onlyfansapi/auth with Next.js and Prisma. # Installation (/auth/installation) import { Tabs, Tab } from "fumadocs-ui/components/tabs"; import { Step, Steps } from "fumadocs-ui/components/steps"; import { Card, Cards } from "fumadocs-ui/components/card"; import { TerminalIcon } from "lucide-react"; ## Package Manager Install `@onlyfansapi/auth` using your preferred package manager: ```bash npm install @onlyfansapi/auth ``` ```bash pnpm add @onlyfansapi/auth ``` ```bash yarn add @onlyfansapi/auth ``` ```bash bun add @onlyfansapi/auth ``` ## Prerequisites Before you begin, make sure you have: } href="https://app.onlyfansapi.com" title="An OnlyFans API account"> If you don't have one yet, registering takes just a few seconds. » Create a free account ## Get Your API Key Before creating a client session token, you'll need an API key to authenticate your requests to the OnlyFans API. ### Go to the OnlyFans API console → API Keys Navigate to your [OnlyFans API console](https://app.onlyfansapi.com) and click on **API Keys** in the navigation menu. ### Create a new API key Click the **"Create API Key"** button to generate a new API key. Copy and save your API key securely - you'll need it to create client session tokens. ## Create Your Client Session Token To use `@onlyfansapi/auth`, you'll need to create a client session token (starts with `ofapi_cs_`) through the [Create Client Session](/api-reference/client-sessions/create-client-session) API endpoint. ### Make a POST request to create a client session Use your API key to authenticate the request: ```bash curl -X POST "https://app.onlyfansapi.com/api/client-sessions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "display_name": "My Application / Model: John Doe" }' ``` **Optional fields:** * `client_reference_id` - Your internal reference ID for the connected account * `proxy_country` - Proxy country value (`"us" | "uk"`) Other proxy countries (DE, FR, IT) have been temporarily removed due to OnlyFans restrictions. Only US and UK proxies are currently available. ### Get the client session token from the response The response will include a `token` field that starts with `ofapi_cs_`: ```json { "data": { "token": "ofapi_cs_OriR8Sdocp0f97eFOdbMMZtiz4Aw5FLX", "display_name": "My Application / Model: John Doe" } } ``` This token is what you'll use with the `@onlyfansapi/auth` package. ### Use the client session token Copy the client session token and use it in your application with `@onlyfansapi/auth`. **Important:** Keep your client session token secure. While it's designed for client-side use, treat it with appropriate security measures. ## Next Steps Once you've installed the package and created your client session token, you're ready to start implementing authentication in your application. * [Quick Start Guide](/auth/quickstart) - Get up and running in minutes * [Create Client Session API Reference](/api-reference/client-sessions/create-client-session) - Full API documentation * [NPM Package](https://www.npmjs.com/package/@onlyfansapi/auth) - Full package documentation on npm # Quick Start (/auth/quickstart) import { Tabs, Tab } from "fumadocs-ui/components/tabs"; import { Step, Steps } from "fumadocs-ui/components/steps"; import { Callout } from "fumadocs-ui/components/callout"; ## Overview This guide will walk you through implementing `@onlyfansapi/auth` in your application. The authentication library provides a simple, secure way to authenticate users with their OnlyFans accounts. ## Before You Start Make sure you've completed the [installation](/auth/installation) steps first. You'll need: * The package installed in your project * An API key to create client session tokens * A client session token (starts with `ofapi_cs_`) to use with the library ## Basic Usage The library exports a single function `startOnlyFansAuthentication` that handles the entire authentication flow. When called, it opens a secure iframe modal where users can authenticate with their OnlyFans account. ### Import ```typescript twoslash import { startOnlyFansAuthentication } from '@onlyfansapi/auth'; ``` ### Function Signature ```typescript const startOnlyFansAuthentication: (clientSessionToken: string, options: { onSuccess: (data: AuthSuccessData) => void; onError: (error: AuthFailureError) => void; onContinue?: () => void; }) => void ``` **Parameters:** * `clientSecret` (string, required): Your client session token obtained from the [Create Client Session](/api-reference/client-sessions/create-client-session) API endpoint * `options.onSuccess` (function, required): Callback invoked when authentication succeeds * `options.onError` (function, required): Callback invoked when authentication fails ## Framework Examples ```tsx import React, { useState } from 'react'; import { startOnlyFansAuthentication } from '@onlyfansapi/auth'; export default function AuthComponent() { const [isLoading, setIsLoading] = useState(false); const [authData, setAuthData] = useState(null); const [error, setError] = useState(null); const handleAuthentication = () => { setIsLoading(true); setError(null); startOnlyFansAuthentication('ofapi_cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', { onSuccess: (data) => { console.log('Authentication successful:', data); setAuthData(data); setIsLoading(false); // data.accountId - The authenticated account ID // data.username - The authenticated username // data.response - Full response from the API }, onError: (error) => { console.error('Authentication failed:', error); setError(error); setIsLoading(false); // error.message - Error message // error.code - Error code (if available) // error.details - Additional error details (if available) }, }); }; return (
{authData && (

Authentication Successful!

Account ID: {authData.accountId}

Username: {authData.username}

)} {error && (

Authentication Failed

{error.message}

)}
); } ```
```vue ``` ```svelte
{#if authData}

Authentication Successful!

Account ID: {authData.accountId}

Username: {authData.username}

{/if} {#if error}

Authentication Failed

{error.message}

{/if}
```
```typescript import { Component } from '@angular/core'; import { startOnlyFansAuthentication } from '@onlyfansapi/auth'; @Component({ selector: 'app-auth', template: `

Authentication Successful!

Account ID: {{ authData.accountId }}

Username: {{ authData.username }}

Authentication Failed

{{ error.message }}

` }) export class AuthComponent { isLoading = false; authData: any = null; error: any = null; handleAuthentication() { this.isLoading = true; this.error = null; startOnlyFansAuthentication('ofapi_cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', { onSuccess: (data) => { console.log('Authentication successful:', data); this.authData = data; this.isLoading = false; }, onError: (error) => { console.error('Authentication failed:', error); this.error = error; this.isLoading = false; }, }); } } ```
```html OnlyFans API Auth
```
## Response Data The library provides TypeScript types for better type safety. Import them if needed: ```typescript import type { AuthSuccessData, AuthError } from '@onlyfansapi/auth'; ``` ### Success Response When authentication is successful, the `onSuccess` callback receives an `AuthSuccessData` object: ```typescript interface AuthSuccessData { accountId: string; // The authenticated OnlyFans account ID username: string; // The authenticated OnlyFans username response: object; // Full response object from the API containing additional metadata } ``` **Example usage:** ```typescript onSuccess: (data) => { // Store the account ID for future API requests localStorage.setItem('ofAccountId', data.accountId); // Redirect to dashboard or update UI console.log(`Authenticated as ${data.username}`); } ``` ### Error Response When authentication fails, the `onError` callback receives an `AuthError` object: ```typescript interface AuthError { message: string; // Human-readable error message code?: string; // Error code (if available) for programmatic handling details?: object; // Additional error details (if available) } ``` **Common error scenarios:** * User cancels the authentication flow * Network connectivity issues * Invalid or expired client session token * OnlyFans account access issues **Example error handling:** ```typescript onError: (error) => { if (error.code === 'AUTH_CANCELLED') { // User closed the authentication modal console.log('Authentication cancelled by user'); } else { // Handle other errors console.error('Authentication failed:', error.message); // Display error to user } } ``` ## Security The authentication library implements multiple security measures to protect user data: * **Origin validation**: All communication with the authentication iframe is validated by origin * **Domain whitelisting**: Only messages from the configured OnlyFansAPI.com domain are accepted * **Secure token transmission**: Client session tokens are passed securely via URL parameters * **HTTPS required**: The library requires HTTPS connections in production environments ## Best Practices ### Storing Client Session Tokens Store your client session token securely: ```typescript // ✅ Good: Use environment variables (if using a build tool) const CLIENT_SECRET = process.env.NEXT_PUBLIC_OFAPI_CLIENT_SECRET; // ✅ Good: Fetch from your backend API (most secure) const clientSecret = await fetch('/api/client-secret').then(r => r.json()); // ❌ Bad: Hardcode in your source code const CLIENT_SECRET = 'ofapi_cs_...'; ``` ### Error Handling Always handle both success and error cases: ```typescript startOnlyFansAuthentication("clientSecret", { onSuccess: (data) => { // Update your application state // Persist authentication data if needed // Redirect or update UI }, onError: (error) => { // Log errors for debugging // Show user-friendly error messages // Provide fallback options }, }); ``` ### User Experience * Show a loading state while authentication is in progress * Disable the authentication button during the flow to prevent duplicate requests * Provide clear feedback on success or failure * Consider adding a "try again" option if authentication fails ## Troubleshooting ### Common Issues **Authentication modal doesn't open:** * Ensure your client session token is valid and properly formatted * Check browser console for any error messages * Verify that pop-ups aren't blocked by your browser **"Invalid client secret" error:** * Verify your client session token is correct (starts with `ofapi_cs_`) * Check that the token hasn't expired * Ensure you're using a token created via the [Create Client Session API](/api-reference/client-sessions/create-client-session) **Network errors:** * Check your internet connection * Verify OnlyFansAPI.com is accessible from your network * Some corporate firewalls may block the authentication iframe ## Next Steps * Review the [Installation Guide](/auth/installation) if you haven't already * Check out the [NPM package](https://www.npmjs.com/package/@onlyfansapi/auth) for the latest version and updates * Visit [onlyfansapi.com/auth](https://onlyfansapi.com/auth) for more information * Explore the [API Reference](/api-reference) to see what you can do with authenticated accounts # API Reference (/api-reference) import { SiOnlyfans } from "@icons-pack/react-simple-icons"; import { FanslyIcon } from "@/components/fansly-icon"; import { FanvueIcon } from "@/components/fanvue-icon"; ## Pick your platform We currently offer three API surfaces. Choose the one you're building against to explore its endpoints. } href="/api-reference/overview" title="OnlyFans API"> Our most popular API with 350+ endpoints covering messaging, fans, media, payouts, posts, and more. } href="/api-reference/fansly" title="Fansly API"> Our brand-new Fansly API, covering messaging, fans, followers, subscribers, earnings, and more. } href="/api-reference/fanvue" title="Fanvue API"> Our Fanvue API, covering chats, messages, fans, subscribers, earnings insights, and more. # Integrations (/integrations) import { SiMake, SiMakeHex, SiZapier, SiZapierHex, SiIfttt, SiIftttHex, SiN8n, SiN8nHex } from "@icons-pack/react-simple-icons"; Please choose an integration to get started: } href="/integrations/n8n" title="n8n (recommended)"> Best for building complex, multi-step no-code automations. Perfect for users who want powerful automation capabilities with full control over their workflows. } href="/integrations/make" title="Make"> Best for simple OnlyFans automations, all without writing code. Ideal for users who want simple visual workflow design. } href="/integrations/zapier" title="Zapier"> Best for quickly setting up no-code automations based on triggers like new messages, PPV purchases, or new fan subscriptions. Great for those who want ease-of-use and a large library of app connections. Or watch our tutorial video: