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:
Recover tickets across browsers
Tickets are tied to the browser's widget session ID, so switching browsers or clearing storage means losing access. You can recover tickets by requesting a recovery link via email.
Request a recovery link
This sends an email containing a recovery link to the provided address. The link includes a ph_conv_restore token as a query parameter and expires after one hour.
Parameters:
email(string) - The email address used in previous conversations
The method is rate limited. If you send too many requests, it throws an error with a 429 status.
Restore tickets from a recovery link
Reads the ph_conv_restore query parameter from the current URL and migrates the associated tickets to the current browser session. After processing, the query parameter is removed from the URL.
Response:
The default widget calls restoreFromUrlToken() automatically on load, so you only need to call this yourself if you're building a custom UI.
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() |
Workflow trigger events
In addition to the widget events above, the following server-side events are captured when ticket or message state changes. These events can be used as workflow triggers to automate support processes.
| Event | Description | Properties |
|---|---|---|
$conversation_ticket_created | A new support ticket was created | — |
$conversation_ticket_status_changed | Ticket status was updated | old_status, new_status |
$conversation_ticket_priority_changed | Ticket priority was updated | old_priority, new_priority |
$conversation_ticket_assigned | Ticket was assigned to a team member or AI | assignee_type, assignee_id |
$conversation_message_sent | Team member sent a message on a ticket | message_id, message_content, author_type, author_id |
$conversation_message_received | Customer sent a message on a ticket | message_id, message_content, author_type, customer_name, customer_email |
All workflow trigger events include these base properties: ticket_id, ticket_number, channel_source, status, and priority.
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 |
requestRestoreLink(email) | Send a recovery email to restore tickets | Promise<void> |
restoreFromUrlToken() | Restore tickets from URL recovery token | Promise<RestoreResult \| null> |