### Authorizing Users: Obtaining Authorization Keys  
To interact with a user's Happeo data, your application needs to obtain their consent and then acquire authorization keys (tokens). This process involves three main API interactions:

1. **Authorization URL:** The endpoint where users are redirected to grant your application access and specify permissions (scopes).
2. **Obtaining Access Token:** The endpoint where your application exchanges a temporary authorization code for an `access_token` and potentially a `refresh_token`.
3. **Obtaining Refresh Token:** The endpoint used to acquire a new `access_token` when the current one expires, using a `refresh_token`.

* * *

#### 1. The Authorization URL: Initiating User Consent  
This is the first step in the OAuth flow. Your application constructs a URL and redirects the user's browser to Happeo's authorization endpoint. Here, the user logs into Happeo (if not already) and is presented with a consent screen where they can approve the permissions (scopes) your application is requesting.

**Endpoint:** `https://app.happeo.com/oauth/authorize` (use your org domain if custom url is configured)  
**Method:** `GET` (via browser redirect)

**Example Request Construction:**

JavaScript

```javascript
const urlParams = new URLSearchParams({
  client_id: "YOUR_CLIENT_ID", // Your application's unique ID
  redirect_uri: "YOUR_REGISTERED_REDIRECT_URI", // Where Happeo redirects after user approval
  response_type: "code", // Always "code" for Authorization Code Flow
  scope: "profile channels:read", // Permissions requested, space-separated
  state: "YOUR_CSRF_STATE_VALUE", // Unique, random string for CSRF protection
  code_challenge: "YOUR_PKCE_CODE_CHALLENGE", // Derived from code_verifier (e.g., SHA256 of code_verifier, then base64url-encoded)
  code_challenge_method: "S256", // Method used to create code_challenge (S256 is standard)
});

const authUrl = `https://app.happeo.com/oauth/authorize?${urlParams.toString()}`;
// note for above - if your organisation uses a custom url, then you should replace app.happeo.com with your configured domain (e.g., intranet.myorg.com)

res.redirect(authUrl);
```

##### Key Parameters:  
- `client_id`: Your app's unique identifier, which you get when you register your app with Happeo.
- `redirect_uri`: The exact URL in your application where Happeo will send the user back after they approve or deny access. This must be pre-registered with Happeo.
- `response_type`: Must be code to start the Authorization Code Flow.
- `scope`: A space-separated list of permissions your app needs. These can be obtained when creating the OAuth app.
- `state`: A unique, random string your app generates for each request. Happeo sends this back, and your app must verify it to protect against Cross-Site Request Forgery (CSRF) attacks.
- `code_challenge`: A transformed version of your randomly generated code_verifier. This is a crucial part of PKCE security.
- `code_challenge_method`: Tells Happeo how you created the code_challenge. Always S256 for Happeo.

After successful authorization, Happeo will redirect the user back to your redirect_uri with an authorization_code and the state parameter added to the URL.

* * *

#### 2. Obtaining an Access Token  
After receiving the `authorization_code` from Happeo (via the `redirect_uri`), your application must exchange this code for an `access_token` by making a direct POST request to Happeo's token endpoint. This request is made server-to-server or from your client application's code (e.g., JavaScript in a SPA).

**Endpoint:** `https://app.happeo.com/oauth/token` (use your org domain if custom url is configured)  
**Method:** `POST`  **Content-Type:** `application/x-www-form-urlencoded`

**Example Request:**

JavaScript

```javascript
const urlParams = new URLSearchParams({
  client_id: "YOUR_CLIENT_ID",
  client_secret: "YOUR_CLIENT_SECRET",
  redirect_uri: "YOUR_REGISTERED_REDIRECT_URI",
  grant_type: "authorization_code", // Indicates we are exchanging an authorization code
  code: "AUTHORIZATION_CODE_PLACEHOLDER", // The authorization code received from Happeo
  code_verifier: "YOUR_PKCE_CODE_VERIFIER", // The original, untransformed secret generated in step 1
});

const tokenUrl = `https://app.happeo.com/oauth/token`; // Token endpoint (use your org domain if custom url is configured)

const response = await fetch(tokenUrl, {
  method: "POST",
  body: urlParams.toString(), // Send parameters in the request body
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
});

if (!response.ok) {
  throw new Error("Failed to fetch token");
}

const data = await response.json();
```

##### Key Parameters:  
- `client_id`: Your application's unique identifier.
- `client_secret`: Your client secret.
- `redirect_uri`: Must exactly match the redirect_uri used in the initial authorization request.
- `grant_type`: Must be `authorization_code`.
- `code`: The authorization_code received from Happeo's redirect.
- `code_verifier`: The original, randomly generated code_verifier that was used to create the code_challenge in step 1. Happeo will use this to verify the code_challenge.

##### Successful Response (JSON):  
A successful response will contain JSON with:
- `access_token`: The token your application will use to make authenticated requests to Happeo APIs.
- `token_type`: (e.g., Bearer)
- `expires_in`: The lifetime in seconds of the access token.
- `refresh_token`: A token that can be used to obtain new access tokens when the current one expires, without requiring the user to re-authorize.
- `scope`: The granted scopes.

#### 3. Obtaining a Refresh Token (Refreshing an Access Token)  
Access tokens have a limited lifetime (e.g., 1 hour). Once an `access_token` expires, your application will receive an authentication error when trying to use it. If you obtained a `refresh_token` during the initial token exchange, you can use it to get a new `access_token` without prompting the user to re-authorize.

**Example Request:**

JavaScript

```javascript
const urlParams = new URLSearchParams({
  client_id: "YOUR_CLIENT_ID",
  client_secret: "YOUR_CLIENT_SECRET",
  grant_type: "refresh_token", // Indicates we are using a refresh token
  refresh_token: "REFRESH_TOKEN_PLACEHOLDER", // The refresh token received previously
});

const refreshTokenUrl = `https://app.happeo.com/oauth/token`; // Token endpoint (use your org domain if custom url is configured)

const response = await fetch(refreshTokenUrl, {
  method: "POST",
  body: urlParams.toString(),
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
});

if (!response.ok) {
  throw new Error("Failed to refresh token");
}

const data = await response.json();
```

##### Key Parameters in Request Body:  
- `client_id`: Your application's unique identifier.
- `client_secret`: (Optional for public clients). Only required for confidential clients.
- `grant_type`: Must be `refresh_token`.
- `refresh_token`: The `refresh_token` obtained from the initial token exchange.

##### Successful Response (JSON):  
A successful response will be similar to the access token response, containing a new `access_token`, `token_type`, `expires_in`, and potentially a new `refresh_token`.
