Authorizing users

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://login.happeo.com/oauth/authorize
Method: GET (via browser redirect)

Example Request Construction:

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://login.happeo.com/oauth/authorize?${urlParams.toString()}`;

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://login.happeo.com/oauth/token
Method: POST Content-Type: application/x-www-form-urlencoded

Example Request:

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://login.happeo.com/oauth/token`; // Token endpoint

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.

Endpoint: https://login.happeo.com/oauth/token
Method: POST Content-Type: application/x-www-form-urlencoded

Example Request:

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://login.happeo.com/oauth/token`; // Token endpoint

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