Step 2: Mint Token

In code, use a library to mint a JWT token as desired.

The Signing Key ID should be provided as the kid in the JWT header. The Signing Key should be used to sign the JWT token.

Depending on the logic you want to enforce, you can include different properties in the JWT claims. You can refer to the property table below for more details on each part of the token you are minting. In the Examples section below we’ll walk through an example with Python and an example with Node.js.

Property Type Details Validation
name string The name of your token. This can be anything, but take note of it as you will need it to configure your Search experience. Required
kid string This is the API key ID of a particular app that has permission to access the desired endpoint. You can find the KeyID in an app in Developer Console in the API Credentials Tab by clicking “Generate Custom Tokens with a Secret Key”. Required
claims object The claims object configures what the token authorizes. You can see there are 3 claims you may want to configure:
  1. aud: Audience is a required claim that is a URL, or array of URLs, specifying which endpoint(s) the token is authorized to call. This must start with /v2/accounts/ and be followed by a specified path up to at least a single endpoint. This should look like /v2/accounts/{businessId}/endpoint/{optionalPath} The businessId can be any businessId or just set to “me” to be the businessId calling the app. The optionalPath is any additional URL path that the token is restricted to, such as a single Stream.
  2. exp: The expiration time of the token in Unix Time conversion found ( here ). If omitted, the token has no expiration.
  3. query: this simply contains additional query params you may want to configure, such as the experienceKey or v param. This can be left empty
Required
scope string A regex that specifies paths in the site. The system will only generate tokens for pages matching the regex of this path. This can improve performance. If not set, the system will generate a token for every page in the site. Optional


Example

For the purposes of this example, let’s assume that a business creates an app with:

Signing Key: a022f72638164ca18b6f92f15d551b99

Signing Key ID: y0M8ZSAVtTS7T8utw-bIOw

The JWT header object for any token created by this app would look like:

{
  "typ": "JWT",
  "alg": "HS256",
  "kid": "y0M8ZSAVtTS7T8utw-bIOw"
}

Which, removing unnecessary whitespace and base64url encoded, gives a JWT header of:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6InkwTThaU0FWdFRTN1Q4dXR3LWJJT3cifQ

Let’s say you want the token to only have access to “MySearchExperience experience” and only be able to make calls to the Search API endpoints .

We’ll also make the token expire at 2021-01-02T03:04:05Z. For the code examples, we’ll make it expire after 1 hour.

The claims object in this case would be:

{
  "aud": "/v2/accounts/me/search", 
  "exp": 1609556645, 
  "query": {
    "experienceKey": "MySearchExperience"
  }
}

Putting it all together, the above header and claims, signed with the API key, yields the full JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InkwTThaU0FWdFRTN1Q4dXR3LWJJT3cifQ.eyJhdWQiOiIvdjIvYWNjb3VudHMvbWUvYW5zd2VycyIsImV4cCI6MTYwOTU1NjY0NSwicXVlcnkiOnsiZXhwZXJpZW5jZUtleSI6Ik15QW5zd2Vyc0V4cGVyaWVuY2UifX0.TiydOR4NwW-MwMV8UGlAgvVmSiFYQiw2gA5ofYdM9Pw

In Python, that JWT can be produced with this code using the popular PyJWT library:

Let’s say you want the token to only have access to “MySearchExperience experience” and only be able to make calls to the PyJWT library :

import jwt
from datetime import datetime, timedelta


token = jwt.encode(
  {
    "aud": "/v2/accounts/me/search",
    "exp": datetime.utcnow() + timedelta(hours=1),
    "query": {
      "experienceKey": "MySearchExperience"
    }
  },
  "a022f72638164ca18b6f92f15d551b99",
  headers={"kid": "y0M8ZSAVtTS7T8utw-bIOw"})

It looks very similar in node.js, using the jsonwebtoken library. That library has convenient syntax for the kid header and exp claim:

var jwt = require('jsonwebtoken');

var token = jwt.sign(
  {
    "aud": "/v2/accounts/me/search",
    "query": {
      "experienceKey": "MySearchExperience"
    }
  },
  "a022f72638164ca18b6f92f15d551b99",
  {keyid: "y0M8ZSAVtTS7T8utw-bIOw", expiresIn: "1h"});