Skip to main content
Connect OnlyFans accounts to your platform securely. OFAuth handles credentials on hosted pages—you receive a Connection ID for API access.
Use Sandbox for testing! Before testing with real OnlyFans accounts, use Sandbox test credentials. Too many login attempts on production accounts can trigger OnlyFans “suspicious activity” detection.

Choose Your Integration


How It Works

  1. Create a Link session with your redirect URL
  2. Redirect the user to OFAuth’s secure authentication page
  3. User authenticates on OFAuth (2FA and captcha handled automatically)
  4. Receive Connection ID via callback URL or webhook

Prerequisites

1

Get API Key

2

Configure Redirect URI

Add your callback URL to Allowed Redirect URIs in Dashboard > Developers > API
3

Set Permissions

Select which OnlyFans data your platform can access in Dashboard > Developers > API > User Data Permissions

Redirect Flow

The simplest integration—redirect users to OFAuth’s hosted authentication pages.
const response = await fetch("https://api.ofauth.com/v2/link/init", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    redirectUrl: "https://yourapp.com/callback",
    clientReferenceId: "your-internal-user-id"
  })
})

const { url } = await response.json()
console.log("Send user to:", url)
Response:
{
  "url": "https://link.ofauth.com/cs_abc123...",
  "expiresAt": "2024-01-15T10:30:00Z"
}

Session Options

OptionTypeDescription
redirectUrlstringCallback URL (must be in Allowed Redirect URIs)
clientReferenceIdstringYour internal user ID for correlation
connectionIdstringExisting connection ID to reconnect

Step 2: Redirect User

window.location.href = url
The user will enter their credentials, complete 2FA if enabled, and solve captchas—all handled automatically by OFAuth.

Step 3: Handle the Callback

After authentication, users are redirected to your URL:
https://yourapp.com/callback?status=success&connection_id=conn_abc123
const params = new URLSearchParams(window.location.search)
const status = params.get("status")
const connectionId = params.get("connection_id")

if (status === "success" && connectionId) {
  await saveConnectionId(userId, connectionId)
  redirect("/dashboard")
} else if (status === "cancelled") {
  console.log("User cancelled at:", params.get("step"))
} else if (status === "error") {
  console.error("Error:", params.get("error_code"))
}

Callback Parameters

ParameterDescription
statussuccess, cancelled, or error
connection_idThe connection ID (on success)
client_reference_idYour internal ID (if provided)
stepWhere user cancelled: pre-login, login, 2fa
error_codeError type: session_expired, invalid_credentials, account_locked, 2fa_failed

Keep users in your app with a popup authentication experience.

Installation

npm install @ofauth/link-embed

JavaScript Library Usage

import { OFAuthLinkEmbed } from '@ofauth/link-embed';

// Create a handler
const handler = OFAuthLinkEmbed.create({
  theme: 'auto',
  async onSuccess(metadata) {
    console.log('Connected:', metadata.connection.id);
    await storeConnection(metadata.connection.id);
  },
  onClose(metadata) {
    console.log('Closed:', metadata.type);
  },
  async onInvalidSession() {
    // Session expired, create a new one
    const response = await fetch("/api/create-link-session");
    const { url } = await response.json();
    handler.open(url);
  }
});

// Open the authentication popup
async function connectOnlyFans() {
  const response = await fetch("/api/create-link-session");
  const { url } = await response.json();
  handler.open(url);
}

Configuration Options

OptionTypeDescription
theme'light' | 'dark' | 'auto'Theme for the interface (default: ‘auto’)
onSuccess(metadata) => voidCalled when authentication succeeds
onClose(metadata) => voidCalled when user closes the embed
onInvalidSession() => voidCalled when session expires

Success Metadata

interface SuccessMetadata {
  successUrl: string;
  connection: {
    id: string;         // Connection ID to store
    userData: {
      id: string;
      name: string;
      username: string;
      avatar: string;
    };
  };
}

Global Script (No Build)

<a
  data-ofauth-link
  href="https://link.ofauth.com/cs_xxxxxxxxx"
  data-ofauth-theme="auto"
>
  Connect OnlyFans Account
</a>

<script
  src="https://unpkg.com/@ofauth/link-embed/dist/embed.global.js"
  defer
  data-auto-init
></script>

<script>
  document.querySelector('[data-ofauth-link]')
    .addEventListener('success', (e) => {
      console.log('Connected:', e.detail.metadata.connection.id);
    });
</script>

Use the Connection

Once you have a Connection ID, make API calls:
const response = await fetch("https://api.ofauth.com/v2/access/self", {
  headers: {
    apikey: "YOUR_API_KEY",
    "x-connection-id": connectionId
  }
})

const account = await response.json()
console.log("Connected as:", account.name)

Reconnecting Expired Connections

When a connection expires, reconnect without creating duplicates:
const response = await fetch("https://api.ofauth.com/v2/link/init", {
  method: "POST",
  headers: {
    apikey: "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    connectionId: "conn_abc123xyz", // Existing connection ID
    redirectUrl: "https://yourapp.com/callback"
  })
})
The existing connection is updated with fresh session data—same Connection ID, no duplicates.

Security Best Practices

Server-Side Verification

Always verify session status server-side, never trust client-side data

HTTPS Only

Use HTTPS for all redirect URLs and API communications

Session Expiry

Link sessions expire after 1 hour. Create a new session if expired.

Allowed URIs

Configure exact redirect URLs in your dashboard. No wildcards.

Troubleshooting

Link sessions expire after 1 hour. Create a new session with /v2/link/init.
Add the URL to Allowed Redirect URIs in Dashboard > Developers > API.
Add your domain to Allowed Origins in the OFAuth dashboard.

Next Steps