Configure Signed Link SSO
This guide walks you through the steps to configured Signed Link SSO.


Before utilizing Signed Link Single Sign-On, you must complete the following steps:

Step 1: Make sure users are set up correctly

  1. Create users in Yext. To add users via the platform, see Add a new user, or Add users in bulk. To do this via the API, visit Users: Create endpoint.
  2. Take note of the ID (id in the Users: List endpoint of the Knowledge API) of the User that you create. You will need this ID when generating the Signed Single Sign-On Link.
    • For most clients, the roleId is typically 9 or 20, Account Manager. You can also follow the steps in the Manage Users Guide to retrieve Available Roles.
    • NOTE: if you have a 1:1 relationship between user and location or account, then the user ID should be equal to the location ID or account ID.

Step 2: Make sure your account has been configured to use Signed Link SSO

  • Your account needs to be configured by Yext Technical Operations to use the Signed Link Single Sign-On option. Please email, with your Account Manager copied, to enable this for your account.
  • Yext will provide you with a secret code (secret) that you will use to sign login requests, as described in the next section.

Create a Client Login Link

There are two main steps to providing login links to your users:
  1. Generating a set of required values
  2. Creating the login link based on those values

Step 1: Generating a Set of Required Values

In your existing dashboard, you must include a link or button that logs the user in to Yext. When a user clicks this link or button, the system should generate the following four values:
  • accountid
    • Your account ID with Yext. This value remains the same for every login link you create.
    • Example: 78369
  • code
    • The user ID for the customer who should be logged in.
    • Example: 567A83
  • timestamp
    • The current time, in seconds, since the epoch
    • Example: 1331847978
  • sign
    • The signature (sign) should be the SHA-1 hash of “accountid | code | timestamp | secret“, hexlified (i.e., converted to a string where each byte is represented by two hex digits). This signature will be valid for 60 seconds on either side of the time in timestamp, but servers should be kept relatively on time. The signature must be generated on the server, which will need to keep track of the secret value. The signature should always be lowercase.
    • Example: ffba83a33623398b051d675060745ea3f48a1e4d

Optional values

  • useSha256
    • This is an optional parameter that allows for the use of SHA-256 hash when generating the signature (sign). SHA-256 works the same way as SHA-1 but is stronger and more secure.
    • Example: true or false, if the parameter is not present the system will automatically default the value to false
  • embed
    • This is an optional parameter that can hide the top navigation bar or the top navigation bar and sub navigation bar depending on the value provided
    • Example: nosubnav, true, or false. nosubnav will hide both the top and sub navigation bars. true will hide the top navigation bar. false will show both navigation bars. If the parameter is not present the system will automatically default the value to true.
  • nav
    • This is an optional parameter that allows you to deep link to certain sections of the Yext dashboard
    • Accepted Values:
      • locations deep links to /locations. If a nav parameter is not provided, Yext will default to locations.
      • activitylog deep links to /reports/activity
      • answersExperiences deep links to /answers/experiences/configuration
      • answersOverview deep links to /answers/overview
      • apps deep links to /apps
      • bios deep links to /bios/all
      • consumerfeedback deep links to /consumerfeedback/invites
      • duplicates deep links to /duplicates
      • events deep links to /events/all
      • facebooklistings deep links to /listings and filters to Facebook
      • googlefacebooklistings deep links to /listings and filters to Facebook & Google My Business
      • googlelistings deep links to /listings and filters to Google My Business
      • home deep links to /home
      • insights deep links to /reports/insightsDashboard
      • intelligentSearchTracker deep links to /reports/intelligentSearchTracker
      • listings deep links to /listings
      • listingsOverview deep links to /listings/overview
      • menus deep links to /menus/all
      • notificationSettings deep links to /notifications/settings
      • pagesKnowledgeTags deep links to /schema/js
      • pagesOverview deep links to /storepages/overview
      • personalSettings deep links to /user/personalSettings
      • posts deep links to /social/post
      • products deep links to /products/all
      • questions deep links to /questions
      • reports deep links to /reports
      • reviews deep links to /reviews
      • reviewOverview deep links to /reviews/overview
      • reviewResponseSettings deep links to /account/reviews/response
      • reviewsApprovals deep links to /consumerfeedback/approvals
      • reviewsInsights deep links to /reviews/insights
      • reviewsResponse deep links to /reviews/response
      • reviewsSentiment deep links to /reviews/sentiment
      • suggestions deep links to /suggestions
      • ugc deep links to /social/usergeneratedcontent
      • ugcGmb deep links to /social/usergeneratedcontent/gmb
      • widgets deep links to /w
Below are three reference implementations for generating the signature: one in Python, one in Java, and one in C#:

import hashlib
import time

def sessionUrl(accountid, code, timestamp, secret, nav, embed):
	messageDigest = hashlib.sha256()
	message = "{0:d}|{1:s}|{2:d}|{3:s}".format(accountid, code, timestamp, secret)
	signature = messageDigest.hexdigest()
	url = "{0:d}&code={1:s}&timestamp={2:d}&sign={3:s}&useSha256=true"
	url = url.format(accountid, code, timestamp, signature)
	navParam = ""
	embedParam = ""
	if nav is not None and nav != "":
		navParam = "&nav=" + nav
	if embed is not None and embed != "":
		embedParam = "&embed=" + embed
	return url + navParam + embedParam;

def main():
	accountid = [insert accountid]
	code = [insert code]
	secret  = [insert secret]
	timestamp = int(time.time())
	nav = [insert nav]
	embed = [insert embed]
	print(sessionUrl(accountid, code, timestamp, secret, nav, embed))

if __name__ == '__main__':
private static String sign(
    long accountid, String code, long timestamp, String secret)
    String message = String.format(
        "%d|%s|%d|%s", accountid, code, timestamp, secret);

    MessageDigest md;
    try {
        md = MessageDigest.getInstance("SHA-1");  //"SHA-256" if useSha256 is set to true
    } catch (NoSuchAlgorithmException ex) {
        // SHA-1 is a built-in algorithm and should never be missing.
        throw new RuntimeException(ex);

    byte[] digest;
    try {
        digest = md.digest(message.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException ex) {
        // UTF-8 is a built-in charset and should never be missing.
        throw new RuntimeException(ex);

    StringBuilder result = new StringBuilder();
    for (byte b : digest) {
        result.append(String.format("%02x", b));
    return result.toString();
private static String sign(
    long accountid, String code, long timestamp, String secret)
    String message = String.Format(
        "{0:d}|{1:s}|{2:d}|{3:s}", accountid, code, timestamp, secret);

    HashAlgorithm algorithm = SHA1.Create();

    byte[] digest = algorithm.ComputeHash(Encoding.UTF8.GetBytes(message));

    StringBuilder result = new StringBuilder();
    foreach (byte b in digest)
    return result.ToString();

Step 2: Creating the login link based on those values

  1. After the signature is generated, pass the required values to
If using SHA-256 hashing algorithm:
This “signed” link could open the Yext platform in the same tab as your customer dashboard or in a new tab, depending on the desired experience. Do not generate link upon page load: Because the link includes a timestamp, it should be generated after the user clicks your on-screen link or button to log in to Yext, not when the page is first loaded. Otherwise, the link may have expired by the time the user clicks it.