JavaScript API reference
Contents
Product Tours is currently in private alpha. Share your thoughts and we'll reach out with early access.
Currently only available on the web. Requires posthog-js >= v1.324.0.
The JavaScript API at posthog.conversations gives you full programmatic control over support conversations. Use it to build custom support interfaces or integrate support into your existing UI.
Checking availability
Before using the API, check if conversations are available:
isAvailable() returns true when:
- Conversations are enabled in your project settings
- The conversations module has loaded successfully
Sending messages
Parameters:
message(string) - The message text to senduserTraits(optional) - Object withnameand/oremailfor user identificationnewTicket(optional, boolean) - Iftrue, creates a new ticket even if one exists
Response:
Fetching messages
Response:
Marking messages as read
Response:
Fetching tickets
Parameters:
Response:
Getting current context
The widget session ID is a persistent UUID that:
- Stays the same across page loads and browser sessions
- Is used for access control (only this browser can access its tickets)
- Survives user identification changes (
posthog.identify())
User identification
Conversations work with both anonymous and identified users.
Anonymous users
Messages are associated with the widget session ID. The user maintains access to their conversation across page loads.
Identified users
When you call posthog.identify(), the conversation seamlessly continues:
- Widget session ID remains the same (user keeps access)
- Backend links the ticket to the identified Person
- User traits from PostHog are used if not provided in
sendMessage()
User traits priority
When sending messages, user traits are resolved in this order:
- Explicitly provided in
sendMessage(message, { name, email }) - PostHog person properties (
$name,$email,name,email) - Previously saved traits from the identification form
Building a custom chat UI
You can build a completely custom chat UI using the API while disabling the default widget:
Events captured
The conversations module automatically captures these events:
| Event | Description |
|---|---|
$conversations_loaded | Conversations API initialized |
$conversations_widget_loaded | Widget UI rendered |
$conversations_message_sent | User sent a message |
$conversations_widget_state_changed | Widget opened/closed |
$conversations_user_identified | User submitted identification form |
$conversations_identity_changed | User called posthog.identify() |
These events integrate with the rest of PostHog – use them in funnels, cohorts, or to trigger other actions.
Persistence
The SDK persists the following data in localStorage:
- Widget session ID (for access control)
- Current ticket ID (to continue conversations)
- Widget state (open/closed)
- User traits (name/email from identification form)
This data is cleared when:
posthog.reset()is called- The user clears browser storage
Error handling
API methods return null if conversations are not available yet. Always check availability or handle null returns:
API calls may also throw errors for:
- Network failures
- Rate limiting (429 status)
- Invalid ticket IDs
- Server errors
API reference summary
| Method | Description | Returns |
|---|---|---|
isAvailable() | Check if conversations API is ready | boolean |
isVisible() | Check if widget is rendered | boolean |
show() | Show/render the widget | void |
hide() | Hide/remove the widget | void |
sendMessage(message, userTraits?, newTicket?) | Send a message | Promise<SendMessageResponse \| null> |
getMessages(ticketId?, after?) | Fetch messages | Promise<GetMessagesResponse \| null> |
markAsRead(ticketId?) | Mark messages as read | Promise<MarkAsReadResponse \| null> |
getTickets(options?) | Fetch tickets list | Promise<GetTicketsResponse \| null> |
getCurrentTicketId() | Get current ticket ID | string \| null |
getWidgetSessionId() | Get widget session ID | string \| null |