Contact Identity Verification (Pre-Authentication)
Pre-authentication lets you automatically sign in your logged-in users to the live chat widget, so they don't have to enter their name and email manually.
How it works
- Your server calls the Herodesk API to generate a secure hash for the contact
- Your frontend passes the hash (along with the contact's details) to the chat widget
- The widget verifies the token and signs the contact in automatically
Step 1: Generate the Hash (Server-Side)
Make a GET request to the Herodesk API from your backend:
GET https://api.herodesk.io/v1/contacts/chat-auth-token?email=john@example.com
Authorization: Bearer YOUR_API_KEY
Note: See https://api.herodesk.io/#/Contacts/contacts_chat_auth_token for API details.
Response:
{
"contact_id": 123,
"email": "john@example.com",
"name": "John Doe",
"auth_token": "a1b2c3d4e5f6..."
}
You can also look up by id instead of email:
GET https://api.herodesk.io/v1/contacts/chat-auth-token?id=123
Authorization: Bearer YOUR_API_KEY
**Important:** Never expose your API key on the frontend. Always generate the auth token on your server.
Performance: Sessison Caching
The widget automatically caches the contact's identity in browser cookies after the first successful identification. On subsequent page loads (or SPA navigations), if the same email is passed via boot, the widget skips the identify API call entirely and uses the cached session.
How It Works
- First visit: API is called → cookies are set
- Subsequent visits: Email hash is compared with cached hash → API call is skipped
Cookie Storage
- herodesk_contact_identified - Hashed email fingerprint (365 days)
- herodesk-chat-contact_uuid - Contact UUID (365 days)
- herodesk_contact_verified - Verification token (365 days)
When API Calls Are Made
1. ✅ First visit (no cookies)
The contact visits for the first time (no cached session)
2. ✅ Email changed (stale cookies cleared)
The email address changes between page loads (stale cookies are cleared automatically)
3. ✅ Cookies expired (browser cleanup)
The cookies have expired or been cleared by the browser
4. ❌ Same email within cookie lifetime → No API Call
Note: This means you can safely call Herodesk('boot', {...}) on every page without worrying about redundant API requests or performance impact.
Javascript API Methods
The Herodesk function provides methods to control the widget programmatically and listen to events. Call these after the widget script has loaded.
State Properties
The Herodesk object exposes read-only state properties that reflect the current widget status:
| Property | Type | Description |
|---|---|---|
| Herodesk.isBooted | Bool | true after boot command is processed with valid parameters |
| Herodesk.isReady | Bool | true when the widget is fully loaded and ready to accept commands |
| Herodesk.isVisible | Bool | True when the chat panel is open, false when closed |
Example:
// Check if the widget is ready before showing
if (Herodesk.isReady && !Herodesk.isVisible) {
Herodesk('show');
}
Note: State properties are updated automatically. isVisible syncs with both programmatic calls (show/hide) and user interactions (clicking the launcher icon or close button).
Herodesk('boot', {});
Use the global Herodesk function to boot the widget with the contact's details. Place this before the Herodesk chat script loads:
<script>
// Queue stub — must be placed before the widget script
// Why do we use Queue stub ? Because the widget never goes through a "first anonymous,
// then identified" transition. It starts with the correct identity from the very first frame.
window.Herodesk = window.Herodesk || function() {
(window.Herodesk.q = window.Herodesk.q || []).push(arguments);
};
// Boot with contact details and auth token from Step 1
Herodesk('boot', {
email: "john@example.com",
firstname: "John",
lastname: "Doe",
auth_token: "a1b2c3d4e5f6..." // auth_token from Step 1
});
</script>
<!-- Load the Herodesk chat widget AFTER setting HerodeskSettings -->
<script src="https://cdn.herodesk.io/livechat.js?wid=YOUR_WIDGET_ID"></script>
Boot Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| String | Yes | Contact's email address | |
| firstname | String | No | Contact's first name |
| lastname | String | No | Contact's last name |
| auth_token | String | No* | HMAC-SHA256 auth token from the API (see above) |
| message | String | No | Pre-fill the chat input with a message |
| language | String | No | Overrides language from visitors browser. Set to fx: da-DK |
| z_index | String | No | Custom z-index for the widget iframe (default: auto) |
* If auth_token is omitted or invalid, the contact will not be verified automatically. They will go through the standard email verification flow instead.
Pre-filling a Message
You can pre-fill the chat input field with pre-authentication:
<script src="https://cdn.herodesk.io/livechat.js?wid=YOUR_WIDGET_ID"></script>
<script>
Herodesk('boot', {
email: "john@example.com",
firstname: "John",
auth_token: "a1b2c3d4e5f6...",
message: "I need help with order #12345"
});
</script>
Custom z-index
<script src="https://cdn.herodesk.io/livechat.js?wid=YOUR_WIDGET_ID"></script>
<script>
Herodesk('boot', {
z_index: 500
});
</script>
Herodesk('show');
Opens the chat widget programmatically.
Herodesk('show');
Herodesk('hide');
Close the chat widget programmatically.
Herodesk('hide');
Herodesk('showConversation', id);
Opens a specific conversation by its ID. The conversation must belong to the current contact.
Herodesk('showConversation', 231);
Note: This method only works after the widget has loaded and the contact has been identified. The conversation ID must belong to the current contact — attempting to open another contact's conversation will be rejected.
Herodesk('setLanguage', language);
Change the language of the live chat after load. This reloads the livechat.
Herodesk('showConversation', 'da-DK');
Herodesk('prefillMessage', message);
Put text into the chat input of an already loaded widget.
Herodesk('prefillMessage', 'How much does shipping cost?');
Herodesk('hideButton');
Hides the live chat launcher button. Use this if you want to build your own custom launcher button (for example to match a dark mode design) instead of showing Herodesk's own button.
Herodesk('hideButton');
Note: This only applies to the current page load — it is not remembered between page loads, and the button does not reappear automatically when a new message arrives. Listen to onUnreadCountChange (see below) if you want to reflect unread messages on your own button.
Herodesk('showButton');
Shows the live chat launcher button again after it has been hidden with hideButton().
Herodesk('showButton');
Herodesk('position', side);
Moves the live chat launcher button, and the chat panel, to the left or right side of the screen. The top/bottom edge stays as configured in your Live chat channel settings — only the left/right side changes.
Herodesk('position', 'left');
You can also nudge the launcher by a pixel offset — for example to clear a cookie banner or another fixed element on your page — by passing an object instead of a plain side string:
Herodesk('position', { side: 'left', x: 24, y: 90 });
| Parameter | Type | Required | Description |
|---|---|---|---|
| side | String | Yes | left or right |
| x | Number | No | Horizontal offset in pixels, added on top of the side placement (default: 0) |
| y | Number | No | Vertical offset in pixels, added on top of the configured top/bottom edge (default: 0) |
Note: The offset only applies together with a side. Calling Herodesk('position', side) again with a plain string clears any offset that was set previously.
Herodesk('openHelpArticle', id);
Opens the widget directly on a specific help center article, by its numeric article ID.
Herodesk('openHelpArticle', 53);
Herodesk('openOnFaq', id);
Opens the widget directly on a specific question from your help center's FAQ section, by its numeric ID — the same way openHelpArticle opens a specific article.
Herodesk('openOnFaq', 12);
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | Number | Yes | The numeric ID of the FAQ question in your help center |
Event Callbacks
Register callbacks to respond to widget events.
Herodesk('onShow', callback);
Fires when the chat widget is opened (by user click or programmatic show).
Herodesk('onShow', function() {
console.log('Chat widget opened');
});
Herodesk('onHide', callback);
Fires when the chat widget is closed (by user click or programmatic hide).
Herodesk('onHide', function() {
console.log('Chat widget closed');
});
Herodesk('onUnreadCountChange', callback);
Fires when the number of unread conversations changes. Receives the new count as a parameter.
Herodesk('onUnreadCountChange', function(count) {
console.log('Unread conversations:', count);
});
Herodesk('onUserEmailSupplied', callback);
Fires when a contact's email is identified — either through pre-authentication (boot with auth_token) or when the user manually enters their email in the widget's contact form.
Herodesk('onUserEmailSupplied', function() {
console.log('User email has been supplied');
});