Using User-Level OAuth

This guide walks you through implementing the Authorization Code Flow. This is the standard method for apps that need to act on behalf of a user, such as performing LPR searches or managing hotlists.

Getting access

Step 1: When registering a Flock app with Flock's team, you'll be asked to provide:

  • Application Name
  • Application Functionality Description
  • Redirect URL(s)

Step 2: Receive Credentials

Flock will register the Flock app for you and then provide to you:

Obtaining User access tokens with OAuth

How it works: a high-level overview

OAuth allows a user in a Flock customer environment to install your app. At the end of the OAuth flow, your app gains an access token. Your app's access token opens the door to Flock API methods and events. During the OAuth flow, you specify which scopes your app needs. Those scopes determine exactly which doors your app can open.

Implementing an OAuth flow can feel hard because there are a lot of steps, but your app really only has to worry about three steps to make OAuth work: requesting scopes, waiting for a user to give their authorization, and exchanging a temporary authorization code for an access token. Redirecting a user to Flock can be done with a single link.

Why is there a third exchanging step in OAuth at all? Why doesn't Flock send your app an access token directly after the user okays your app? The reason is two-factor authentication. You have to prove both that you have the right temporary authorization code, and that you have your app's client secret.

1. Requesting scopes

While developing your app, you'll determine a minimum list of scopes that your app requires to work. When a user installs your app in their Flock environment, you'll request those scopes.

To request scopes, redirect users to https://login.flocksafety.com/authorize

Include both your app's client ID, and a space-separated list of scopes, such as: scope=openid offline_access_customer-hotlist:write. The full redirect URL will look something like this:

https://login.flocksafety.com/authorize?scope=openid offline_access_customer-hotlist:write&client_id=YOUR_CLIENT_ID

When requesting scopes, you also need to tell Flock where to send your temporary authorization code afterward. Include a redirect_uri parameter in the URL above. The redirect_uri is where Flock will send the user back to, along with the temporary authorization code, once the user okays your app. We recommend the redirect_uri to use HTTPS.

When there are multiple redirect_uri values configured when you initially register your Flock app, the redirect_url parameter must be sent in both the Authorize and Access steps described below, and the parameter value must be the same for both steps - otherwise, you will encounter a bad_redirect_uri error:

  • Authorize: You direct the user to the corresponding /oauth/v2/authorize path (this can be done with a link or button, for example). Send the redirect_uri in this step.
  • Redirect: Flock redirects the user to what was specified as the redirect_uri in the previous step, and adds a verification code to that URL.
  • Access: Your server retrieves the authorization code from the previous step and sends it to the token API endpoint to exchange that code for a user access token. If you sent a redirect_uri field in the first step, you must send that same field with the same value in this step.

If you sent more than one redirect_uri when registering your Flock app, but no redirect_uri parameter is sent, the OAuth flow will use the first redirect_uri from the list your sent. You can use the redirect_uri parameter in your oauth/v2/authorize redirect as mentioned above.

There are other important parameters to provider in this link explained below:

Parameters:

  • response_type: Always code for this flow
  • client_id: Your Flock app Client ID.
  • redirect_uri: Your registered callback URL (e.g., https://yourapp.com/callback).
  • scope: Space-separated permissions (e.g., openid offline_access custom-hotlist:write).
    • Include offline_access to receive a refresh token
  • audience: com.flocksafety.integrations (or com.flocksafety.integrations.dev for Sandbox).
  • state: A random string you generate to prevent CSRF attacks.

Example URL with all those parameters:

https://login.flocksafety.com/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
scope=openid offline_access custom-hotlist:write&
audience=YOUR_API_AUDIENCE&
state=RANDOM_STATE_VALUE

2. Waiting for a user to approve your requested scopes

Good news! Your app doesn't really have to do anything.

Prepare for the return of a user by listening for HTTP requests at whatever redirect_uri you specified when registering your Flock app.

3. Exchanging a temporary authorization code for an access token

If all goes well, a user goes through the Flock app installation and okays your app with all the scopes it requests. Then, Flock redirects the user back to your specified redirect_uri.

Parse the HTTP request that lands at your redirect_uri for a code field. That's your temporary authorization code, which expires after ten minutes.

Example:

https://yourapp.com/callback?code=AUTH_CODE_HERE&state=xyz123random
📘

Security Check: Verify the state parameter if you sent one along with your initial user redirect. If it doesn't match what you sent, consider the authorization a forgery.

Now, you just need to exchange the authorization code for a user access token.

Make a POST request to the token endpoint (https:/login.flocksafety.com/oauth/token):

curl -X POST https://login.flocksafety.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
  "grant_type": "authorization_code",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "code": "AUTH_CODE_FROM_STEP_2",
  "redirect_uri": "https://yourapp.com/callback"
	}'

Once you complete your access call, Slack sends you an HTTP request response containing an access token. It looks something like this:

{
  "access_token": "eyJhbGc...",
  "refresh_token": "v1.MRr...",
  "id_token": "eyJhbGc...",
  "token_type": "Bearer",
  "expires_in": 1800
}

One more suggestion: show the user a nice message once they are redirected and you successfully gain an access token - or, if there's been an error, report that error to the user. The reason the user is redirected back to your app at the end of OAuth is for transparency purposes: the user deserves to know the end of the story, whether your app was installed successfully or not.

More about tokens

Using tokens

The best way to communicate your access tokens - also known as bearer tokens - to Flock is by presenting them in a request's Authorization HTTP header where the full value, including "Bearer", is case-sensitive. This approach is required when using application/json with a write method.

curl -X POST https://api.flocksafety.com/api/v3/reads/search \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "your_search_params"}'

Refreshing Tokens

User Access Tokens expire after 30 minutes. Use the refresh_token (valid for 12 hours) to get a new access token.

Best Practice: Proactively refresh your access token before it expires (e.g., after 25 minutes) to avoid service interruptions.

{
  "access_token": "eyJhbGc...",
  "refresh_token": "v1.New...",
  "token_type": "Bearer"
}

OpenID Connect Libraries

To help you integrate with Flock Safety's authentication system, here are recommended OpenID Connect libraries for popular programming languages:

Token Structure

Flock Safety access tokens include custom claims:

  • Note that https://flocksafety.com/external_id refers to a user's unique external ID
  • <YOUR_AUDIENCE> will differ based on your application
{
  "https://flocksafety.com/external_id": "24e07116-4ce4-4e76-b19c-61a80c430960", 
  "https://flocksafety.com/organization_id": "cd8d9c47-cf0d-4c24-9fdd-4bbdf9f54086",
  "https://flocksafety.com/timezone": "US/Eastern",
  "https://flocksafety.com/vendor_id": "2c0ff6d6-c2ca-40ae-8828-127fc38e5c3b", 
  "https://flocksafety.com/is_user": true,
  "iss": "https://login.flocksafety.com",
  "scope": "openid lpr-alerts:subscribe lpr-alerts:subscribe.image-urls lpr-devices:read",
  "aud": "<YOUR_AUDIENCE>",
  "iat": 1763758772,
  "exp": 1763760572,
  "azp": "<SOME_CLIENT_ID>"
}

Errors

Below are some errors you may encounter and reasons for encountering them:

  • bad_redirect_uri: Occurs when there are multiple redirect_uri parameter values configured and they do not match.
  • invalid_scope: Occurs if requesting a non-existent scope or requesting a set of scopes that are in conflict with each other.

Support & Resources