# Authorization Code Flow with PKCE (for SPAs)

This flow is required for **public clients** (SPAs) where a user is present to grant consent but the application cannot securely store a client secret.

The flow has two main parts:

- Request User Authorization
- Exchange Authorization Code for an Access Token


## **Part 1: Request User Authorization**

Your application must redirect the user to the eGain authorization endpoint from [metadata](/developer-portal/guides/authentication/metadata) to obtain User's Authorization Code.

* **Method**: `GET`
* **Endpoint**: Your **Authorization URL** (from your client application's [metadata](/developer-portal/guides/authentication/metadata)).
  * **Example Base Authorization URL for a User:**

```
https://ai.egain.cloud/system/auth/TMPRODB88619984-U/oauth2/authorize
```
  * **Example Base Authorization URL for a Customer:**

```
https://ai.egain.cloud/system/auth/TMPRODB88619984-C/oauth2/authorize
```


**Query Parameters:**

| Parameter | Relevance | Description |
|  --- | --- | --- |
| `client_id` | Required | The Client ID for your application. |
| `response_type` | Required | Must be set to `code`. |
| `redirect_uri` | Required | The URI to redirect to after the user grants or denies permission. |
| `scope` | Required | A space-separated list of scopes. You can include any combination of scopes assigned to your client application in a single request. This allows you to generate one multi-purpose token for your entire application, or separate tokens for specific tasks, depending on your architectural needs. |
| `state` | Recommended | An opaque value used to prevent cross-site request forgery attacks. |
| `code_challenge` | Required | A transform value of the `code_verifier` used for PKCE. |
| `code_challenge_method` | Required | The method used to generate the `code_challenge`. Must be `S256`. |


* **Example Full Authorization URL for a User:**

```
https://ai.egain.cloud/system/auth/TMPRODB88619984-U/oauth2/authorize?client_id=b4b2c1d9-4c19-4e8a-8e7a-9a0b1c2d3e4f&response_type=code&redirect_uri=https%3A%2F%2Foauth.pstmn.io%2Fv1%2Fcallback&scope=core.aiservices.read%20core.aiservices.write&state=a1b2c3d4e5f67890&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256
```


## **Part 2: Exchange Authorization Code for an Access Token**

Once your application receives the authorization code, it exchanges it for an access token through access token endpoint found in [metadata](/developer-portal/guides/authentication/metadata).

* **Method**: `POST`
* **Endpoint**: Your **Token URL** (from your client application's metadata).
  * **Example Base Token URL for a User:**

```
https://ai.egain.cloud/system/auth/TMPRODB88619984-U/oauth2/token
```
  * **Example Base Token URL for a Customer:**

```
https://ai.egain.cloud/system/auth/TMPRODB88619984-C/oauth2/token
```


**Headers:**

| Header | Value |
|  --- | --- |
| `Content-Type` | `application/x-www-form-urlencoded` |


**Body Parameters (`application/x-www-form-urlencoded`):**

| Parameter | Relevance | Description |
|  --- | --- | --- |
| `grant_type` | Required | Must be set to `authorization_code`. |
| `code` | Required | The authorization code received from the previous step. |
| `redirect_uri` | Required | The same `redirect_uri` used in the initial authorization request. |
| `client_id` | Required | The Client ID for your application. |
| `code_verifier` | Required | The original secret generated by your application before the flow started. |


* **Example Full Token cURL for a User:**



```curl
curl --location --request POST 'https://ai.egain.cloud/system/auth/TMPRODB88619984-U/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=def456-gh-ijkl-789-mnopqr' \
--data-urlencode 'redirect_uri=https://oauth.pstmn.io/v1/callback' \
--data-urlencode 'client_id=b4b2c1d9-4c19-4e8a-8e7a-9a0b1c2d3e4f' \
--data-urlencode 'code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
```

**Next Steps:**

- [Make Authenticated Requests](/developer-portal/guides/authentication/making-requests)