Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.whop.com/llms.txt

Use this file to discover all available pages before exploring further.

With OAuth, users sign in to Whop themselves through a sign-in page or an iOS webview. Your app receives Whop user tokens that can authenticate embedded chat and act on behalf of the signed-in user. Use OAuth when your app needs access to the user’s Whop account, or when you do not want to mint company-scoped user tokens from your own backend.

Full OAuth guide

See the general OAuth guide for the complete OAuth 2.1 + PKCE flow, token exchange, refresh, and revocation details.

Setup

Use the Create App endpoint to create an OAuth app programmatically:
import Whop from "@whop/sdk";

const client = new Whop({ apiKey: process.env.WHOP_API_KEY });

const app = await client.apps.create({
  name: "My App",
  redirect_uris: [
    "http://localhost:3000/api/auth/callback/whop",
    "https://myapp.com/api/auth/callback/whop"
  ],
});

console.log(app.id);            // App ID
console.log(app.client_secret); // Client Secret
Update redirect URIs later with the Update App endpoint.

Required scopes

Your OAuth configuration should include these scopes:
ScopePurpose
openid, profile, emailBasic profile info
chat:message:create, chat:readChannels
dms:read, dms:message:manage, dms:channel:manageDirect messages
support_chat:read, support_chat:message:createSupport chats

Web token endpoint

Your server needs to provide a token endpoint that returns a valid OAuth token with the required scopes. The React and vanilla JavaScript chat elements call this function whenever they need to authenticate.
async function getToken() {
  const response = await fetch("/api/token");
  const data = await response.json();
  return data.token;
}
See the OAuth guide for implementing the server-side token exchange.

SDK-managed OAuth on iOS

Call configureWithOAuth on app launch. The SDK handles the entire flow: showing a sign-in webview, obtaining tokens, and refreshing them automatically.
.task {
    await WhopSDK.configureWithOAuth(
        appId: "app_XXXXXXXXXXXXXX",
        scopes: [
            "openid", "profile", "email",
            "chat:message:create", "chat:read",
            "dms:read", "dms:message:manage", "dms:channel:manage",
            "support_chat:read", "support_chat:message:create",
        ]
    )
}
By default, the SDK uses your bundle identifier for the redirect URI (com.yourapp.bundle://oauth/callback). You can customize this:
await WhopSDK.configureWithOAuth(
    appId: "app_XXXXXXXXXXXXXX",
    redirectUri: "myapp://auth/callback",
    scopes: [
        "openid", "profile", "email",
        "chat:message:create", "chat:read",
        "dms:read", "dms:message:manage", "dms:channel:manage",
        "support_chat:read", "support_chat:message:create",
    ]
)
Make sure the redirect URI matches what you configured in the Whop Dashboard > Developer > App > OAuth. When a user navigates to a chat view, the OAuth flow is triggered automatically if they’re not already authenticated. You can also trigger sign-in and sign-out manually:
// Sign in
try await WhopSDK.signIn()

// Sign out
WhopSDK.signOut()

Tracking authentication state

Use the .whopAuthState modifier to reactively track whether the user is signed in:
struct ChatView: View {
    @State private var isAuthenticated = false

    var body: some View {
        VStack {
            if isAuthenticated {
                Text("Signed In")
            } else {
                Text("Not Signed In")
            }
        }
        .whopAuthState($isAuthenticated)
    }
}

Pre-filling tokens

If you already have the user’s Whop tokens from another source, such as a web OAuth flow or tokens synced from your backend, you can pre-fill them to skip the sign-in webview on first launch. This is optional and only relevant if your users have already authenticated with Whop elsewhere.
let tokens = await myBackend.getWhopTokens(for: currentUser)

try await WhopSDK.preSignIn(
    accessToken: tokens.accessToken,
    refreshToken: tokens.refreshToken
)
The SDK extracts the token expiration from the JWT and handles refresh automatically. If the pre-filled tokens expire and can’t be refreshed, the normal OAuth flow kicks in.

Next steps

Authentication

Compare OAuth with company-scoped tokens for embedded chat.

General OAuth guide

Implement the full OAuth flow, token exchange, refresh, and revocation.

Chat element

Learn the props, events, styles, and deeplinking options for the chat UI.

Embedded chat quickstart

Render your first embedded chat experience.