# Source: https://polar.sh/docs/integrate/oauth2/connect.md

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

# OAuth 2.0 Connect

## Authorize

To start the authorization flow you need to redirect the user to the authorization URL. It looks like this:

```
https://polar.sh/oauth2/authorize?
  response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
  &scope=openid%20email
```

The parameters are the one described in the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The most important ones are:

<ParamField path="response_type=code" type="string" required>
  Indicates that you want to use the authorization code flow. Most common and
  the only one supported by Polar.
</ParamField>

<ParamField path="client_id" type="string" required>
  The Client ID you got when creating the OAuth 2.0 client.
</ParamField>

<ParamField path="redirect_uri" type="string" required>
  The URL where the user will be redirected after granting access to their data.
  Make sure you declared it when creating the OAuth2 client.
</ParamField>

<ParamField path="scope" type="string" required>
  A space-separated list of scopes you want to ask for. Make sure they are part
  of the scopes you declared when creating the OAuth2 client.
</ParamField>

If you redirect the user to this URL, they'll see a page asking them to grant access to their data, corresponding to the scopes you asked for. By default, the user will also be prompted to select one of their organizations, as Polar generates organization-level access tokens by default.

<img src="https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=1927989fc0478485e77a1140a088e939" data-og-width="1920" width="1920" data-og-height="1080" height="1080" data-path="assets/integrate/oauth2/connect.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?w=280&fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=a1aee489dd928855eebd48275b442a3a 280w, https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?w=560&fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=08e3afe8990106c73cd5201a6175fd50 560w, https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?w=840&fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=98c7a9731dec10d2c508bb6165acc93e 840w, https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?w=1100&fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=5d09f0d4a88bb704f79590b3f8e611bd 1100w, https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?w=1650&fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=fee040d7fffec477262ae5bf313ffa76 1650w, https://mintcdn.com/polar/0Af3hN6-oIM4IHT3/assets/integrate/oauth2/connect.png?w=2500&fit=max&auto=format&n=0Af3hN6-oIM4IHT3&q=85&s=a60a6a05eb190e81c422087c317e8300 2500w" />

If they allow it and select an organization, they'll be redirected to your `redirect_uri` with a `code` parameter in the query string. This code is a one-time code that you can exchange for an access token.

To skip the organization selection and get a user-scoped token instead, you can add `sub_type=user` to the authorization URL:

```
https://polar.sh/oauth2/authorize?
  response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
  &scope=openid%20email
  &sub_type=user
```

#### Exchange code token

Once you have the authorization code, you can exchange it for an access token. To do so, you'll need to make a `POST` request to the token endpoint. This call needs to be authenticated with the Client ID and Client Secret you got when creating the OAuth2 client.

Here is an example with cURL:

```bash Terminal theme={null}
curl -X POST https://api.polar.sh/v1/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code&code=AUTHORIZATION_CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=https://example.com/callback'
```

You should get the following response:

```json  theme={null}
{
  "token_type": "Bearer",
  "access_token": "polar_at_XXX",
  "expires_in": 864000,
  "refresh_token": "polar_rt_XXX",
  "scope": "openid email",
  "id_token": "ID_TOKEN"
}
```

The `access_token` will allow you to make authenticated API requests on behalf of the user. The `refresh_token` is a long-lived token that you can use to get new access tokens when the current one expires. The `id_token` is a signed JWT token containing information about the user, as per the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).

#### Organization vs User Access Tokens

By default, Polar OAuth2 flow generates **organization-level** access tokens. These tokens are tied to a specific organization rather than a user, allowing requests to operate only on that organization's data, which improves privacy and security.

When using the default flow, the user will be prompted to select one of their organizations before allowing access to their data:

```
https://polar.sh/oauth2/authorize?response_type=code&client_id=polar_ci_j3X95_MgfdSCeCd2qkFnUw&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid%20email
```

To request a **user-scoped** access token instead, you need to explicitly add the parameter `sub_type=user` to the authorization URL:

```
https://polar.sh/oauth2/authorize?response_type=code&client_id=polar_ci_j3X95_MgfdSCeCd2qkFnUw&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid%20email&sub_type=user
```

The rest of the flow remains unchanged. The access token you'll get will be tied to either the selected organization (default) or the user (when explicitly requested).

#### Public Clients

Public clients are clients where the Client Secret can't be kept safe, as it would be accessible by the final user. This is the case for SPA, mobile applications, or any client running on the user's device.

In this case, **and only if the client is configured as a Public Client**, the request to the token endpoint won't require the `client_secret` parameter. However, the [PKCE](https://oauth.net/2/pkce/) method will be required to maximize security.

### Make authenticated requests

Once you have an access token, either from a Personal Access Token or from the OpenID Connect flow, you can make authenticated requests to the API. Here is a simple example with cURL:

```bash Terminal theme={null}
curl -X GET https://api.polar.sh/v1/oauth2/userinfo \
  -H 'Authorization: Bearer polar_at_XXX'
```