Back to top

Javascript API Reference

By using the Javascript API, you can integrate our Co-browsing technology into your own application or build a thin layer around our technology.


1. Load Surfly widget

To use the Surfly JS API, you will first need to include our snippet on the webpages you want to be able to start co-browsing from:


This snippet loads the necessary Surfly JS libraries. Once it is there, the Surfly.init() function will be immediately available. Note that it is on you to make sure that you don’t make any other API calls until readyCallback is called.

Note: we advise against loading Surfly through a tag manager, since tag managers come with certain limitations. If your users have an ad blocker installed, you run the risk that it will block the tag manager also. This is a side effect of ad blockers, as many of them block the loading of scripts from third parties. This means that these ad blockers would block all Javascript loaded through the tag manager, not just Surfly’s. Therefore, it is advisable to add any code snippet to the website directly.

2. Initialize the API

Surfly.init( settings Object, [ readyCallback Function ] )

This function must be called (just once per page) before any other API call is made. This initializes the environment for Surfly, the settings based on settings object, it tests required browser features, and passes the result to the readyCallback function.

The best practice is to call Surfly.init() immediately after the snippet code. It doesn’t slow down the page load, so it can even be placed in the <head> section of your HTML.

Note: The settings object should contain at least your widget_key. Surfly can be used without a widget key, but this will require use of the REST API and functionality will be restricted.

You can also customize the confirmation pop up body (when confirm_session_start is set to true a pop up is shown to the user before starting the session) by passing confirmation_modal_body argument to the settings object. The value of this argument should be a string.

We load the Surfly widget code asynchronously, so that it doesn’t slow down your page load. This also means that the Surfly API is not initialized immediately after the snippet code is executed. That’s why it is important that you always start by calling Surfly.init(), and don’t make any other API calls before readyCallback is called.

Please refer to our examples to see how the API should be initialized.

3. Implement a callback function

readyCallback should be a function accepting one argument with the following structure:

  "success": true|false,
  "errorMsg": "<error message or null if no error occured>"

In addition to success check, you probably want to detect if the page is currently loaded under Surfly session by checking if Surfly.currentSession exists.

4. Add your domain to the list

Log into your Surfly account. On your dashboard, go to “Settings” >> “Options” >> “General session settings” and add the domains you want to integrate Surfly on to the “Domain list”. Use the following format: "*" or “*” (for subdomains).


The following example initializes Surfly JS API and adds a Surfly button on the page:


  var settings = {
    widget_key:'**your widget key here**',
    only_embedded_sessions: true
  Surfly.init(settings, function(initResult) {
    if (initResult.success) {
      console.log('All good for happy cobrowsing!');
      // it is now safe to use API
      if (!Surfly.isInsideSession) {
    } else {
      console.log('Your browser lacks features required by Surfly');

For more examples of common use cases, see the Examples page

The Surfly Object

Before you get started, you might want to freshen up on how. The main thing you would want to keep in mind is that co-browse sessions are opened in an iframe, that lays on top of the original web page. So when we refer to being inside or outside a session, we refer to the Surfly iframe and the original web page respectively.


Surfly.isInsideSession Boolean

Returns true if the current page is loaded within a Surfly session. This makes it possible to change the page behaviour while cobrowsing. Usually used together with currentSession

It allows you to detect whether the current page is loaded under Surfly, and also use the SurflySession API for communication with the outer window, as shown below:

if (Surfly.isInsideSession) {
  Surfly.currentSession.on('message', function (session, event) {
    if (event.origin === window.location.origin) {
      console.log('Outer window says:',;
    } else {
      console.log("Outer window has a different origin");


SurflySession Surfly.currentSession Object

If called from inside a session, this returns a SurflySession object referring to a session we are currently in. Otherwise, it returns null.

Note: the same can be achieved by using Surfly.listSessions()[0]


Surfly.listSessions() Array

Surfly.listSessions().forEach(function(session) {
  console.log('Found a session:', session.followerLink);

Returns a list of SurflySession objects that were created with JS API, or restored after the page reload. Note that by the time the init callback is called, this list can already contain some sessions restored after a page reload.

Inside a session, the return array will contain only one object, representing the currently open session (see Surfly.currentSession).


Surfly Surfly.on( eventName String , callback Function )

Sets a global event handler.

If eventName is a session event, the handler will affect all sessions, including the currently created ones.

callback must be a function. Depending on the type of event, it will be provided with relevant data.

See Events section for more details.

Returns a reference to the Surfly object, so chained calls are possible:

Surfly.on('session_ended', function(session, event) {
  console.log('Session', session.followerLink, 'has just ended');


Surfly.agentAvailable Boolean

Only available after Surfly has successfully been initialized (so after the readyCallback). Contains true if there is at least one company agent online.

// this is how you might hide a custom element depending on
// agent availability
var but = document.getElementById('my-custom-button');
if (!Surfly.agentAvailable) { = 'none';
else { = 'block';

The same can be established by using the agent_status event.

.session( [ sessionSettings Object ], [ sessionUrl String ] )

SurflySession Surfly.session( [ sessionSettings Object ], [ sessionUrl String ] )

Creates a session object with provided settings. Some properties of the returned SurflySession may not be initialized. You can bind callbacks using .on() method to hook on specific points of session lifetime. Note that you will need to call .create() or .startLeader() / .startFollower() methods to actually create a session and open a cobrowsing window respectively.

sessionSettings: (optional) session settings object

sessionUrl: (optional) URL string with leader or follower session link. If specified, Surfly will not create a new session, and will just open the provided session link instead. This is useful, for example, when a session has been created beforehand using the REST API.

Surfly.init({widget_key: '**your key here**'}, function(init) {
  if (init.success) {
      Surfly.session({docked_only: true}).startLeader();

.button( [ settingsObject ] )

Surfly.button( [ settingsObject ] )

Adds a Surfly button to the current page. When a user clicks the Surfly Button, it will create a new Surfly session, and open a leader window. The Surfly button will automatically hide itself under the Surfly session, or if there is no support agent online (unless autohide_button is set to false).

settingsObject: here you can set settings that will be applied to all sessions created with this button. If there is a conflict, settings provided here will override the ones passed to Surfly.init().

Inside a session, there is no need to create a session, so Surfly.button() calls will be silently ignored.

The Surfly button is just a shortcut for a quick integration, and doesn’t allow for much customization. For more fine-grained integration, use SurflySession API.

Surfly.init({widget_key: '**your key here**'}, function(init){
  if (init.success) {
    Surfly.button({autohide_button: false, position: 'bottomleft'});


Surfly Sessions

The Javascript API provides a set of functions allowing you to start and control the behaviour of your Surfly sessions.

Once a session has been initialized, you’ll be able to use several events in order to check the session status and, if necessary, make modifications depending on this status. More information on how to handle events can be found on the session events page.

Starting sessions

SurflySession SurflySession.startLeader( [ iframeSelector String ], [ userData Object ] )

SurflySession SurflySession.startFollower( [ iframeSelector String ], [ userData Object ] )

(not available inside a session)

Initialize a cobrowsing session, opening a new iframe/browser tab if necessary. Adds the session to the support queue.

iframeSelector - (optional) CSS selector string to an iframe element on the current page. If specified, Surfly will open a session in this iframe instead of creating a new one. Note that Surfly cannot open a session in an iframe when 3rd-party cookies are disabled. Also, this is not compatible with the open_in_new_window option.

userData - (optional) a plain object with additional data to be attached to the joining user. This will be visible in subsequent user-related events (viewer_joined, for example), and can be used to track users when they join or leave the session. You are free to specify any type of data you want to pass to the method. Surfly offers three special fields that have additional effects:

  • name: this will be displayed as a user name in the Surfly chatbox inside a session

  • email: this will be used for Gravatar lookup

  • agent_id: will pin the (unpinned) session to a specific Agent. Agent must belong to the company owning the widget key that was used for creating the session.

userData from .startLeader() call will be visible on the Queue page in Surfly dashboard, so you can easily distinguish between the users in the queue.


var session = Surfly.session().startLeader();
// now send `session.followerLink` to someone else

// in another browser
Surfly.session({}, followerLink)
      .startFollower(null, {name: 'John Doe', foo: 'bar'});


SurflySession SurflySession.create()

(not available inside a session)

Just initialize a new session (retrieve a leader and follower links from Surfly server) without opening a cobrowsing window. In most cases there is no need to call this function explicitly. It will be called automatically from SurflySession.startLeader() and SurflySession.startFollower().

Note that you still must call SurflySession.startLeader() or SurflySession.startFollower() at some point, to open a cobrowsing window.

If the session is already initialized, SurflySession.create() does nothing.

SurflySession.end( [ redirectUrl String ] )

SurflySession SurflySession.end( [ redirectUrl String ] )

Gracefully ends the current session (as long as the current user has permissions to do so).

If specified, redirectUrl should be a valid URL string. The user will be redirected there after the session ends. The exception is when end_of_session_popup_url settings is set. In this case, it will have priority over redirectUrl.

Note that by default a user is redirected to the page that was last visited inside the session.


SurflySession.settings Object

(read only, not available inside a session)

Returns the session settings with which the session was created

SurflySession.on( eventName String , callback Function )

SurflySession SurflySession.on( eventName String, callback Function )

Use this to set an event handler. Inside the callback function, this will be set to the current SurflySession instance. See Events section for more details.

Returns a reference to the current SurflySession, so chained calls are possible:


SurflySession.log( entry Object )

SurflySession SurflySession.log( entry Object )

Log custom message to the audit log. entry must be a plain JSON object. Can be used to track your user’s steps during co-browsing. Handy for metrics and reveiling pain points on your website. The entry object can contain arbitrary keys, but there are several reserved keys with special meaning:

  • varN (where N is a number from 0 to 9): when provided, must have a String value. These variables can be referenced and used in visualization later on.

SurflySession.sendMessage( message Object, targetOrigin String )

SurflySession.sendMessage( message Object, targetOrigin String )

This function is useful when you need to establish a communication channel between your JS code on the original page, and its proxified version inside the session.

It is available on both sides, and works in symmetric way: it will trigger a message event on the other side of the channel (see Events section).

message argument must be a plain JSON-serializable object. targetOriginshould be set to the origin of the expected recipient. If set to "*", message will be delivered regardless of the recipient’s origin.

if (!Surfly.isInsideSession) {
      // From outside a co-browsing window, send a message to the co-browsing window
      var endBtn = document.getElementById('btn-end-queued-session');
      endBtn.addEventListener('click', function() {
        Surfly.listAllSessions[0].sendMessage({message: 'end'}, window.location.origin);
    else {
    // Check the cobrowsing session and set the message event listener
      .on('message', function(session, event) {
        if ( === 'end') {
          // reply to the message

SurflySession.giveControl( clientIndex Integer )

SurflySession.giveControl( clientIndex Integer )

(not available inside a session)

Switch control to the user with specified clientIndex. clientIndex is always 0 for the leader and 1 or more for followers.

See also Control options



(not available inside a session)

Request control from the session leader. This call will be silently ignored if the user is already in control, if she is a leader, or if one of agent_can_request_control and allow_control_switching options is disabled.

SurflySession.relocate( newUrl String )

SurflySession.relocate( newUrl String, newTab Boolean )

(not available inside a session)

Navigate current tab to newUrl, which must begin with a protocol, such as https://. If newTab is set to true, the link will open a new virtual tab inside the session window.



(not available inside a session)

When called from the leader side, pause streaming content to other participants



(not available inside a session)

Resume a session previously paused with pause()

[DEPRECATED] SurflySession.resize( [ width Number ], [ height Number ] )


(not available inside a session)

This method is DEPRECATED and is ignored in Surfly v2.47 and newer. The viewport size is detected automatically inside iframes.

Set the size of the underlying session frame window to specified dimensions. Useful when the session is started with a custom frameSelector. Note that if you start a session without a custom selector, this function is called automatically every time you resize the browser window.

If width and height are omitted, the size of current browser window will be used.

session.setDrawingSettings({enabled: 'false', userIndex: 0});

Disables the leader’s pen.

session.setDrawingSettings({timeout: 30, color: 'magenta'});

Sets everyone’s pen color to magenta, and erases lines 30 seconds after they’re drawn.

Surfly.listSessions()[0].setDrawingSettings({enabled: true, userIndex: 0})
Surfly.listSessions()[0].setDrawingSettings({enabled: false, userIndex: 0})

Toggles between leader’s (userIndex: 0) cursor and drawing mode



(not available inside a session)

Toggles videochat fullscreen mode



(not available inside a session)

Mutes/unmutes your microphone


SurflySession.started Boolean

(not available inside a session)

boolean, set to true if the session window is opened

SurflySession.leaderLink String

(not available inside a session)

contains a leader link. This is a URL that SurflySession.startLeader() opens. It can only be opened in one browser at a time.

SurflySession.followerLink String

(not available inside a session)

contains a URL that can be used for joining the session. This is a URL that SurflySession.startFollower() opens. String

contains a 4-digit PIN code that can be used to join the session. This becomes available only after the session is started (either manually by .startLeader() call, or automatically by Surfly Button).


SurflySession.node HTMLIFrameElement

(not available inside a session)

if a session is opened in an iframe, it contains a reference to its DOM node


SurflySession.window Window

(not available inside a session)

reference to the session window (either tab window or contentWindow of the iframe container)


Surfly JS API dispatches a number of events that you can listen to and attach custom handler functions using Surfly.on() and SurflySession.on(). Callback functions are provided with arguments, depending on the event type.

Global Events

Global events can be registered with Surfly.on() method. Global event handlers will be provided with 2 arguments: - a reference to the global Surfly object - JSON object with event attributes

// this will be triggered for all sessions, including the restored ones
Surfly.on('agent_status', function(api, event) {
  if (event.available) {
    console.log('There is an available support agent');
  } else {
    console.log('There is no support agents available at the moment');


triggered when a support agent availability changes. Parameters:

  • available is set to true if a support agent has just become available, and false if all agents have become unavailable.


(not available inside a session)

triggered when a SurflySession object is recreated after a page refresh. This happens only when auto_restore option is on.

Session Events

Session event handlers can be set with the SurflySession.on() method, or with the global Surfly.on() method. The latter will affect all existing and future sessions.

Callback functions should accept two arguments: - SurflySession instance that triggered the event - JSON object with event attributes

// this will be triggered for all sessions, including the restored ones
Surfly.on('session_ended', function(session) {
  console.log(session, 'has ended');

function startCobrowsing () {
  Surfly.session({docked_only: true})
    // these handlers will only be called for this particular session
    .on('session_started', function(session) {
      console.log(session, 'is fully initiated');
    .on('viewer_joined', function(session, event) {
      console.log('There are', event.count, 'users in total');

Available session events:


triggered when a session is created (usually after SurflySession.create() call).

session_queued (Deprecated: use session_created event instead) triggered when the session has been placed in the waiting queue, and the PIN code is generated


triggered when a session window has been loaded (usually after a call to SurflySession.startLeader()). Has no additional parameters.


triggered when the DOM inside the session has been fully loaded. Has no additional parameters.


triggered when a follower joins the session. Parameters:

  • count updated number of users in the session

  • clientIndex index of the user. Can be used in subsequent SurflySession.giveControl() calls

  • userData data provided in userData argument of SurflySession.start*() call


triggered when a follower leaves the session. Parameters:

  • count updated number of followers in the session

  • clientIndex index of the user

  • userData data provided in userData argument of SurflySession.start*() call


triggered when the session has been properly finished (normally after clicking the close button, or as a result of SurflySession.end() call). Parameters:

  • final_location On the leader side, URL of the last co-browsed page


triggered when the message is received. Parameters:

  • data message object sent from the other side

  • origin the origin of the sender window


triggered when master clicks, moves mouse, or presses any key. Triggered once per second if activity is present.


(not available inside a session)

triggered when the current tab inside a Surfly session starts loading a new page. In conjunction with the relocated event, it allows you to track page loading inside a cobrowsing session. For example, use it to show a custom loading indicator. Parameters:

  • url absolute URL loading webpage


(not available inside a session)

triggered when the current tab inside a Surfly session navigates to another page. Parameters:

  • url absolute URL of new location


(not available inside a session)

triggered on common errors. Parameters:

  • reason error description. Currently may be one of the following:

    • "other_connection" the leader_link was opened elsewhere. The new window/browser becomes the leader and the old leader is kicked out. It also happens if follower_link was open twice in the same browser
    • "connect_failed" The WebSocket connection to Surfly cannot be established
    • "create_failed" Surfly session could not be created. Check the details attribute of the event object for more information about the error
    • "start_failed" Surfly session could not be started. Check the details attribute of the event object for more information about the error


triggered when control over the session has been transferred. Parameters:

  • to index of the client that now has the control. Always 0 for the leader, 1 or more for a viewer

  • gained set to true if control was given to the current user

  • myIndex contains the user index of the current user


triggered when a file download occurs inside the session. Note that this event is only fired when the user is controlling the session. This JS event is fired regardless of the share_downloads session option. Parameters:

  • url direct link to the downloaded file. File will be available until the end of the session.

  • filename name of the downloaded file


(Supported only on the leader side)

triggered when a user tries to end the session using the “✕” button in the session UI. This can be used, for example, for storing the state of your page before ending a session. Note that this event is not fired if you end a session using JS API or REST API. WARNING: if you attach a listener for this event, you MUST eventually call SurflySession.end(), otherwise the session will not be ended. Parameters:

  • final_location contains the URL of the last co-browsed page


(Supported only on the leader side)

triggered when a session is paused by the leader. See also session_resumed event and the documentation on allow_pause session option.


(Supported only on the leader side)

triggered when a session is resumed after a pause. See also session_paused event and the documentation on allow_pause session option.


Surfly uses CSS classes to change the appearance of DOM elements it handles. You can easily customize the look-and-feel of those elements by overriding the CSS rules for these classes.

For more complex customizations, consider providing your own DOM element to startLeader() and startFollower() functions.

Surfly Button

The Surfly button element created with the Surfly.button() function will have surfly-button class assigned. We recommend creating a custom button for more complex style changes.

Session iframe

If the session is opened in an iframe, we will also set a CSS class on a corresponding <iframe> element.


set on Surfly session iframe element.

Generated by aglio on 26 Sep 2022