Skip to main content
V3 uses the OAuth 2.0 Authorization Code flow with PKCE. Your backend owns the client secret, PKCE verifier, state, and token exchange.

Create the authorization request

Build the URL on your backend and send the user to it.
Each parameter may appear once. Unknown or repeated parameters return invalid_request. You do not send resource. If your OAuth client library always sends one, it must be https://api.ofauth.com/v3; any other value returns invalid_request.
Keep the PKCE verifier, client secret, and state record on your backend. Send only the authorization URL to the browser or native app.

Redirect URI rules

Redirect URIs are registered per environment client in the dashboard. The redirect_uri parameter must match a registered value exactly. The URI must be an absolute, canonical URL. Register the exact string you will send. Each client can have up to 20 redirect URIs.

Open the system browser

Open OFAuth as a top-level browser journey. Do not use an iframe or postMessage. Do not send the client secret or PKCE verifier to the browser or native app.

What the user sees

  1. The user signs in to OFAuth or creates an account.
  2. The user links an OnlyFans account, or chooses accounts they or their organization already linked.
  3. The user approves the scopes you requested for the chosen accounts.
  4. OFAuth redirects to your callback.
A linked account belongs to its owner, not to your integration. The owner can share the same account with several apps, and can revoke your access from the OFAuth dashboard at any time.

Accounts linked later

The consent screen can offer the owner Also share accounts I link later. It is off by default, and it is not offered on every consent screen. If the owner turns it on, accounts are added to your authorization with the scopes they approved, and you receive authorization.updated with reason: "auto_added":
  • In Live, each OnlyFans account the owner newly links afterwards is added.
  • In Test, only accounts designated as test accounts are added, when they are designated, and only if they were linked after auto-add was turned on.
  • Only new accounts are added. Reconnecting an existing account does not add it, and an account the owner removed from your authorization is never added back.
  • The owner can turn the setting off from the third-party apps page in their dashboard. Accounts already shared stay shared.

Handle the callback

OFAuth returns only to the exact registered redirect URI. If the request cannot be tied to a registered redirect URI, OFAuth shows the error instead of redirecting (invalid_request, invalid_scope, unauthorized_client, or access_denied with a reason). The authorization code expires after 5 minutes and is single-use. Your backend must consume the state once. Reject a missing, changed, expired, or reused state. Then handle the error or exchange the code.
Node.js

Return to a native app

The native app asks its backend for the authorization URL. It opens that URL in ASWebAuthenticationSession or a Custom Tab. After the HTTPS callback, the backend can open a one-use Universal Link or App Link. Put only an opaque developer-owned attempt reference in that link. Keep the authorization code, OAuth state, tokens, client secret, and PKCE verifier on the backend. Do not use a custom URL protocol. Do not send OFAuth directly to a native callback. Do not exchange tokens from a public native client.

Requesting more scopes or accounts later

Run the authorization flow again with the larger scope set. The owner approves the additional scopes, and can add or remove accounts. The authorization keeps its authorization_id, and you receive authorization.updated with reason: "consent_updated". Access calls that need a scope you have not been granted fail with missing_scope or additional_consent_required. See Errors.