diff --git a/integrations/quickstart.mdx b/integrations/quickstart.mdx
index a7cffe8a..3b86f3d6 100644
--- a/integrations/quickstart.mdx
+++ b/integrations/quickstart.mdx
@@ -47,11 +47,17 @@ Here is a step-by-step guide on how to set up OAuth 2.0 authentication with Dub.
| `response_type` | Expected response type. It should be `code`. |
| `scope` | A space separated list of scopes that you want to request access to. Read more about scopes [here](#scopes). |
| `state` | The state parameter to prevent against CSRF attacks. Read more about it [here](https://auth0.com/docs/protocols/state-parameters) |
+ | `code_challenge` | Required for PKCE. The code challenge generated from the `code_verifier`. |
+ | `code_challenge_method` | Required for PKCE. The method used to generate the code challenge. It should be `S256`. |
+
+
+ PKCE (Proof Key for Code Exchange) is enabled by default and recommended for all applications. If you include `code_challenge` and `code_challenge_method` in the authorization request, you must also include the `code_verifier` when exchanging the code for an access token in Step 3.
+
An example URL would look like this:
```
- GET https://app.dub.co/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=SOME_SCOPE&state=SOME_STATE
+ GET https://app.dub.co/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=SOME_SCOPE&state=SOME_STATE&code_challenge=YOUR_CODE_CHALLENGE&code_challenge_method=S256
```
@@ -72,37 +78,74 @@ Here is a step-by-step guide on how to set up OAuth 2.0 authentication with Dub.
POST https://api.dub.co/oauth/token
```
- Here's an example using the fetch API:
-
- ```js
- await fetch("https://api.dub.co/oauth/token", {
- method: "POST",
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- },
- body: new URLSearchParams({
- code: "YOUR_AUTHORIZATION_CODE",
- client_id: "YOUR_CLIENT_ID",
- client_secret: "YOUR_CLIENT_SECRET",
- redirect_uri: "YOUR_REDIRECT_URI",
- grant_type: "authorization_code",
- }),
- });
- ```
-
The `Content-Type` header should be set to `application/x-www-form-urlencoded`.
- Parameters:
-
- | Property | Description |
- | -------- | ------------------------------------- |
- | `code` | The code you received when the user was redirected back to your application. |
- | `client_id` | The client ID of your OAuth application. |
- | `client_secret` | The client secret of your OAuth application. |
- | `redirect_uri` | The same redirect URI you used in the authorization URL. |
- | `grant_type` | The grant type. It should be `authorization_code`. |
+
+
+ We recommend using the [PKCE](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) flow for all applications, especially native desktop or mobile applications and single-page apps (SPAs) where the `client_secret` cannot be hidden.
+
+ With PKCE, the `client_secret` is **never sent to the authorization server**, preventing the `client_secret` from being leaked from the client application.
+
+ ```js
+ await fetch("https://api.dub.co/oauth/token", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: new URLSearchParams({
+ code: "YOUR_AUTHORIZATION_CODE",
+ client_id: "YOUR_CLIENT_ID",
+ code_verifier: "YOUR_CODE_VERIFIER",
+ redirect_uri: "YOUR_REDIRECT_URI",
+ grant_type: "authorization_code",
+ }),
+ });
+ ```
+
+ Parameters:
+
+ | Property | Description |
+ | -------- | ------------------------------------- |
+ | `code` | The code you received when the user was redirected back to your application. |
+ | `client_id` | The client ID of your OAuth application. |
+ | `code_verifier` | The original code verifier used to generate the `code_challenge` in Step 2. |
+ | `redirect_uri` | The same redirect URI you used in the authorization URL. |
+ | `grant_type` | The grant type. It should be `authorization_code`. |
+
+ For example, the [Dub Raycast extension](https://github.com/raycast/extensions/tree/main/extensions/dub) uses PKCE to authenticate users.
+
+
+ If you're building a server-side application where the `client_secret` can be securely stored, you can use the standard flow.
+
+ ```js
+ await fetch("https://api.dub.co/oauth/token", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: new URLSearchParams({
+ code: "YOUR_AUTHORIZATION_CODE",
+ client_id: "YOUR_CLIENT_ID",
+ client_secret: "YOUR_CLIENT_SECRET",
+ redirect_uri: "YOUR_REDIRECT_URI",
+ grant_type: "authorization_code",
+ }),
+ });
+ ```
+
+ Parameters:
+
+ | Property | Description |
+ | -------- | ------------------------------------- |
+ | `code` | The code you received when the user was redirected back to your application. |
+ | `client_id` | The client ID of your OAuth application. |
+ | `client_secret` | The client secret of your OAuth application. |
+ | `redirect_uri` | The same redirect URI you used in the authorization URL. |
+ | `grant_type` | The grant type. It should be `authorization_code`. |
+
+
Response:
@@ -118,14 +161,6 @@ Here is a step-by-step guide on how to set up OAuth 2.0 authentication with Dub.
}
```
- We recommend using the [PKCE](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) flow for native desktop or mobile application or a single-page app (SPA) where the `client_secret` cannot be hidden.
-
- With PKCE, the `client_secret` is **never sent to the authorization server**, preventing the `client_secret` from being leaked from the client application.
-
- Instead of using the `client_secret`, you will need to generate a `code_verifier` and `code_challenge` and use them to exchange for an access token.
-
- For example [Dub Raycast extension](https://github.com/raycast/extensions/tree/main/extensions/dub) uses PKCE to authenticate users.
-