> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coloop.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth Flow

The authentication flow differs based on whether you're using a private or public application.

## Private Application Flow (Authorization Code)

1. **Redirect Users to Authorization URL**

   Construct the authorization URL with your `client_id` and `callback_url`:

   ```javascript theme={null}
   const authUrl = new URL("https://clerk.coloop.ai/oauth/authorize");
   authUrl.searchParams.append("client_id", "your_client_id");
   authUrl.searchParams.append("redirect_uri", "your_callback_url");
   authUrl.searchParams.append("response_type", "code");
   authUrl.searchParams.append("scope", "email profile");
   // Redirect user to authUrl
   ```
2. **Handle the Callback**

   After authorization, CoLoop redirects to your callback URL with an authorization code:

   ```javascript theme={null}
   // Example callback URL:
   // https://your-domain.com/oauth2/callback?code=abc123...
   ```
3. **Exchange Code for Tokens**

   Make a POST request to the token endpoint:

   ```javascript theme={null}
   const response = await fetch("https://clerk.coloop.ai/oauth/token", {
     method: "POST",
     headers: {
       "Content-Type": "application/x-www-form-urlencoded",
     },
     body: new URLSearchParams({
       grant_type: "authorization_code",
       client_id: "your_client_id",
       client_secret: "your_client_secret",
       code: "authorization_code_from_callback",
       redirect_uri: "your_callback_url"
     })
   });
   const tokens = await response.json();
   // {
   //   "access_token": "...",
   //   "refresh_token": "...",
   //   "scope": "email profile",
   //   "token_type": "bearer",
   //   "expires_in": 7200
   // }
   ```

## Public Application Flow (PKCE)

1. **Generate PKCE Challenge**

   ```javascript theme={null}
   // Generate a random code verifier
   function generateCodeVerifier() {
     const array = new Uint8Array(32);
     crypto.getRandomValues(array);
     return base64UrlEncode(array);
   }
   // Create code challenge
   async function generateCodeChallenge(verifier) {
     const encoder = new TextEncoder();
     const data = encoder.encode(verifier);
     const digest = await crypto.subtle.digest("SHA-256", data);
     return base64UrlEncode(new Uint8Array(digest));
   }
   const codeVerifier = generateCodeVerifier();
   const codeChallenge = await generateCodeChallenge(codeVerifier);
   ```
2. **Redirect to Authorization URL with PKCE**

   ```javascript theme={null}
   const authUrl = new URL("https://clerk.coloop.ai/oauth/authorize");
   authUrl.searchParams.append("client_id", "your_client_id");
   authUrl.searchParams.append("redirect_uri", "your_callback_url");
   authUrl.searchParams.append("response_type", "code");
   authUrl.searchParams.append("scope", "email profile");
   authUrl.searchParams.append("code_challenge", codeChallenge);
   authUrl.searchParams.append("code_challenge_method", "S256");
   // Redirect user to authUrl
   ```
3. **Exchange Code for Tokens**

   ```javascript theme={null}
   const response = await fetch("https://clerk.coloop.ai/oauth/token", {
     method: "POST",
     headers: {
       "Content-Type": "application/x-www-form-urlencoded",
     },
     body: new URLSearchParams({
       grant_type: "authorization_code",
       client_id: "your_client_id",
       code: "authorization_code_from_callback",
       code_verifier: codeVerifier,
       redirect_uri: "your_callback_url"
     })
   });
   const tokens = await response.json();
   ```

#### Using the Access Token

For both flows, use the access token to make authenticated requests:

```javascript theme={null}
const userInfo = await fetch("https://clerk.coloop.ai/oauth/userinfo", {
  headers: {
    "Authorization": `Bearer ${access_token}`
  }
});
const user = await userInfo.json();
// {
//   "email": "user@example.com",
//   "email_verified": true,
//   "name": "John Doe",
//   ...
// }
```

#### Token Refresh

When the access token expires (after 2 hours), use the refresh token to get a new one:

```javascript theme={null}
const response = await fetch("https://clerk.coloop.ai/oauth/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({
    grant_type: "refresh_token",
    client_id: "your_client_id",
    refresh_token: "your_refresh_token",
    // Include client_secret only for private applications
    ...(isPrivateApp && { client_secret: "your_client_secret" })
  })
});
const tokens = await response.json();
```

#### Security Considerations

1. **Token Storage**
   * Store access tokens and refresh tokens securely
   * For public applications, use secure browser storage mechanisms
   * For private applications, use server-side secure storage
2. **PKCE Verifier**
   * Generate a new code verifier for each authorization request
   * Store the verifier securely until the token exchange
3. **Error Handling**
   * Handle token expiration and refresh scenarios gracefully
   * Implement retry logic with exponential backoff for failed requests
