Signed Link SSO is a single sign-on (SSO) option primarily for partners who want to enable SSO for their customers and iframe the Yext platform. It lets your users access Yext directly from your existing dashboard, using a signed link, without a separate Yext login.
Note: If you use a SAML identity provider such as Okta or Active Directory Federation Services, authenticate via SAML instead. See Configure SAML SSO.
Before you can use Signed Link SSO, complete the setup steps below.
Step 1: Set Up Users
- Create users in Yext.
- To add users through the platform, see Add a New User or Add Users in Bulk.
- To add users through the API, use the Users: Create endpoint.
- To create a custom user role, see Create a Custom User Role.
- Note the ID (
idin the Users: List endpoint of the Management API) for each user you create. You need this ID to generate the Signed Link SSO URL.- For most users, the
roleIdis 9 or 20 (Account Manager). - Note: If you have a 1:1 relationship between user and entity or account, the user ID should match the entity ID or account ID.
- For most users, the
Step 2: Enable Signed Link SSO for Your Account
Your account needs to be explicitly configured by Yext Technical Operations to use Signed Link SSO.
- Your account needs to be explicitly configured by Yext Technical Operations to use the Signed Link Single Sign-On option. Please email help@yext.com with your account team copied to enable this for your account.
- Yext provides a secret code (
secret) that you use to sign login requests, as described below.
Generate the Required Values
When a user clicks the link or button in your dashboard that logs them into Yext, your system must generate four required values:
| Value | Description | Example |
|---|---|---|
accountid |
Your account ID with Yext. This value stays the same for every login link. | 78369 |
code |
The user ID for the customer being logged in. | 567A83 |
timestamp |
The current time, in seconds, since the epoch. | 1331847978 |
sign |
The SHA-1 hash of accountid|code|timestamp|secret, hexlified and lowercase. This signature is valid for 60 seconds on either side of the timestamp value, so keep your servers reasonably in sync. Generate the signature on the server, since it needs access to the secret value. |
ffba83a33623398b051d675060745ea3f48a1e4d |
Optional Values
| Value | Description |
|---|---|
useSha256 |
Enables SHA-256 hashing instead of SHA-1 for a stronger signature. Accepts true or false; defaults to false if omitted. |
embed |
Hides the top navigation bar, the top and sub navigation bars, or neither. Accepts nosubnav (hides both), true (hides the top bar), or false (shows both); defaults to true if omitted. |
nav |
Deep links to a specific section of the Yext dashboard. See the supported values below. |
Supported nav values:
| Nav Value | Link |
|---|---|
activitylog |
reports/activity |
answersExperiences |
search/experiences/configuration |
answersOverview |
search/overview |
apps |
apps/ |
bios |
bios/all |
brandedTerms |
reports/brandedTerms |
calendar |
social/calendar |
comments |
social/inbox |
consumerfeedback |
consumerfeedback/invites |
duplicates |
duplicates |
events |
events/all |
facebooklistings |
listings |
facebookListingsPublisher |
listings/publishers/71 |
generativeReviewResponse |
account/reviews/responsegeneration |
googlefacebooklistings |
listings |
googlelistings |
listings |
googleListingsPublisher |
listings/publishers/250 |
home |
home |
insights |
reports/insightsDashboard |
intelligentSearchTracker |
reports/intelligentSearchTracker |
knowledgegraph |
entities |
listings |
listings |
listingsAll |
listings/all |
listingsOverview |
listings/overview |
listingsPublishers |
listings/publishers |
listingsInsights |
listings/insights |
listingsInsightsVisibility |
listings/insights?tab=1& |
listingsInsightsMap |
listings/insights?tab=2& |
menus |
menus/all |
notificationSettings |
notifications/settings |
pagesKnowledgeTags |
schema/js/ |
pagesOverview |
storepages/overview |
personalSettings |
user/personalSettings |
posts |
social/post |
products |
products/all |
publishersuggestions |
publishersuggestions |
questions |
questions |
reports |
reports/ |
reviewOverview |
reviews/overview |
reviewResponseSettings |
account/reviews/response |
reviews |
reviews |
reviewsApprovals |
consumerfeedback/approvals |
reviewsInsights |
reviews/insights |
reviewsResponse |
reviews/response |
reviewsSentiment |
reviews/sentiment |
searchExperiences |
search/experiences/configuration |
searchOverview |
search/overview |
sendReviewInvites |
consumerfeedback/invites/sendInvites |
sendSingleReviewInvite |
consumerfeedback/invites/singleInvite |
suggestions |
suggestions/ |
tasks |
tasks/inbox |
ugc |
social/usergeneratedcontent |
ugcGmb |
social/usergeneratedcontent/gmb |
widgets |
w/ |
Reference Implementations
Use one of the following reference implementations to generate the signature.
Python
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)
messageDigest.update(message)
signature = messageDigest.hexdigest()
url = "https://www.yext.com/users/corplogin?accountid={0:d}&code={1:s}×tamp={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__':
main()Java
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();
}C#
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)
{
result.Append(b.ToString("x2"));
}
return result.ToString();
}Create the Login Link
After you generate the signature, pass the required values to www.yext.com/users/corplogin.
Example:
https://www.yext.com/users/corplogin?accountid=78369&code=567A83×tamp=1331847978&sign=ffba83a33623398b051d675060745ea3f48a1e4d
Example using SHA-256:
https://www.yext.com/users/corplogin?accountid=78369&code=567A83×tamp=1331847978&sign=ffba83a33623398b051d675060745ea3f48a1e4d&useSha256=true
This signed link can open the Yext platform in the same tab as your customer dashboard or in a new tab, depending on the experience you want.
Note: Don't generate the link on page load. Because the link includes a timestamp, generate it only after the user clicks your on-screen link or button, not when the page first loads. Otherwise, the link may expire before the user clicks it.