Reference sheet · lessons 1, 2, 8
tawk.to JavaScript API
Everything on window.Tawk_API as documented on 2026-10-17, compressed. Widget 4.3.0.
Embed
<script>
var Tawk_API = Tawk_API || {}, Tawk_LoadStart = new Date();
(function(){ var s1 = document.createElement("script"), s0 = document.getElementsByTagName("script")[0];
s1.async = true; s1.src = 'https://embed.tawk.to/PROPERTY_ID/WIDGET_ID'; s1.charset = 'UTF-8'; s1.setAttribute('crossorigin','*');
s0.parentNode.insertBefore(s1, s0); })();
</script>
- IDs: Administration → Overview (Property ID); Channels → Chat Widget (Widget ID, Direct Chat Link). Default widget ID is
default.tawk.to Help: property and widget ID - Call methods only after the embed code has loaded, inside
onLoad.tawk.to JavaScript API reference
Settings (set before the script loads)
| Setting | Shape | Notes |
|---|---|---|
Tawk_API.visitor | { name, email, hash?, phone? } | Read at load; later changes are not sent. Phone in E.164. Use setAttributes for SPA/AJAX logins. |
Tawk_API.autoStart | false | Widget hidden and disconnected until start(). Default true. |
Tawk_API.customStyle | { zIndex: 1000 } | Officially zIndex only; the React wrapper and help centre also document visibility.{desktop,mobile}.{xOffset,yOffset,position}. Default z-index is 2,000,000,000. |
Connection and identity
| Method | Signature | Notes |
|---|---|---|
start | start({ showWidget?: true }) | Opens the socket; shows the widget once connected. |
shutdown | shutdown() | Disconnects the socket. |
switchWidget | switchWidget({ propertyId, widgetId }, cb(error)) | Drops the connection, logs out, switches widget. |
login | login({ hash, userId, name?, email?, phone?, ...custom }, cb(error)) | hash = HMAC-SHA256 of userId with the site API key. Restores the user’s previous conversation; reconnects. Extra keys become custom attributes. |
logout | logout(cb(error)) | No arguments. |
Visitor data and context
| Method | Signature | Limits / errors |
|---|---|---|
setAttributes | setAttributes({ key: value }, cb(error)) | Keys alphanumeric + dash, lower-cased; 50 custom attributes (name, email, hash excluded); values non-empty, ≤ 255 chars; name/email require secure mode + hash. Errors: INVALID_ATTRIBUTES, SESSION_EXPIRED, SERVER_ERROR, ACCESS_ERROR, ATTRIBUTE_LIMIT_EXCEEDED, CONTAINS_INVALID_KEY, CONTAINS_INVALID_VALUE. |
setChatInputMessage | setChatInputMessage(text, cb(error)) | Pre-fills the input “ready for the visitor to review, edit, and send.” Added in widget 4.2.0 (2026-09-22). Does not send. |
addEvent | addEvent(name, metadata?, cb(error)) | Name alphanumeric + dash. Errors: INVALID_EVENT_NAME, plus the attribute errors. |
addTags / removeTags | addTags(['a','b'], cb(error)) | 10 tags total. Errors: INVALID_TAGS, TAG_LIMIT_EXCEEDED, VERSION_CONFLICT, SESSION_EXPIRED, SERVER_ERROR. |
Widget control and state
maximize() · minimize() · toggle() · popup() · showWidget() · hideWidget() · toggleVisibility() · endChat() · getWindowType() → 'inline' | 'embed' · getStatus() → 'online' | 'away' | 'offline' · isChatMaximized() · isChatMinimized() · isChatHidden() · isChatOngoing() · isVisitorEngaged().
Callbacks (assign functions)
| Callback | Receives | Fires when |
|---|---|---|
onBeforeLoad / onLoad | nothing | API usable / widget rendered |
onStatusChange | 'online'|'away'|'offline' | page status changes |
onChatStarted / onChatEnded | nothing | chat starts / ends |
onChatMaximized / onChatMinimized / onChatHidden | nothing | widget state changes |
onPrechatSubmit | form data | pre-chat form submitted |
onOfflineSubmit | { name, email, message, questions[] } | offline form submitted |
onChatMessageVisitor / onChatMessageAgent / onChatMessageSystem | { message?, attachments[] } (object since widget 0.2.0) | a message is sent |
onAgentJoinChat | { name, position, image, id } | agent joins |
onAgentLeaveChat | { name, id } | agent leaves |
onChatSatisfaction | -1 | 0 | 1 | rating given |
onVisitorNameChanged | name | visitor edits their name |
onFileUpload | link | file uploaded |
onTagsUpdated | data | tags change |
onTranscriptRequest | visitor requests an email transcript (widget 4.1.0) |
Most callbacks are “not supported in pop out chat window.” Only in the React wrapper: tawkOnUnreadCountChanged, tawkOnLoaded, tawkOnBeforeLoaded, tawkWidgetPosition, and embedded mode via embedId.tawk-messenger-react API reference
Secure mode
- “The hash is server side generated HMAC using SHA256, the user’s email and your site’s API key.” For
login: userId + key.tawk.to JavaScript API reference Help articles say “user ID” for both: test once against your dashboard. - Key: Administration → Overview → JavaScript API → enable Secure Mode → copy.tawk.to Help: generating a hash
- Node:
createHmac("sha256", key).update(identifier).digest("hex")(seeexamples/src/tawk-secure-mode.ts). - Mismatch: details silently not updated;
loginlogs 401 in the console.
Handoff recipe (lesson 2)
Tawk_API.onLoad = async () => {
const { userId, hash } = await fetch('/api/tawk-identity').then(r => r.json());
Tawk_API.login({ userId, hash }, log);
Tawk_API.setAttributes({ 'bot-last-reason': reason }, log);
Tawk_API.addTags(['bot-handoff'], log);
Tawk_API.addEvent('bot-handoff', { reason }, log);
Tawk_API.setChatInputMessage(summary, log);
Tawk_API.maximize();
};
Official wrappers
@tawk.to/tawk-messenger-react 2.0.2 · @tawk.to/tawk-messenger-vue-3 · @tawk.to/tawk-messenger-vue-2 · @tawk.to/tawk-messenger-angular · @tawk.to/tawk-messenger-ember. Same API, prefixed tawk.tawk-messenger-react (GitHub)
Direct Chat Link
https://tawk.to/chat/{propertyId}/{widgetId}: standalone page, works on mobile, pre-chat form applies, widget must be online, no query parameters.tawk.to Help: Direct Chat Link