---
language: "en"
---
# How can we help?

## [Introduction](https://help.surfly.com/en/introduction.md)

### [Under the Hood](https://help.surfly.com/en/how-surfly-works.md)

### [Getting Started](https://help.surfly.com/en/getting-started.md)

### [Technical Guides](https://help.surfly.com/en/technical-gudies.md)

### [Product Updates](https://help.surfly.com/en/product-updates.md)

### [Need help?](https://help.surfly.com/en/need-help.md)

---
language: "en"
---
# Adding a new Language

We strive to make Surfly available to all users in their native language. If your language is not yet available in Surfly, we'd be more than happy to add it!

First, we'll need some more information about the language, its writing system, and the people who speak it. We use this background information to ensure that contributions in your language will look great in our interface.  
Unfortunately, technical limitations currently prevent us from supporting languages that are written from right to left (RTL).

## To proceed, we will require the following minimum information from you:

* What does the language call itself? What is the English name of the language? Does it have any other names?

* Where is it spoken? Where do the users that will use this language live?

Many languages have regional variants, e.g. South American Portuguese has drifted somewhat from European Portuguese. We'll have to decide whether translations will apply to one region or to the whole language.

* What writing system (alphabet) should we use in Surfly for text in this language?

Some languages use multiple writing systems, so we need to know your preference.

* When should we make your language available to users? If users select the language, any missing translations will appear to them in English. Should users be able to select this language right away? If so, users will see some English-language text until all translations are complete. As more translations are approved, users will see more and more of their chosen language.

Once the language is created, there will be lots of text that doesn't yet have a translation. If users select this language right away, these missing translations will appear in English. Most clients prefer to wait until a certain amount of translations are approved before allowing users to select it.

* Finally, please provide translations for the following strings:

  * Loading, please wait...

  * 20 records per page

  * Showing 20 to 30 of 50 rows

  * Search

  * No matching records found

  * Hide/Show pagination

  * Refresh

  * Toggle

  * Columns

  * All

Once you provide us with this information, we can make the language available for translation in Surfly Translate within 2--5 business days.

**Read more about** [**contributing to Surfly Translate \>\>**](https://help.surfly.com/en/translations.md)

---
language: "en"
---
# Alternative Option to Domain Delegation

While domain delegation is our recommended method for using Surfly Public Cloud from your own domain, we understand that it may not always be feasible for everyone. In such cases, we offer an alternative solution, although it is not our preferred approach.

If domain delegation is not suitable for your needs, you have the option to provide us with the required SSL certificates and create DNS records to point your chosen subdomain to Surfly servers. You'll need to provide SSL certificates with yearly validity.

To implement this alternative option, please follow these steps:

* **SSL Certificate Requirements:**

  * Provide us with a file containing the complete certificate chain and private key, valid for both `domainname.com` and `*.domainname.com`

  * Make sure that the certificate is in **\*.pem** format and has the following structure:

        -----BEGIN RSA PRIVATE KEY-----
            (Your Private Key)
        -----END RSA PRIVATE KEY-----

        -----BEGIN CERTIFICATE-----
            (Your Primary SSL certificate)
        -----END CERTIFICATE-----

        -----BEGIN CERTIFICATE-----
            (Your Intermediate certificate)
        -----END CERTIFICATE-----

        -----BEGIN CERTIFICATE-----
            (Your Root certificate)
        -----END CERTIFICATE-----

  * Ensure the certificate is valid for a year.

* **Create DNS Records:**

  * Configure DNS records to direct your subdomain to Surfly servers.

    * Create a `ANAME` record "`*`" pointing to `surfly.com`

    * Create a `ANAME` record "" pointing to `surfly.com`

We offer the capability to securely bind your domain to your Surfly account(s), guaranteeing that only authorised users can utilise this domain. This ensures a private and protected association, eliminating concerns about other entities accessing your domain on Surfly's public cloud.

---
language: "en"
---
# Architecture

**The following is a network overview of Surfly Public Cloud:**

++*Origin Servers*++ represent the infrastructure of a web-app. a ++*Tab-owner*++ is co-browsing.

The content of each tab is rendered in the browser of its ++*Tab-owner*++ . Only updates to the Document Object Model (DOM), which provide lossless visuals, are shared with the ++*other participants*++.  
In a Surfly session, there may be several Tab-owners, but each individual Surfly tab has only one Tab-owner, depending on who opened it. Visual updates are shared with the other participants in that session, and the network overview of each Surfly tab remains the same, as described below.  
![Network Diagram Public Cloud-20230217-113657.png](https://help.surfly.com/__attachments/a_986796fbcd41f1b998d3227cd1d57a57d5ea3221d070398a65af3fcd70635de7/Network%20Diagram%20Public%20Cloud-20230217-113657.png?cb=c11420cb546c66352ea2eca1767c4d77)

**The following is a network overview of Surfly On-premise setup:**

++*Origin Site*++ represents the infrastructure of a web-app. that a ++*Tab-owner*++ is co-browsing.

The content of each tab is rendered in the browser of its ++*Tab-owner*++ . Only updates to the Document Object Model (DOM), which provide lossless visuals, are shared with the company ++*Agents.*++ Financial institutions with regulatory requirements that necessitate on-site data processing typically choose this model. As a result, they install Surfly on-premise server(s) at their own location.  
![On Premise Network Overview-20230217-134417.png](https://help.surfly.com/__attachments/a_2b753070fb5b11ae53e771a2c10077de26fa1c0e82974506ea4d826d1d91e92f/On%20Premise%20Network%20Overview-20230217-134417.png?cb=5d5fa5802e542356a345c8828e532d3b)

## Read more about various deployment models [here \>\>](https://help.surfly.com/en/deployment-models.md)

### Read more Tab-ownership [here \>\>](https://help.surfly.com/en/what-do-leader-and-follower-mean-in-a-surfly-sessi.md)

---
language: "en"
---
# Are the pricing plans for Surfly subject to VAT or sales tax?

That depends on your location.

Non-EU: For all customers outside the European Union, we do not have to add VAT.

EU: For companies in the European Union that have a valid VAT tax ID, we do not have to add VAT. For private individuals or organisations without a valid VAT tax ID within the EU, we have to add your country's local VAT percentage.

---
language: "en"
---
# Basic Requirements

## Browsers and OS

Surfly works with all modern browsers such as Chrome, Edge, Firefox, Safari.  

### ^Recommendations^

* ^For desktops and laptops running Windows, MacOS or Linux, users can use Chrome, Edge, Firefox or Safari.^

* ^For Android mobile devices we recommend using Google Chrome and for iOS mobile devices we recommend Safari.^

* ^Always use the most recent version of your browser.^

## Network \& Protocols

Communication with Surfly is done over port 443 and we use standard TLS encryption.

### Bandwidth requirements

There are no added bandwidth requirements for accessing web content.

For Videochat/Screen-sharing:

* Video: 600 kbps per stream (lowest level)

* Audio: 50 kbps per stream (lowest level)

### Permissions

#### For (co)browsing web content, document sharing and screen-recording

Participating users and [++original servers++](https://help.surfly.com/en/architecture.md) should allow connections to `*.surfly.com`  
^Users need to establish a websocket connection with the Surfly servers. When participating a Surfly session through a WAF/Proxy/Security-gateway, we recommend bypassing \*.surfly.com or our^[^++IP addresses++^](https://help.surfly.com/en/what-are-the-surfly-ip-addresses)^to ensure proper functioning of your session.^

##### For Video-chat, Screen-sharing and Camera-sharing

Surfly uses a WebRTC solution for video chat and screen sharing. At a minimum, the following requirements must be met:

* TCP port 443 and UDP port 3478 open for the following domains:

  * `*.tokbox.com`

  * `*.opentok.com`

You can test if a network and device meets the connectivity requirements by running the [Vonage pre-call test](https://tokbox.com/developer/tools/precall/). ^\*This test link is not supported in FireFox browser, but video-chat is.^

#### Read about testing Surfly locally [here \>\>](https://help.surfly.com/en/can-i-test-surfly-on-localhost.md)

#### Read about Surfly server IP addresses [here \>\>](https://help.surfly.com/en/what-are-the-surfly-ip-addresses.md)

---
language: "en"
---
# Billing & Accounts

---
language: "en"
---
# Browser's Third-party cookie restrictions

Browsers like Safari implement policies to limit or control third-party cookies usage, impacting the way sessions start and function on websites using *widget*.

By default, when a session is initiated, it is served from Surfly's domain (e.g., [surfly.com](http://surfly.com/) ) instead of the website's domain that you have open in your browser tab (e.g., [yourDomain.com](http://yourdomain.com/) ). Due to the browser's restrictions on third-party cookies, Surfly sessions can only start in a new tab rather than the desired website's current tab.  
Please note: If your web application uses a COOP (Cross-Origin-Opener-Policy) header, workarounds such as opening a new tab may fail due to its restrictions.

To overcome these limitations and enhance your user experience, consider running Surfly from your own domain, for example, [assistance.yourDomain.com](http://assistance.yourdomain.com/) .

This approach offers multiple benefits, including:

* **Unrestricted Session Initiation when using Surfly widget:** Start sessions directly within the current tab for a smoother user experience and workflow.

* **Enhanced Trust \& Branding:** Users feel more secure when sessions run under your domain, creating a sense of trust, and it allows for a more branded and consistent user interface.

## Read about running Surfly from your own domain [here \>\>](https://help.surfly.com/en/can-i-run-surfly-from-my-own-domain.md)

---
language: "en"
---
# Can I cancel my Surfly plan?

## 🧾 **If you purchased your plan online (credit card/self-service)**

You can cancel or downgrade your subscription directly from your account:

* Go to **Settings \> Plan**

* Click **"Cancel your current plan"** or select a **free plan**

* Your subscription will remain active until the end of your current billing cycle (monthly or yearly, depending on your plan).

* If you **upgrade**, changes apply immediately.

* If you **downgrade**, the change takes effect at the end of the current term.

*** ** * ** ***

### 🏢 **If you are an enterprise customer (signed contract)**

Enterprise customers with custom agreements must follow the cancellation process defined in their contract.

* In most cases, written notice must be sent to Surfly **at least 30 days prior** to the end of the current subscription term.

* Your subscription will automatically renew unless such notice is received.

* Please reach out to your account manager or [**invoice@surfly.com**](mailto:invoice@surfly.com)if you wish to discuss cancellation, renewal, or changes to your subscription.

---
language: "en"
---
# Can I integrate Surfly through a Tag Manager?

Yes, you can. But tag managers do come with certain limitations.

If your users have an ad blocker installed, you run the risk that it will block the tag manager too. 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.

---
language: "en"
---
# How can I run Surfly sessions using my own domain?

You can run Surfly using your own domain in more than one ways. One is to have your own *dedicated* Surfly server setup. You can install and manage one yourself or we can do that for you. These are [our *on-premise* and *private-cloud* deployment](https://help.surfly.com/en/deployment-models.md) offerings and they come with a lot of benefits but you also need to take into consideration the technical resources and/or cost when you opt for those.

## There is also another faster, simpler and much less expensive option to run Surfly from your domain of choice whilst leveraging our global server infrastructure.

For example, if your chosen domain is [++https://collaborate.yourdomain.com++](https://collaborate.yourdomain.com/) the invite links will be [++https://collaborate.yourdomain.com/xyz123++](https://collaborate.yourdomain.com/xyz123) and you will be able to access the Surfly user dashboard (UI) using [++https://app.collaborate.yourdomain.com++](https://app.collaborate.yourdomain.com/)

To achieve this, you can delegate your chosen subdomain to us so that we can generate required SSL certificate and create DNS records to point your subdomain to Surfly servers. Once that is done, you can start accessing Surfly from [++app.collaborate.yourdomain.com++](https://app.collaborate.yourdomain.com/) and run sessions from it.

**Technical requirement:**

Please use the following nameservers for domain delegation:

[ns0.surfly.com](http://ns0.surfly.com/)

[ns1.surfly.com](http://ns1.surfly.com/)

[ns2.surfly.com](http://ns2.surfly.com/)

[ns3.surfly.com](http://ns3.surfly.com/)

[ns4.surfly.com](http://ns4.surfly.com/)

[ns5.surfly.com](http://ns5.surfly.com/)

Once you have completed the domain delegation, please verify it. Additionally, we need your company name and ID as registered with Surfly. If you are making this request on behalf of a client, please provide their name instead. You can find the necessary steps to verify that the domain delegation is complete and to locate the registered account [here](https://help.surfly.com/en/verifying-domain-delegation.md).

We offer the capability to securely bind your domain to your Surfly account(s), guaranteeing that only authorised users can utilise this domain. This ensures a private and protected association, eliminating concerns about other entities accessing your domain on Surfly's public cloud.

We offer an alternative to domain delegation. More details on this option can be found [here](https://help.surfly.com/en/alternative-option-to-domain-delegation.md).

---
language: "en"
---
# Testing Surfly on localhost

It is important to note that Surfly needs to be able to reach the server over the network. You can use tools such as [++ngrok.io++](http://ngrok.io/) or [++burrow.io++](http://burrow.io/) to allow Surfly access to your local machine whilst you are developing locally. However, if you really want to work on an isolated LAN, you can install [Surfly on-premise](https://help.surfly.com/en/deployment-models.md).

If you want to have you own local on-premise solution, please feel free to contact us at [++sales@surfly.com++](mailto:sales@surfly.com)

---
language: "en"
---
# Can I use Surfly to browse social media sites?

For users on the 14-day free trial and our free plan, we have restricted social media websites like Twitter, Facebook, Instagram, Youtube, etc.

If you want to be able to co-browse these websites, please upgrade to a paid plan.

---
language: "en"
---
# Can Surfly be integrated on mobile apps?

Surfly's co-browsing is browser-based, so you can join a Surfly session from either a desktop, laptop, or mobile device.

Native apps can be co-browsed through the use of a WebView only.

---
language: "en"
---
# Clients Functionality: Admin Guide

## Introduction

The Clients functionality empowers you to create and fully manage Surfly accounts directly under your own account. Each client account you create will have its own set of users, queue, API keys, and settings.  
![Screenshot 2023-06-06 at 14.31.54.png](https://help.surfly.com/__attachments/a_be75c17d0d5f3f7143d8ccf22dcb97a26d8401b8727738d6f85c44b23380353c/Screenshot%202023-06-06%20at%2014.31.54.png?cb=59f9edb8b345195b1fa522d74beeda0a)  
This functionality is available under our partnership model. For other companies, enabling this feature requires a review on a case-by-case basis. Please contact [sales@surfly.com](mailto:sales@surfly.com)

### Overview

This guide provides detailed instructions on how to administer your clients using the Clients Functionality. You have two options for client administration: utilizing our Surfly dashboard or integrating with our [REST API](https://docs.surfly.com/api/v2#tag/Clients). The choice between these two methods depends on your specific use case and whether you prefer to build your own dashboard. In this guide, we will primarily focus on using the Surfly dashboard, which offers a user-friendly interface to get you started and acquainted with Surfly.

### Administration

Setting up a new client account under your own account is a simple process. To begin, log into your Surfly dashboard and navigate to the *Clients* tab. From there, you can add a new company to your Company List.  
![First.gif](https://help.surfly.com/__attachments/a_6f5075cd7e2edc0bfe59f2a2b19dca7f665dc77a20971fb86e6b353bed48d340/First.gif?cb=9d02c6cbac5efcbae0ea2936e8318126)

Please remember to remove the default 14-day expiration date assigned to a newly created company if you are not offering a limited period trial. To remove the expiration date, simply select it and press the backspace button to delete it.

Once added, click on ++*Manage Agents*++ to configure the agents for the account. Upon adding users, they will receive emails to set up their accounts. It's crucial to define user roles for effective account management.  
Please note that a user (unique email address) can only exist in one Surfly account. This means that the same user (email address) cannot be part of multiple Surfly accounts, whether it's the main Surfly account or a client account.

Finally, you have the ability to log into your client's account as an admin. This feature can be useful if you need to make adjustments to their settings or access their credentials, such as API keys. To do this, navigate to your *Clients* page and click on ++*Log in as admin*++.  
![Second.gif](https://help.surfly.com/__attachments/a_52f1e7767ed3433a32287cc4be459774289dcb62b11e0775b06ae6dc055402be/Second.gif)
This video showcases the complete segregation between your account and your client account, highlighting that the settings for each can be individually configured and managed.  
Please note that this function is only available if the company has at least one [*Admin*](https://help.surfly.com/en/what-s-the-difference-between-an-admin-a-manager-a.md) privilege user. This user will enable you to log in as an Admin and effectively manage the account settings for the specific client account. However, if having an actual individual in the Admin role is not a business requirement, you can add a dummy user and assign them Admin privileges. This will provide you with the ability to log in as the dummy user and efficiently manage the account settings.

By following these steps, you can effectively manage client accounts under your own Surfly account, ensuring seamless collaboration and efficient administration.

### Here are some important points to note:

* **User Management**: To manage the users of a client, go to the Clients tab and click on "Manage Agents."

* **Creating Clients** : Avoid using the "Allow to create clients" option when creating a client unless specifically discussed with Surfly beforehand. Enabling this option can complicate usage reviews and billing processes on our end. Additionally, note that you will not be able to manage a *client* of a *client*. This functionality is designed for specific use cases.

* **Client Search**: You can use the search option on the Clients tab to find the client to which a user belongs. Simply search by email or use unique keywords from the email.

* **Usage History**: You can easily check and extract the usage history of a client by navigating to the Clients tab and clicking on the "Sessions Created" column for the respective client.

* **Seats**: Seats do not impact any functionality or billing. They serve as a visual reference to help you monitor if a company is utilizing the contracted/agreed-upon number of seats or not.

Please keep these points in mind to ensure a smooth and efficient management experience within the Clients functionality.

---
language: "en"
---
# Custom MCP Tools: 95% Fewer Tokens. 3x Faster Agents.

With **Custom MCP Tools** , developers can expose structured information and actions directly to agents, replacing repeated page analysis with purpose-built tools. The result is **dramatically faster workflows, significantly lower token consumption, and more reliable automation**.

In the example below, an AI agent completes a multi-step assessment journey on an existing Dutch VvE (homeowners association) sustainability helpdesk website. The user simply describes their situation and goal. The agent completes the assessment, reviews the recommendations, and emails the report.  
![Final-Custom-Tools.gif](https://help.surfly.com/__attachments/a_146e6844deabeefa8b8ef54a582dd3212ae6a83f11af764f0c6b1411d6547dcb/Final-Custom-Tools.gif)

This runs on an existing website and workflow. No code changes were required.  

|                 | Without Custom MCP Tools | With Custom MCP Tools |
|-----------------|--------------------------|-----------------------|
| Token usage     | \~66,000                 | \~3,000               |
| Completion time | \~3 minutes              | Under 1 minute        |

That's a **95% reduction in token consumption** and a workflow that completes **more than three times faster**.

Want to build your own tools? Read our guide to **Custom MCP Tools** :

<https://dev.webfu.se/custom-mcp-tools/>

The same approach can make AI-powered customer journeys significantly faster and more cost-efficient by reducing the amount of context agents need to process. Think of workflows like:

* Buying or modifying an insurance policy

* Opening a bank account and completing KYC

* Filing taxes across government and third-party portals

All on top of existing applications and websites. No code changes required. Third-party systems can be part of the same workflow, with every action remaining fully auditable.

Sometimes the biggest improvement isn't a better model. It's giving the model the right tools.

---
language: "en"
---
# Custom Notifications with Webhooks

## Queue notifications

By default, when an incoming session is placed in a queue (e.g., triggered by a button on a website), users with the Surfly dashboard open in their browser receive sound notifications. The availability of these notifications depends on your Surfly settings and browser configurations allowing [app.surfly.com](http://app.surfly.com/) to generate sound alerts.  
![Screenshot 2023-06-19 at 17.06.23.png](https://help.surfly.com/__attachments/a_c770e1a850a77ed7f0c15b5779b5f9eb620f76b7f4c2d79b802fbba4b0b2bf9e/Screenshot%202023-06-19%20at%2017.06.23.png?cb=6e73b13070b62de0aef8ae92ca812bca)

This default notification system eliminates the need for continuous monitoring of the queue. However, there may be situations where the sound notification alone is insufficient for your specific requirements. For instance, you might prefer additional notification methods, such as receiving a WhatsApp message or a phone call, to actively alert agents and prompt them to join the incoming session in the queue.

### Setting up these custom notifications is simple

By utilizing the `session.queued` [webhook](https://docs.surfly.com/surfly/webhooks#sessionqueued), you can seamlessly send real-time data to your own service or popular third-party platforms like Zapier or Twilio, allowing you to generate WhatsApp messages or initiate phone calls to specified numbers in real time.

To begin, configure the session.queued webhook in your Surfly*Settings \>\> Integration* page. This ensures that the necessary data is transmitted whenever a session is placed in the queue.

With this setup, you can actively notify agents and ensure their prompt engagement with incoming sessions, enhancing the overall efficiency and effectiveness of your queue management process.

---
language: "en"
---
# Customising Surfly Emails: Personalise and Rebrand

While default emails from Surfly are not customisable, you can disable them and leverage our webhooks to send your own branded emails.

This enables you to craft compelling email content that reflects your organization's tone and voice, and use your own mail servers to send these invitations.

Below, we explore how to personalise and rebrand session invites to align with your organisation's identity.

1. **Leveraging Webhooks** : To begin personalizing session invites, configure a webhook for the `session.invitation` event. Access your Surfly *Settings \>\> Integration* page and *Add webhook* . This setup allows you to receive notifications when a session invitation is triggered. You can then utilize your own mail servers to send fully customized emails, incorporating relevant [++information from the webhook++](https://docs.surfly.com/surfly/webhooks#sessioninvitation), such as the `follower_link`.

2. **Disabling Default Surfly Emails** : By default, invite to the sessions are sent from [++support@surfly.com++](mailto:support@surfly.com). Once you have configured the webhook and triggered your own emails, it's essential to disable the default invites. In your Surfly *Settings \>\> Options \>\> Session Functionality* toggle the `default_invitations_enabled` option to `false`.

In a similar manner, you can also rebrand other Surfly emails, such as new account invites, password reset notifications, and usage history emails. For each of these events, [**set up a webhook**](https://docs.surfly.com/surfly/webhooks) and configure it accordingly. Once the webhooks are in place, you can disable all Surfly emails by adjusting the `default_invitations_enabled`under*Settings \>\> Options \>\> Company Settings*.

++Customising Session Links++ : Surfly's default session links are in the format [surfly.com/xyz123](http://surfly.com/xyz123). If you wish to customise them to your own domain, such as [https://YourDomain.com/xyz123](https://yourdomain.com/xyz123), you need to run Surfly from your own domain.

## Read more running Surfly from your own domain [here \>\>](https://help.surfly.com/en/can-i-run-surfly-from-my-own-domain.md)

---
language: "en"
---
# Customizing User Icons with free Gravatar Integration

[**Gravatar**](https://en.gravatar.com/), a popular free service, can be used to replace default participant icons with actual pictures or preferred generic images in Surfly sessions. If a user has a Gravatar set up, it will be populated in place of the default icon. Otherwise, a default icon will be generated.  
![Screenshot 2023-04-25 at 17.06.40-20230425-150646.png](https://help.surfly.com/__attachments/a_ba551a068d72c0ca8dd7fc3a47344e95d400a8edd1c08ff6e49247f098f09939/Screenshot%202023-04-25%20at%2017.06.40-20230425-150646.png?cb=185ddfab85a02287e51f6ba0cf892ed1)  
~In the screenshot example, one user named Sasha does not have a Gravatar set up and hence a default icon 'S' is generated in place of a personalized image, whereas the other user has a Gravatar set up and their chosen image is displayed as their participant icon.~

To use Gravatar, users can create an account and upload their desired image, which will be automatically populated in the session. Additionally, there is an option to generalize agent name, email, and hence Gravatar under Company Settings.

However, integrating this feature for customers who are not Surfly users can be challenging. To do so, the customer's name and email must be passed into the session and a Gravatar created for them. This can be more easily achieved through integrations where a generic customer name and email can be passed into the session and a Gravatar can be set up accordingly.

---
language: "en"
---
# Privacy & Security

Security is a core design principle of our technology. When no data is stored, no data can be lost. The whole Surfly session has been designed to act as infrastructure, information is only passing through but never stored.

* We don't store any session data. All session data only lives within memory during the time of the session, we do not store it on disk.

* Surfly uses secure HTTPS connections

* We use strong SHA-256 SSL encryption for data in transit, the same kind of encryption your bank uses.

* Surfly is PCI compliant. We never store your credit card, as this is all handled by Chargebee.

* We are fully GDPR compliant, SOC 2 \& ISO27001 certified

And it doesn't stop there... Surfly co-browsing comes with built-in features that you can enable to make your sessions more secure. For instance, you can restrict your users to only be able to co-browse your website, or you can disable the option that allows your agents to take control over the navigation.

Moreover, our API comes with built-in functions that enable you to secure your website even more during a co-browsing session. With "field masking" you can mask form fields from your agents, and with "control dependent appearance" you can change the look of the web page or create restrictions according to who is in control over the session. Finally, with our "audit log" functionality you are able to trace back all steps that your users have taken during co-browsing.

## Read more about GDPR compliance [here \>\>](https://help.surfly.com/en/is-surfly-gdpr-compliant.md)

### Read more about PCI compliance [here \>\>](https://help.surfly.com/en/is-surfly-pci-compliant.md)

---
language: "en"
---
# Deployment For Clients

## Overview

Surfly application consists of 23+ services. All of them are containerized and

run with Podman. Podman containers are managed by systemd with services which are prefixed with `ss-`.

Storage services (SQL and in-memory databases - Redis, PostgreSQL) are normally managed separately by clients as external services. See [on-premise documentation](https://docs.surfly.com/installation/#configuration). Surfly optionally provides an automated script to set it up on the server itself.

During the installation process, the container images of services are pulled from the [Surfly registry](https://registry.surfly.com/). The images of officially released versions are retained in the registry for 720 days. The other images are retained for 5 days.

To complete the installation process, a client requests a build file from our [build server](https://build.surfly.com/). The build file contains personalized configuration files for Surfly installation and a license file. The build file is downloaded from [storage server](https://storage.surfly.com/) and cached for 1 day.

## Minimum deployable version

Surfly releases a new version, on average, 2 to 6 times a month. We highly recommend using the latest version for optimal performance and security. However, if you are unable to do so, we also make efforts to ensure that older Surfly versions remain deployable.

The deployability of older versions is subject to certain conditions:

* Availability of container images in the registry

* Changes in system packages which are required for Surfly to function correctly (see up-to-date list [here](https://docs.surfly.com/installation/#required-packages))

* Changes in system packages required for Surfly to build

* The version of the Surfly `setup` script. Regardless of the Surfly version you intend to deploy, the **latest version of the setup script is required**.

We are actively working to minimize system dependencies for both building and running Surfly, ensuring smoother deployment experiences.

Please note that Surfly does not support versions that rely on operating systems that have reached End of Life (EOL) status.

**Major Surfly versions are supported for 1 year**. The support is often extended and follows the base OS release cycle (CentOS Stream).

## Roadmap

* Minimize the number of system packages required for Surfly to operate and build.

* Transfer the generation of configuration files from the build server to the installation process on the server itself. This optimization aims to accelerate deployment and decrease reliance on system packages necessary for building Surfly.

* Implement a distribution-independent installation process. We will define the minimum version of container engine, Linux kernel, and other essential system packages required for Surfly to function. This approach will enable easy installation on any modern Linux distribution.

* We plan to complete the mentioned improvements in Q4 2024 with Surfly v5 release.

---
language: "en"
---
# Deployment Models

|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|                    | **Public cloud clients**                                                                                                                                                                                                                                                                                                                                                                                           || **Private-Server clients**                                                                                                                                                                                                                                                                                                                                                                  ||
|                    | **Surfly Public Cloud**                                                                                                                                                                                  | **Custom SSL Certificate**                                                                                                                                                                               | **Private Cloud**                                                                                                                                        | **On-premise**                                                                                                                                                                                                                    |
| **Branding**       | Your sessions run using [++surfly.com++](http://surfly.com/)                                                                                                                                             | Your sessions run using [++yourdomain.com++](http://yourdomain.com/)^\*^                                                                                                                                 | Your sessions run using [++yourdomain.com++](http://yourdomain.com/)                                                                                     | Your sessions run using [++yourdomain.com++](http://yourdomain.com/)                                                                                                                                                              |
| **SLA**            | We take care of the hosting and monitoring of the underlying infrastructure                                                                                                                              | We take care of the hosting and monitoring of the underlying infrastructure                                                                                                                              | We take care of the hosting and monitoring of the underlying infrastructure                                                                              | You have to care of the hosting and monitoring of the underlying infrastructure                                                                                                                                                   |
| **Compliance**     | We use single tenant servers only. Session data is logically separated for all sessions, from all users. Sessions are hosted using any of our data center locations that are spread across the globe.^#^ | We use single tenant servers only. Session data is logically separated for all sessions, from all users. Sessions are hosted using any of our data center locations that are spread across the globe.^#^ | We use single tenant servers dedicated to your sessions only. Sessions are hosted using your private sever setup in a region or your choice. (AWS/Azure) | You decide what kind of server you want to use to install Surfly and run your sessions.^\^^ Sessions are hosted using your own sever setup (data center or any cloud provider). Surfly has no access or control over this server. |
| **Change Control** | Surfly's software release cycle applies. You always use the latest version.^\*\*^                                                                                                                        | Surfly's software release cycle applies. You always use the latest version.^\*\*^                                                                                                                        | You decide your update cycle.^\*\*^                                                                                                                      | You manage your server updates yourself.^\*\*^                                                                                                                                                                                    |
| **Features**       | Video-chat \& Screen-sharing included\^\^                                                                                                                                                                | Video-chat \& Screen-sharing included\^\^                                                                                                                                                                | Video-chat \& Screen-sharing included\^\^                                                                                                                | Video-chat \& Screen-sharing are not included.^+^                                                                                                                                                                                 |
| **Features**       | Document Editor                                                                                                                                                                                          | Document Editor                                                                                                                                                                                          | Document Editor                                                                                                                                          | Document Editor                                                                                                                                                                                                                   |
| **Pricing**        | [Contact our Sales team](mailto:sales@surfly.com)                                                                                                                                                        | [Contact our Sales team](mailto:sales@surfly.com)                                                                                                                                                        | [Contact our Sales team](mailto:sales@surfly.com)                                                                                                        | [Contact our Sales team](mailto:sales@surfly.com)                                                                                                                                                                                 |

^\*^[How can I run Surfly sessions using my own domain?](https://help.surfly.com/en/can-i-run-surfly-from-my-own-domain.md)

^#^By default, sessions are started from the closest available location. List of all [++available regions++](https://surfly.com/v2/servers/). However, if you want to set a preference for location or even fix the location(s) where the session should start from, you can.

^\^^ Minimum [System requirements](https://docs.surfly.com/installation/#system-requirements) \& [Deployment](https://help.surfly.com/en/deployment-for-clients.md) details for on-premise deployment.

^\*\*^We update our servers frequently - at least weekly. These updates do not result in server downtime, but they can cause some active sessions to be disconnected. To prevent this, we deploy updates during off-business hours for each region.

^\^\^^The usage of video chat is restricted to 1000 minutes per user per month for the entry level plans. For usage-based plans, the limit is same as the number of monthly minutes allowed.

^+^It uses a 3rd-party service that runs through cloud only and can be enabled for you at extra cost.

---
language: "en"
---
# 🤖 Digital First Omnichannel Chat- CXOne Agent

## Introduction

This guide will show you step by step how to install Surfly's custom component on your

NICE inContact CXOne agent.

This component will let you start co-browsing, video chat and screen sharing sessions with patrons using the DFO chat.

## Surfly Integration to CXone Agent

To integrate **Surfly** with your **CXone Agent**, please follow the official instructions provided by NICE.

👉 [Click here to access the NICE Help Page with full integration steps](https://help.nice-incontact.com/content/agent/cxoneagent/cobrowseincxa.htm?TocPath=Agents%7CCXone%20Agent%20%7C_____2)

## Surfly Integration to a website

To integrate **Surfly** with your **Live Chat** system, you'll need to append a Surfly-specific code snippet immediately after your regular Chat Snippet.

### 1. Your Standard Chat Snippet

Below is an example of a typical chat snippet. This should already be included in your website:

    (function (n, u) {
          window.cxone = n,
            window[n] = window[n] || function () { (window[n].q = window[n].q || []).push(arguments); }, window[n].u = u,
            e = document.createElement("script"), e.async = 1, e.src = u + "?" + Math.round(Date.now() / 1e3 / 3600),
            document.head.appendChild(e);
        })('cxone', 'https://livechat-static-de-na1.niceincontact.com/4/chat.js');
    cxone('init', 1022, 'chat_4bc8d701-a316-4b5f-bc12-9c45f766dbd0');
    cxone('getOngoingThreads');

#### 2. Surfly Integration Snippet

**Insert the following snippet right after your chat snippet.**

##### Important:

* Replace the placeholder `customerWidgetKey` with **your Surfly Widget Key**.

* To find it: go to **Surfly Dashboard → Settings → Integration** . Use the **Widget Key** , *not* the **REST API Key**.

* The default trigger phrase is `#COBROWSE#`. You can customize this to suit your workflow.

    cxone('setAllowedExternalMessageTypes', ['MESSAGE_SENT', 'MESSAGE_RECEIVED']); window.addEventListener("message", function (event) {       console.log(event, 'listener event');       // Ensure the data structure is as expected       if (event.data && event.data.actionType === "MESSAGE_RECEIVED") {         console.log(event.data.actionType, 'ACTION TYPE');         const messageContent = event.data.action.message;         // Check if the message content is "#COBROWSE#"     if (messageContent === "#COBROWSE#") {       console.log("Cobrowse message received:", event.data);       startCobrowse();     }   } });  function startCobrowse() {   let customerWidgetKey = "134f5fd2ac8842c0a1cd6062818eee74"; //set customer widget key to variable
      window.parent.Surfly.settings.widget_key = customerWidgetKey; //set customer widget key to widget_key high level
      if (window.parent.Surfly.settings.widget_key === customerWidgetKey) {
        // check if it worked to avoid null
        console.log('widget key change correctly', customerWidgetKey);
        Surfly.session().on(
          'session_created',
          function (session, event) {
            console.log("Session created", session, event);
            var surflySessionPin = session.pin;
            console.log("Surfly session pin", surflySessionPin);
            if (surflySessionPin) {
              console.log(document, 'document');
              //document.getElementsByName("reply-box")[0].value = surflySessionPin;
            }
          }
        ).on('session_started', function (session, event) {
          console.log("Session started", session, event);
        }).startLeader();
      }
    }

---
language: "en"
---
# Frequently Asked Questions (FAQs)

* [Can Surfly be integrated on mobile apps?](https://help.surfly.com/en/can-surfly-be-integrated-on-mobile-apps.md)
* [How do I clear the cache?](https://help.surfly.com/en/how-do-i-clear-the-cache.md)
* [Where can I find the Surfly snippet?](https://help.surfly.com/en/where-can-i-find-the-surfly-snippet.md)
* [Can I integrate Surfly through a Tag Manager?](https://help.surfly.com/en/can-i-integrate-surfly-through-a-tag-manager.md)
* [I can only browse Wikipedia with Surfly, what's going on?](https://help.surfly.com/en/i-can-only-browse-wikipedia-with-surfly-what-s-goi.md)
* [Can I use Surfly to browse social media sites?](https://help.surfly.com/en/can-i-use-surfly-to-browse-social-media-sites.md)
* [How many Surfly sessions can I create?](https://help.surfly.com/en/how-many-surfly-sessions-can-i-create.md)
* [What defines the Successful start of a session?](https://help.surfly.com/en/what-defines-the-successful-start-of-a-session.md)
* [Understanding Session Termination and Link Validity](https://help.surfly.com/en/understanding-session-termination-and-link-validit.md)
[Billing \& Accounts](https://help.surfly.com/en/billing-accounts.md)
* [How to export HAR dump from web browser.](https://help.surfly.com/en/how-to-export-har-dump-from-web-browser.md)
* [Generating a Diagnostic Report for On-Prem Server](https://help.surfly.com/en/generating-a-diagnostic-report-for-on-prem-server.md)

---
language: "en"
---
# Key Features

Below is the list of Surfly features that you can use alongside co-browsing.  
* [Masking](https://help.surfly.com/en/masking.md)
* [Standard Landing pages](https://help.surfly.com/en/standard-landing-pages.md)
* [Video chat and Text chat](https://help.surfly.com/en/video-chat.md)
* [Session Recording](https://help.surfly.com/en/session-recording.md)
* [Screen-sharing \& Camera-sharing](https://help.surfly.com/en/screen-sharing.md)
* [Audit logs](https://help.surfly.com/en/guide-to-audit-logs.md)
* [File Sharing \& Editing](https://help.surfly.com/en/file-sharing-editing.md)
* [Single Sign-On (SSO)](https://help.surfly.com/en/single-sign-on-sso.md)
* [Huddle Mode](https://help.surfly.com/en/huddle-mode-collaborate-in-real-time-like-never-be.md)
* [SMS session invitations](https://help.surfly.com/en/sms-session-invitations.md)

---
language: "en"
---
# File Sharing & Editing

Our File Sharing \& Editing feature empowers you not only to upload `.pdf` files for collaborative review but also to annotate and edit them in real-time.

The entire session seamlessly unfolds within a single browser tab, positioning Surfly as a comprehensive solution for sharing, editing, saving, and even printing PDF documents.

## Uploading a file into the session

You can do this by opening a ++*New tab*++ inside the session. You can click on ++*Upload files*++ button and select the file from your computer  
![File Sharing.gif](https://help.surfly.com/__attachments/a_f40894b35cd12c269a7ce6ff97c9d6852675e78dca18dd1785fe05af11d19378/File%20Sharing.gif?cb=93ae8838d788f4702a28ffa277dc646a)

Or you can even drag a drop a file into this ++*New tab*++ popup

### User Interface

Once your file has been uploaded you will see a Document Editor UI or Document Viewer UI, depending on your setting for option `document_editor_enabled`.

### Under the hood

When a local file is uploaded to the session, it is temporarily stored in the server cache for the duration of the session. Our Document Editor then renders the file from the cache for display purposes. Similar to a webpage, the DOM/Visual updates are shared with the following-participants.

To download the original file in its original format (e.g. .docx), users must enable the `allow_original_file_download` option, which can be accessed via the chat button (see below) or a webhook `document.shared`.

Once the session ends, the original document is automatically removed from the server cache to protect user privacy.

### Related session options

|              Option              | Default |                                                                                                                                                                                             Description                                                                                                                                                                                              |
|----------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `filesharing_enabled`            | true    | Allow file sharing and enable Document Editor feature. When set to false, the button will disappear from the control bar.                                                                                                                                                                                                                                                                            |
| `document_viewer`                | pdf     | `.pdf `documents are the only type of documents allowed to be shared.                                                                                                                                                                                                                                                                                                                                |
| `document_editor_enabled`        | true    | Enable editing in the document viewer interface.                                                                                                                                                                                                                                                                                                                                                     |
| `original_file_download_allowed` | false   | When enabled, users will be able to download shared files in their original format using the chat button (See below). If disabled, users can download the current working document in PDF format, using the download button in the document editor menu. This option may be useful in situations where preserving the original file format is important, such as when sharing media or design files. |
| `download_trigger_enabled`       | true    | When a user downloads a file in a Surfly session, offer to let others download the file. If set to false, downloaded files will not be available to other participants.                                                                                                                                                                                                                              |

![Screenshot 2024-02-28 at 16.14.38.png](https://help.surfly.com/__attachments/a_3dc4b91b3d11aa63a8484a3f9fbd127179e3bcbb40d0710550c55ffcef18c047/Screenshot%202024-02-28%20at%2016.14.38.png?cb=695cf2ef9378806ee0688690f8c503dd)

---
language: "en"
---
# Standard to Custom: Feature Variations and Implementation Considerations

* [Session Start Buttons: Default vs Custom](https://help.surfly.com/en/session-start-buttons-default-vs-custom.md)
* [Landing Pages: Standard vs Custom](https://help.surfly.com/en/landing-pages-standard-vs-custom.md)

---
language: "en"
---
# Generating a Diagnostic Report for On-Prem Server

If you're experiencing issues with your Surfly On-Prem deployment, our Support team may ask you to generate a diagnostic report. This report collects information about your server and Surfly installation to help us troubleshoot problems more efficiently.

## What information is included?

The diagnostic report includes:

* Operating system and hardware information

* System service logs

* Surfly usage metadata

* Surfly account and configuration settings

The report **does not** contain information about user activity inside Surfly sessions, such as personally identifiable information (PII) or session content.

### ▶️ Generate the Diagnostic Report

Execute the following command on your Surfly server:

    curl -O https://raw.githubusercontent.com/surfly/on_prem_log_collection/main/generate_report.sh && chmod +x generate_report.sh && ./generate_report.sh

This will:

* Download the latest diagnostic script

* Make the script executable

* Run the script immediately

*** ** * ** ***

### 📁 Report Output

Once the script completes, you will see output similar to:

    Local report generated: /path/to/surfly_diagnostic_full.html

The generated HTML file contains the complete diagnostic report.

*** ** * ** ***

### 🔗 Generate a Shareable Link (Optional)

At the end of execution, you will be prompted:

    Would you like to export this report to a shareable link? (y/n):

* Enter `y` to generate a temporary public link. This option may not be available depending on your network configuration.

* Enter `n` to keep the report on your local server. You can then send the generated HTML file directly to Surfly Support.

*** ** * ** ***

### 📤 Share the Report

Send either:

* the generated HTML file, or

* the shareable link (if you created one)

to the Surfly Support team as requested.

*** ** * ** ***

### 🔐 Security

The diagnostic script automatically masks sensitive information before generating the report, including:

* Passwords (for example `*_PASSWORD` and `*_PASS`)

* Tokens and secrets (for example `*_TOKEN` and `*_SECRET`)

* API keys and credentials

* Database credentials (for example `PG_EXTERNAL_USER_PASS`)

* Mail server credentials

If your organization has additional security requirements, we recommend reviewing the report before sharing it.

*** ** * ** ***

### ❗Troubleshooting

If the script does not run successfully:

1. Verify that `curl` is installed on the server.

2. Check the script for syntax errors:

       bash -n generate_report.sh

3. Confirm that the script downloaded successfully and that the file contains the shell script rather than an HTML error page.

---
language: "en"
---
# Getting Started

[Basic Requirements](https://help.surfly.com/en/basic-requirements.md) [Adding \& managing users](https://help.surfly.com/en/how-do-i-add-agents-to-my-surfly-account.md)
* ['Participant', 'Tab Owner', 'Host' \& 'Control' in a Surfly session](https://help.surfly.com/en/what-do-leader-and-follower-mean-in-a-surfly-sessi.md)
* [Start a Surfly session](https://help.surfly.com/en/how-do-i-start-a-surfly-co-browsing-session.md)
[User Interface Guides](https://help.surfly.com/en/product.md) [Integration \& Customizations](https://help.surfly.com/en/integration-testing.md)

---
language: "en"
---
# Audit logs

## INTRODUCTION

Audit Log is a feature that companies with strict audit and compliance policies will find useful. You can log almost any event that occurs within the session, from web pages visited to button clicks.

These logs are as good as screen-recordings of sessions (even better when you consider negligible data storage costs).

### Security

All the audit logs are saved to the specified location and are not accessible to Surfly - you are in control of your data at all times. If the feature is not enabled, all data is getting erased once the co-browsing session ends.

Standard events that are recorded in the Audit logs do not include any sensitive data.

Any sensitive information can easily be masked using [Field/Element Masking](https://docs.surfly.com/surfly/tutorials/security-functionalities#field-masking).

With element masking you can hide parts of web-pages - such as*banking account details or patient health record,* or inputs made by a user - *like login credentials or personal address* .

Elements masked will not be visible to a Follower in the session, and the hidden data will not get recorded in the Audit logs.

### Example

Here is a simple example of a session and its corresponding Audit log.  
![audit-log-session.gif](https://help.surfly.com/__attachments/a_5dbd2130e4971f11a858f26fd0c77b5b5ce79ad12c4eab65df1da096da3dd96b/audit-log-session.gif)

The video is from the Agents's perspective. In this case Agent is a follower.

The session is initiated by a 'Customer', who is unable to locate the 'Log in' button on a page.

After the 'Agent' joins the session, Customer transfers control to the Agent, who then clicks the Login button. After this, Agent transfers the control back to the Customer to fill in the Login details.

You can see the 'Username' is masked from the Agent's screen using "Element Masking". Customer enters the login details, submits them and then ends the session. The details are neither seen by Agent, nor do they go in the Audit logs.

You can check is the Audit Log that has been recorded [here](https://drive.google.com/file/d/1kmbbVizOGbmub040cngEGIjuG_sOpawr/view).

## GETTING STARTED

### Step 1: Enabling Audit logs

You can enable audit logs via the store_session_logs option.

In Surfly Dashboard, go to Settings → Options → Session Functionality and search for "store_session_logs".

Alternatively, you can enable this option using our APIs:

* [JavaScript API](https://docs.surfly.com/category/javascript-api-1)

* [REST API](https://docs.surfly.com/surfly/rest_api)

### Step 2: Store your Audit logs

Apart from this, you will need to specify your S3 bucket details.

To do so, go to Surfly Dashboard, go to Settings → Options → Company Settings and fill in these fields:

* S3_endpoint_url

* S3_access_key

* S3_access_secret

Please ensure the S3 bucket has the following policy actions..

* GetBucketLocation

* PutObject

And lastly, fill in the `S3_log_bucket` in Settings → Options → Session Functionality.

You can also choose any other cloud bucket that is Amazon S3 standards compatible.

Instead of a cloud bucket, you can also choose to store audit logs at your own location using a webhook. You can configure the webhook on Surfly Dashboard → Settings → Integration.

At the bottom of the page, click "Add webhook" button.

In the URL field add your destination endpoint, where you want to store your audit logs. Then select "Type" `session.log`.

Alternatively, you can configure the webook via our [REST API](https://docs.surfly.com/api/v2/#tag/Webhooks).

Once setup is complete, audit log file will be generated and stored at the location of your choice at the end of each co-browsing session. You are in control of your data at all times.

## AUDIT LOG STRUCTURE

Surfly's Audit logs are JSON format files, with **an array of objects** structure. Each of the objects represents 1 specific event at a time.

Every event in the file consists of 4 parts: **type** , **details** , **session_id\*** and **time**.

    [
       {
          "time":"date and time of event",
          "type":"type of event",
          "session_id":"ID of the session",
          "details":"the details specific for this type of event"
       },
       {
          "time":"date and time of event",
          "type":"type of event",
          "session_id":"ID of the session",
          "details":"the details specific for this type of event"
       },
       "..."
    ]

'\*' -*in session_created event "session_id" is nested under details.*

## AVAILABLE EVENTS

In the next sections you can find the detailed descriptions of all the events with the names and details specific for the particular event.

### Events related to the session and participants

#### session_created

The event that every Surfly session starts with. The only event that contains the session_id parameter inside the "details" section.  

|---------------|------------------------------------------------------------------|
|               | **"details"**                                                    |
| session_id    | ID of the session                                                |
| start_url     | URL where the session starts                                     |
| ip            | IP address of the user who creates the session                   |
| created_from  | The way the session was created, e.g., "outbound", "widget" etc. |
| options       | Session options                                                  |
| server_region | Surfly server region                                             |
| meta          | Meta data, if provided                                           |

Example:

    {
       "type":"session_created",
       "time":"2022-01-21T09:35:17.581036",
       "details":{
          "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
          "start_url":"http://bing.com/",
          "ip":"::ffff:95.97.8.146",
          "created_from":"outbound",
          "options":{
             "agent_can_end_session":false,
             "agent_can_request_control":true,
             "agent_can_take_control":true,
             "allow_control_switching":true,
             "allow_original_file_download":true,
             "allow_pause":true,
             "blocklist":[
                {
                   "pattern":".*example\\.com.*"
                }
             ],
             "block_until_agent_joins":false,
             "..."
          },
          "server_region":"eu-nl",
          "meta":{
             
          }
       }
    }, 

#### leader_joined

The event indicates the moment when a leader opens a leader's link. It contains information about the user, like their email and browser that the user used to join the session.  

|-------------------|------------------------------------------------------------------------------|
| **"details"**     |                                                                              |
| client_index      | Index of the user: always "0" for the leader and "1" and more for followers  |
| **"user_params"** |                                                                              |
| avatar            | User's avatar grabbed from [Gravatar.com](http://gravatar.com/), if provided |
| email             | Email address of the user, if provided                                       |
| follower_prefix   | Title follower is referred to: "Follower"                                    |
| ip                | IP address of the leader                                                     |
| name              | Name of the user, if provided                                                |
| queue_index       | Index of the queue, if provided                                              |
| user_agent        | Info about user's browser                                                    |
| username          | Name of the user, if provided                                                |

Example:

    {
       "time":"2022-01-21T09:35:18.161544875",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"leader_joined",
       "details":{
          "client_index":0,
          "user_params":{
             "avatar":"https://www.gravatar.com/avatar/eebed148d8e8f16d071e588748151950?d=404&s=56",
             "email":"inessa@surfly.com",
             "follower_prefix":"",
             "ip":"::ffff:95.97.8.146",
             "name":"Surfly Test",
             "queue_index":"",
             "user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
             "username":"Surfly Test"
          }
       }
    }

#### invitation_sent

The event contains information about the session invites that have been sent via email or sms.  

|-----------|------------------------------------------------------|
|           | **"details"**                                        |
| invite_by | "sms" or "email"                                     |
| to        | Phone number or email depending on "invite_by" field |

Example:

    {
       "time":"2022-01-21T09:35:48.4645764",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"invitation_sent",
       "details":{
          "invite_by":"email",
          "to":"test@surfly.com"
       }
    }

#### follower_joined

The event indicates the moment when a follower opens a follower's link. Event repeats for every follower in a session, with a different "client_index" for each follower.  

|-------------------|-----------------------------------------------------------------------------|
| **"details"**     |                                                                             |
| client_index      | Index of the user: always "0" for the leader and "1" and more for followers |
| **"user_params"** |                                                                             |
| avatar            | User's avatar grabbed from Gravatar, if provided                            |
| email             | Email address of the user, if provided                                      |
| follower_prefix   | Title follower is referred to: "Follower"                                   |
| ip                | IP address of the follower                                                  |
| name              | Name of the user, if provided                                               |
| queue_index       | Index of the queue, if provided                                             |
| user_agent        | Info about user's browser                                                   |
| username          | Name of the user, if provided                                               |

Example:

    {
       "time":"2022-01-21T09:36:19.432741282",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"follower_joined",
       "details":{
          "client_index":1,
          "user_params":{
             "avatar":"https://www.gravatar.com/avatar/72d0bf2a6f3210565fdf06cd8bdbe3cb?d=404&s=56",
             "email":"test@surfly.com",
             "follower_prefix":"",
             "ip":"::ffff:95.97.8.146",
             "name":"Test",
             "queue_index":"bWoZp0KKntjvCPLAVsbQT3IA",
             "user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
             "username":"Test"
          }
       }
    }

#### follower_left

The event indicates the moment when a follower leaves a session. It contains more information about the follower, for example what device the user used to participate in the session.  

|-----------------------|----------------------------------------------------------------------------------------------|
| **"details"**         |                                                                                              |
| avatar                | User's avatar grabbed from Gravatar, if provided                                             |
| client_index          | Index of the user: always "0" for the leader and "1" and more for followers                  |
| color                 | Color of the follower's annotation tool and avatar (if no Gravatar provided)                 |
| country_code          | Country code based on ip                                                                     |
| deviceType            | "Desktop" or "mobile"                                                                        |
| email                 | Email address of the user, if provided                                                       |
| index                 | Client index: always "0" for the leader and "1" and more for followers                       |
| name                  | Name of the user, if provided                                                                |
| online                | Status of the user at the moment of the event: "online" or "offline"                         |
| screenHeight          | Screen height in pixels                                                                      |
| screenWidth           | Screen width in pixels                                                                       |
| ua                    | Info about user's browser, "user_agent"                                                      |
| webrtcEnabled         | Whether videochat was used                                                                   |
| **"drawingSettings"** |                                                                                              |
| color                 | Annotation/drawing tool color                                                                |
| enabled               | Whether enable_drawing option has been on                                                    |
| mode                  | "Permanent" or "temporary" drawing mode                                                      |
| timeout               | Amount of time in seconds when an annotation starts disappearing in "temporary" drawing mode |
| width                 | Width of the annotation tool                                                                 |
| **"user_params"**     |                                                                                              |
| avatar                | User's avatar grabbed from Gravatar, if provided                                             |
| email                 | Email address of the user, if provided                                                       |
| follower_prefix       | Title follower is referred to: "Follower"                                                    |
| ip                    | IP address of the follower                                                                   |
| name                  | Name of the user, if provided                                                                |
| queue_index           | Index of the queue, if provided                                                              |
| user_agent            | Info about user's browser                                                                    |
| username              | Name of the user, if provided                                                                |

Example:

    {
       "time":"2022-01-21T09:42:03.209678752",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"follower_left",
       "details":{
          "avatar":"https://www.gravatar.com/avatar/72d0bf2a6f3210565fdf06cd8bdbe3cb?d=404&s=56",
          "client_index":1,
          "color":"blue",
          "country_code":"NL",
          "deviceType":"desktop",
          "drawingSettings":{
             "color":"default",
             "enabled":false,
             "mode":"temporary",
             "timeout":5,
             "width":15
          },
          "email":"test@surfly.com",
          "index":1,
          "name":"Test",
          "online":true,
          "screenHeight":677,
          "screenWidth":1765,
          "ua":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
          "user_params":{
             "avatar":"https://www.gravatar.com/avatar/72d0bf2a6f3210565fdf06cd8bdbe3cb?d=404&s=56",
             "email":"test@surfly.com",
             "follower_prefix":"",
             "ip":"::ffff:95.97.8.146",
             "name":"Test",
             "queue_index":"bWoZp0KKntjvCPLAVsbQT3IA",
             "user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
             "username":"Test"
          },
          "webrtcEnabled":true
       }
    }

#### session_end

The event that every Surfly session ends with. One of the useful metrics here is session duration.  

|--------------|-----------------------------------------------|
|              | **"details"**                                 |
| duration     | The duration of the session                   |
| participants | Number of participants (leader and followers) |

Example:

    {
       "type":"session_end",
       "time":"2022-01-21T09:42:11.156199",
       "details":{
          "duration":"0:06:53.574883",
          "participants":2
       }
    }

### Events related to control switching

#### control_gained

The event indicates the moment when a user gets control inside a session.  

|----------------|-----------------------------------------------------------------------------|
|                | **"details"**                                                               |
| "client_index" | Index of the user: always "0" for the leader and "1" and more for followers |
| "username"     | Name of the user, if provided                                               |

Example:

    {
       "time":"2022-01-21T09:40:11.22883706",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"control_gained",
       "details":{
          "client_index":0,
          "username":"Surfly Test"
       }
    }

#### control_switch

The event indicates the moment when control over a session is switched to a different user.  

|----------------|-----------------------------------------------------------------------------|
|                | **"details"**                                                               |
| "client_index" | Index of the user: always "0" for the leader and "1" and more for followers |
| "controller"   | The user in control: "leader" or "follower"                                 |

Example:

    {
       "time":"2022-01-21T09:40:29.268323917",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"control_switch",
       "details":{
          "client_index":1,
          "controller":"follower"
       }
    }

#### control_switch_request

The event indicates the moment when a user requests control over a session.  

|----------------|-------------------------------------------------------------------------------------------------|
|                | **"details"**                                                                                   |
| "request_type" | The type of control switch request: "control requested", "control granted" or "control refused" |

Example:

    {
       "time":"2022-02-22T16:14:59.547790164",
       "session_id":"f50e8zrJcoKHRiWoSU0IGD2bGw",
       "type":"control_switch_request",
       "details":{
          "request_type":"control requested"
       }
    }

### Events related to co-browsed content

#### relocate_start

The event indicates the moment when a web page is opened inside a session.  

|-------|-----------------------------------------|
|       | **"details"**                           |
| "url" | The URL of the web page that was opened |

Example:

    {
       "time":"2022-01-21T09:35:18.723581484",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"relocate_start",
       "details":{
          "url":"https://www.bing.com:443/?toHttps=1&redig=5DFED92F32D84B2B95CA97E8E9838E74"
       }
    }

#### navigate

The event indicates the moment when a new Surfly tab is opened inside a session.  

|------------|-------------------------------|
|            | **"details"**                 |
| "url"      | The URL opened in the new tab |
| "username" | Name of the user, if provided |

Example:

    {
       "time":"2022-01-21T09:36:33.830090877",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"navigate",
       "details":{
          "url":"http://wikipedia.org",
          "username":"Surfly Test"
       }
    } 

#### switch_active_tab

The event indicates the moment when a user switches to a different Surfly tab.  

|-------|----------------------------------------------|
|       | **"details"**                                |
| "url" | The URL opened in the tab that was activated |

Example:

    {
       "time":"2022-01-21T09:38:44.047847047",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"switch_active_tab",
       "details":{
          "url":"https://fr.wikipedia.org/wiki/Toshiko_Ueda"
       }
    }

#### click

The event is raised when the user in control clicks on an element inside a session.  

|--------------|-------------------------------------------------------------|
|              | **"details"**                                               |
| "xpath"      | Xpath of the specific element where the click was detected  |
| "attributes" | The attributes of the element, if known, e.g., "href", "id" |
| "node_name"  | The name of the node where the click was detected           |

Example:

    {
       "time":"2022-01-21T09:41:10.886314778",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"click",
       "details":{
          "attributes":{
             "class":"forecast--high"
          },
          "node_name":"p",
          "xpath":"/html/body/div[6]/div/section[4]/div/div/div[2]/div/section[3]/div/div/div[2]/ul/li/a/p"
       }
    }

#### input_change

The event is raised for \<input\>, \<select\>, and \<textarea\> elements when an alteration to the element's value is committed by a user.  

|------------------------------|-----------------------------------------------------------------------------------|
|                              | **"details"**                                                                     |
| xpath                        | Xpath of the specific element where the change was detected                       |
| **"attributes"**             | The attributes of the element, if known, e.g., "id", "class", etc                 |
| value                        | The value of the element, if known                                                |
| node_name                    | The name of the node where the change was detected                                |
| **"parent_form_attributes"** | The attributes of the parent element, if known, e.g. "action", "class", "id", etc |

Example:

    {
       "time":"2022-01-21T09:41:13.943887335",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"input_change",
       "details":{
          "attributes":{
             "name":"scope"
          },
          "node_name":"input",
          "parent_form_attributes":{
             "action":"https://search.bbc.co.uk/search",
             "class":"b-f",
             "id":"orb-search-form",
             "method":"get"
          },
          "value":"all",
          "xpath":"/html/body/header/div/div/div[3]/form/div/input"
       }
    }

#### document_edit

The event is raised when an uploaded file is being edited with Surfly's document editor.  

|-------------------|--------------------------------------------|
| **"details"**     |                                            |
| action            | Type of edit action, e.g. "add", "remove"  |
| **"annotations"** |                                            |
| author            | Author of the edit                         |
| id                | Change id                                  |
| tool              | Tool name, e.g. "AnnotationCreateFreeHand" |
| type              | Tool type, e.g. "FreeHand"                 |

Example:

    {
       "time":"2022-02-21T09:39:04.682133863",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"document_edit",
       "details":{
          "action":"add",
          "annotations":[
             {
                "author":"Inessa Li (inessa@surfly.com)",
                "id":"204f7a41-085c-a44c-97f7-914e541f4c42",
                "tool":"AnnotationCreateFreeHand",
                "type":"Free Hand"
             }
          ]
       }
    }

#### submit

The event is raised on a form submission by a user.  

|------------------|---------------------------------------------------------------|
|                  | **"details"**                                                 |
| xpath            | Xpath to the specific form that was submitted                 |
| node_name        | The name of the node of the form that was submitted           |
| **"form_data"**  | The data submitted through the form                           |
| **"attributes"** | The attributes of the form, if known, e.g., "action", "class" |

Example:

    {
       "time":"2022-02-21T09:37:12.661682659",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"submit",
       "details":{
          "attributes":{
             "action":"/w/index.php",
             "class":"wvui-typeahead-search__form",
             "id":"searchform"
          },
          "form_data":{
             "search":"",
             "title":"Spécial:Recherche",
             "wprov":"acrw1"
          },
          "node_name":"form",
          "xpath":"//*[@id=\"searchform\"]"
       }
    }

#### screenshot_generated

The event is raised when an automated screenshot has been taken inside a session.

Example:

    {
       "time":"2022-01-17T11:18:54.491262954",
       "session_id":"f50wknEOkaaDQgWDgOw3J9wdwA",
       "type":"screenshot_generated",
       "details":null
    }

#### webrtc_stream_exception

The event is raised when a WebRTC screenshot flow has been disrupted by the user - they might have selected a wrong source for screenshots.

This is specific to [Screenshots with webRTC functionality](https://help.surfly.com/en/screen-sharing).  

|---------|---------------------------------------------|
|         | **"details"**                               |
| message | exception message, e.g. "Permission Denied" |

Example:

    {
       "time":"2022-02-22T15:52:23.381489885",
       "session_id":"f50V2TDKHzbjTWyZD0iCYLOLUg",
       "type":"webrtc_stream_exception",
       "details":{
          "message":"Permission denied"
       }
    }

#### webrtc_stream_ended_by_user

The event is raised when a WebRTC screenshot flow has been disrupted by the user - they might have prematurely ended the WebRTC stream from which screenshots are made.

This is specific to [Screenshots with webRTC functionality](https://help.surfly.com/en/screen-sharing).

Example:

    {
        "time":"2022-02-22T15:52:07.102701986",
        "session_id":"f50V2TDKHzbjTWyZD0iCYLOLUg",
        "type":"webrtc_stream_ended_by_user",
        "details":null
    },

#### document_share

The event is raised when a document is shared inside a session.  

|-----------|--------------------------------------|
|           | **"details"**                        |
| file_name | The name of the file that was shared |
| url       | URL of the shared file               |

Example:

    {
       "time":"2022-01-21T09:38:44.047738283",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"document_share",
       "details":{
          "file_name":"Screenshot_20220220-173133.jpg",
          "url":"https://session50.surfly.com/blob/f50mG8gS5llRCOX3cGKnTajkA/.../Screenshot.jpg"
       }
    } 

#### file_download

The event is raised when a document is downloaded inside a session.  

|-----------|----------------------------------------------|
|           | **"details"**                                |
| file_name | The name of the file that was downloaded     |
| user_name | The name of the user who downloaded the file |

Example:

    {
       "time":"2022-02-21T09:39:08.955836988",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"file_download",
       "details":{
          "file_name":"Screenshot_20220220-173133.jpg.pdf",
          "user_name":"Surfly Test"
       }
    }

#### chat

The event is raised when a chat message is sent inside a session.  

|----------|-------------------------------|
|          | **"details"**                 |
| username | Name of the user, if provided |
| message  | The message that was sent     |

Example:

    {
       "time":"2022-01-21T09:39:29.528786438",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"chat",
       "details":{
          "message":"ok",
          "username":"Test"
       }
    }

#### video_chat_enabled

The event indicates when a user joins a videochat.  

|--------------|-----------------------------------------------------------------------------|
|              | **"details"**                                                               |
| client_index | Index of the user: always "0" for the leader and "1" and more for followers |

Example:

    {
       "time":"2022-01-21T09:37:31.150039967",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"video_chat_enabled",
       "details":{
          "client_index":0
       }
    }

#### video_chat_archiving_started

The event indicates when a user joins a videochat.  

|--------------------|--------------------|
|                    | **"details"**      |
| opentok_session_id | Opentok session ID |

Example:

    {
       "time":"2022-01-21T09:37:31.150039967",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"video_chat_enabled",
       "details":{
          "opentok_session_id":"opentok_foo_123"
       }
    } 

#### pause_started

The event contains information when the session pause started.  

|--------------|---------------|
|              | **"details"** |
| client_index | Client index  |

Example:

    {
       "time":"2022-01-21T09:39:44.48056932",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"pause_started",
       "details":{
          "client_index":0
       }
    } 

#### pause_ended

The event contains information when the session pause ended.  

|--------------|---------------|
|              | **"details"** |
| client_index | Client index  |

Example:

    {
       "time":"2022-01-21T09:39:44.488274147",
       "session_id":"f50mG8gS5llRCOX3cGKnTajkA",
       "type":"pause_started",
       "details":{
          "client_index":0
       }
    }

### Custom events

#### client_log

The event contains custom variables that were saved to the audit logs during a session. To use custom variables, you need to use our JavaScript API.

You can supply any information to audit logs via client_log event.

For example, a simple line of code like below might help you to add specific info to the Audit logs, perhaps about products placed into the shopping cart.

    Session.log({Added item: product_ID +" in the basket with value " + product_value})

Check out our [Javascript API reference](https://docs.surfly.com/category/javascript-api-1) for more information.  

|-----|----------------------------------------------------------------------------------|
|     | **"details"**                                                                    |
| msg | The list of variables with values stored during the session: "var0", "var1" etc. |

---
language: "en"
---
# Implementation

Below is the list of guides that can help you set up Surfly  
[Standard to Custom: Feature Variations and Implementation Considerations](https://help.surfly.com/en/from-standard-to-custom-feature-variations-and-imp.md)
* [Salesforce Integration Guide](https://help.surfly.com/en/salesforce-integration-guide.md)
* [How do I start a Surfly co-browsing session on Intercom, Olark, or Zendesk?](https://help.surfly.com/en/how-do-i-start-a-surfly-co-browsing-session-on-int.md)

---
language: "en"
---
# How are videochat minutes calculated?

Surfly's videochat is based on WebRTC technology.

## WebRTC

Web Real-Time Communication, or WebRTC, allows video and audio communication to happen on web pages.

WebRTC streams are a sequence of information that are made available from time to time. This information is mostly the video and audio data.

**Publishers** are the sources streaming the video/audio, while **subscribers** are the ones receiving it.

During the video chat, the users are both subscribers and publishers.

## Videochat minutes calculation formula

Videochat minutes are charged per *subscribed* minute, the calculation for which is:  

|----------------------------------------------------------------------------------|
| *videochat duration \* nr. of session participants \* nr. of subscribed streams* |

***Videochat duration*** is the period of time during the session when the videochat was enabled.

***Number of session participants*** - a number of users present during the session.

***Number of subscribed streams*** - number of session participants minus one.

For example, if session duration is 20 min and there are 5 participants, all of which had videochat enabled for 15 min, then the videochat minutes will be:  

|------------------------------|
| *15 \* 5 \* 4 = 900 minutes* |

Whereas, if session duration is 20 min and there are 2 participants, all of which had videochat enabled for 15 min, then the videochat minutes will be:  

|-----------------------------|
| *15 \* 2 \* 1 = 30 minutes* |

---
language: "en"
---
# Adding & managing users

A Surfly user can be assigned one of the three privilege levels - [***an "Agent" , a "Manager" or an "Admin***](https://help.surfly.com/en/what-s-the-difference-between-an-admin-a-manager-a.md)***"***

If you have the *"Admin"* or *"Manager"* privileges, you can add or manage users to your account from the *"Agents"* page in your dashboard:

1. Fill in the fields with email address and name of the user and click *"Add agent"*

2. The user will then get an activation email on the email address that you've specified, that allows them to create a password for their account.

3. Users are provided *"Agent"* level privilege by default. You can also modify their *"Role"* to adjust their user privilege, depending on your privilege.

Note:- If you activate them from the dashboard instead, the activation email gets nullified and they will not be able to set up a password for themselves. In that case, they can make use of [Forgot your password?](https://app.surfly.com/password/reset/) option to set up a password.

## Read about different user privilege levels [here \>\>](https://help.surfly.com/en/how-to-add-users-programmatically)

### Read about adding users in bulk [here \>\>](https://help.surfly.com/en/how-to-add-users-programmatically.md)

---
language: "en"
---
# How do I add Surfly's co-browsing to my website?

If you want to be able to start co-browsing directly from your website, you have to add the Surfly snippet to each page you want to be able to start a session from. If you have access to the code, you can add the below script right above the closing \</body\> tag of your HTML.

If you use a website builder, you probably have an option there where you can add code to your web pages.

You can also use a Tag Manager to add the Surfly snippet to your website.

    <script>
    (function(s,u,r,f,l,y){s[f]=s[f]||{init:function(){s[f].q=arguments}};
    l=u.createElement(r);y=u.getElementsByTagName(r)[0];l.async=1;
    l.src='https://surfly.com/surfly.js';y.parentNode.insertBefore(l,y);})
    (window,document,'script','Surfly');

    var settings = {
    // Surfly session options can be set here, or at the Company/Plan levels.
    widget_key: '<Widget_Key>',
    require_password: false,
    };

    Surfly.init(settings, function(initResult) {
        if (initResult.success) {
            // API calls can now be made!
            if (!Surfly.isInsideSession) {
                Surfly.button();
            }
        }
        else{
            console.log("Surfly was unable to initialize properly.")
        }
    });
    </script>

**Should I put the Surfly snippet on every page of my website?** [**Read here \>\>**](https://help.surfly.com/en/should-i-put-the-surfly-snippet-on-every-page-of-m.md)

---
language: "en"
---
# How do I clear the cache?

When you make changes to the implementation of Surfly on your website, we recommended that you make sure the browser cache is cleared. This is important to ensure that the browser has not cached any old data or versions when you start a new co-browsing session.

You can do this by opening the developer tools in Chrome, then go to the "Network" tab and check the box next to "Disable cache". This will set a header that will also make sure our server cache is cleared.

---
language: "en"
---
# Start a Surfly session

To start a Surfly co-browsing session, log into your Surfly account. Then enter the URL of the website you'd like to visit and click 'Start session.' You can then send the link to someone to invite them to co-browse with you.

Keep in mind that this may depend on your workflow, and whether or not co-browsing has been integrated on your company's website or CRM system. If this isn't immediately clear, please ask someone on your team.

If you want to get a quick overview of what Surfly is about, you can take a look at this short video:  
[https://www.youtube.com/watch?v=5LNc1C1fE1Q\&t=3s](https://www.youtube.com/watch?v=5LNc1C1fE1Q&t=3s)

---
language: "en"
---
# How do I start a Surfly co-browsing session on Intercom, Olark, or Zendesk?

You can start a co-browsing session by typing \^surfly in the chat widget. If video chat has been enabled by your company, then you can also type \^video if you want to start a co-browsing session together with video chat. Both triggers will automatically start a co-browsing session on the customer's side. Just as described above, you can take the call from the queue on your Surfly dashboard.

---
language: "en"
---
# How is co-browsing different from screen sharing?

Co-browsing is browser-based, meaning that you only share the browser instead of sharing your entire screen (which is the case with screen sharing).

Both technologies come with their own approaches. Co-browsing solutions like Surfly use a Javascript approach, which means that the HTML, Javascript, and CSS of a website are synchronized between users. This allows you to extend the online experience to multiple users, and therefore add a multi-user experience on your website.

Screen-sharing solutions are pixel-based, the drawback of this approach being that screen updates are slow and of low quality. Most screen-sharing tools require external software to be installed by users. This makes it unsuitable for most web situations, as people are often unwilling to install extra software that circumvents the browser's security measures.

Further, screen-sharing opens you up to chances of unwanted private information leak. On the other side, with Surfly Cobrowsing you can even mask specific parts of the web content you want to share with others.

---
language: "en"
---
# How is Surfly different from other co-browsing solutions?

* Surfly is safe; all connections to Surfly are encrypted and security tokens or passwords from *Tab-owner(s)* will never be sent to the other participants. The secure proxy allows 'logged-in sessions'. This means that secure sessions with session-specific resources just work. Next, we automatically make sure that all content will function correctly with the co-browsing session: even those that are not served from the same domain, such as widgets or plugins.

* With Surfly there is no need to install any plugin or software; it works within the browser tab.

* We do not share the state between the two different browsers, but we only send over the visual changes of one to the other. This makes our approach much more secure and robust.

* At Surfly we make sure that what the *Tab-owner* sees on their screen will be matched by all other participants. This includes scroll position and the state of responsive websites.

![Schermafbeelding 2019-01-04 om 15.26.19.png](https://help.surfly.com/__attachments/a_b718ba5374ab58f458e05e76080bc3c1bfd562ffed4bfa948812e05bb5f613e6/Schermafbeelding%202019-01-04%20om%2015.26.19.png?cb=5cb18bf077edff25911a238d06a3b039)

---
language: "en"
---
# How many Surfly sessions can I create?

This information only applies to accounts set up with self-managed subscription via a bank card.

The free plan has a limit of five sessions per month.

All paid plans come with an unlimited number of sessions.

---
language: "en"
---
# Under the Hood

* [Technology](https://help.surfly.com/en/the-surfly-proxy.md)
* [Architecture](https://help.surfly.com/en/architecture.md)
[Deployment Models](https://help.surfly.com/en/deployment-models.md) [Privacy \& Security](https://help.surfly.com/en/data-processing-protection.md)
* [Service Level Objectives](https://help.surfly.com/en/service-level-objectives.md)

---
language: "en"
---
# Adding users programmatically

In certain cases, you may need to add users programmatically instead of using the [++Agents++](https://app.surfly.com/agents/profile/) page on your dashboard. Listed below are the 2 reasons you might need to do so:

1. **Addition of users without email verification**and/or

2. **Addition of users in bulk**

The solution is to add users via [++REST API call for creation of agents++](https://docs.surfly.com/api/v2/#tag/Agents/operation/Createanewagent). This call is the obvious choice if only a few agents need to be created. You can simply make this call from tools like Shell/Terminal/Postman. There are no invite or activation emails sent out to the users if they are added through the REST API.

But, if the number of users to be added to an account are greater than 20, then doing it programmatically is more efficient. To do so, you can either use a tool like Postman and create a loop of POST requests from your list of users' information, or you can create a script to do the same.

Below is a sample script that you can use for this purpose.

*Note: You need to have experience using command line interface on your computer. (Terminal/Shell). You can create your own script or use the one below. It is a python script and you will need a few packages/modules installed on your machine. The following should suffice: Python, PIP, Request module.*

Step 1. Make sure you have the below data in `.csv` format

The fourth column "**role** " is optional. If not specified, the role "**agent**" is applied to all the users.  
![Screenshot 2021-09-17 at 11.43.54.png](https://help.surfly.com/__attachments/a_8e413066285bcfc246f4679251780a1f9d383c97f0f3d5c753c4975fae1ae383/Screenshot%202021-09-17%20at%2011.43.54.png?cb=4c9c6c83c25e48c24f69b0558cfbdac2)

Step 2. Once you have this sheet ready you can use the below script with minor changes

*- Please update the* `api_key`*of the company you want to add users to*

*- Please update the file name* `'USER_LIST.csv'`*with the file name from the previous step (case sensitive)*

*- If the script is to be run for a private server, then* `surfly.com` will need to be changed to `your-domain.com`

    import csv
    import requests

    url = 'https://surfly.com/v2/agents/?api_key=9deXXXXXXXXXXXXXXXXXXX318'

    with open('USER_LIST.csv', mode='r') as csv_file:
      csv_reader = csv.DictReader(csv_file)
      for row in csv_reader:
        print(row)
        create_agent = requests.post(url, data = row)
        print(create_agent.text)

Step 3. Run the updated script!

User already existing in the Surfly database will be skipped with the below message:

`{"error": "Invalid input: A user with this email already exists"}`

---
language: "en"
---
# How to export HAR dump from web browser.

Below are steps to export a HAR (HTTP Archive) dump from your Chrome or Microsoft Edge Web browser, follow these steps:

**Step 1** : Open Chrome Web browser and click on three dot menu in top right corner.

![image-20251205-104359.png](https://help.surfly.com/__attachments/a_91f7f910d505c69ce0ab700a60b73428ac26c83176f5d5f84315fb42c3d27107/image-20251205-104359.png?cb=f9626d8a91064b898b6a5e1ce8d741f3)

**Step 2** : Click on "**More tools** " and select "**Developer tools** ".

![image-20251205-104316.png](https://help.surfly.com/__attachments/a_1132f52085592e2cc931556984c34dcd6c68b43da475e95acbbcbd7e637abfd2/image-20251205-104316.png?cb=d9604dbd8d25c583598de78a67bf604a)

**Step 3** : Click on "**Network** " tab and select check box "**Preserve log** " and "**Disable cache**".  
![image-20251205-103949.png](https://help.surfly.com/__attachments/a_f9b4a38cb8eddb9f0233c7aac4db88a4f815ef4775ef92f687b586f6ba57f2f2/image-20251205-103949.png?cb=5a5563fd016f43bfc61bdc9006946a93)

**Step 4** : Click on the "**Settings** " button.

![image-20250530-100519.png](https://help.surfly.com/__attachments/a_6c17039a7287e92cc9bec5cbfa4376dd5a6f34857d0c34a7d0fdad2ad511c711/image-20250530-100519.png?cb=88786fd64c3de699ef1e7126ff28b813)

**Step 5** : Navigate to the **Preferences** section and scroll down to the Network settings.

Check the box labeled "**Allow to generate HAR with sensitive data**".  
![image-20250530-100549.png](https://help.surfly.com/__attachments/a_ca9321a9bfac0296ae107ca458867e37bbca26bf9384b401db9300cbc1980bea/image-20250530-100549.png?cb=02de232b3e7ad507a0ae6ab67f43f23f)

**Step 6** : Close the **Settings** panel. Locate the **Export HAR** button in the Developer Tools. You will now see a small arrow on the button, indicating that the option to export with sensitive data is available.

![image-20250530-100621.png](https://help.surfly.com/__attachments/a_3060db827eeb5d437e5aa54b5ce7146b4bac4e9a6831a9a99ad08b9890fc0f9b/image-20250530-100621.png?cb=a556e9a0eb3d6f44fbeddfe3efdffd34)

**Step 7** : Reproduce the issue inside the Surfly session. After doing so, select the option "**Export HAR (with sensitive data)...**" to begin exporting an unsanitized HAR file.

Repeat the same steps outside the Surfly session and export another unsanitized HAR file.

*Note: By default, Chrome exports a sanitized HAR file. To export an unsanitized file, always* ***long-click*** *the Export button and choose the appropriate option.*  
![image-20250530-100747.png](https://help.surfly.com/__attachments/a_1fbf4fcd70b61f472a61fe22d34b3bd3d94c93f971978dda6561d8d5fc2ca274/image-20250530-100747.png?cb=133027d5e55f0f5471cc5cebd7e85197)

**Final Step** : Once both HAR dumps (from inside and outside the Surfly session) are collected, please forward them to Surfly Support at [support@surfly.com](mailto:support@surfly.com).

---
language: "en"
---
# How to get a demo and a free trial?

Discover the power of Surfly today. Schedule a free demo to explore all the features and benefits that Surfly can offer you.

Our team of experts will guide you through the setup process and help you start your free trial right away.

[**Contact us now**](https://www.surfly.com/request-a-demo/) to take the first step towards a more seamless and efficient online experience.

---
language: "en"
---
# How to integrate Surfly

Now it's time to start implementing Surfly. This can be done in three ways:

* through a [++basic integration with the admin panel++](https://docs.surfly.com/surfly/technology#how-to-integrate-surfly)

* with the [++Javascript API++](https://docs.surfly.com/category/javascript-api)

* and/or with the [++REST API++](https://docs.surfly.com/surfly/rest_api)

How you choose to implement our API depends on how deeply you want to integrate it into your website and your workflows. In [++sales++](https://www.surfly.com/platform) for instance, you might want to use Surfly to demo your website or product and make this a more captivating and interactive experience for all users. This could already be done through an integration with the admin panel or a basic Javascript implementation. The same goes for advisors, but maybe you would like to create your own landing page that fits your brand perfectly and start co-browsing from there.

In [++support++](https://www.surfly.com/contact-centers/), you might want to co-browse together with your client to guide them through the website, and create designs together or help them fill in forms. For the latter you might have to deal with sensitive information, so Surfly provides the option of limiting co-browsing to certain pages on your website, or to mask data in form fields for other users.

You could also integrate Surfly into your already implemented helpdesk software using the REST API. You might want to add your client's location to the queue based on their IP-address for instance, so that your helpdesk agents have some background info when they join them in a Surfly session.

Surfly could also be used for educational purposes, as a lot of learning platforms use our API to create an online class room. Or maybe you would like to add Surfly as a social tool to your website to allow your users to shop together.

Surfly can be integrated in many ways, together with other software solutions. Our API is completely rebrandable according to your wishes, and it can even be made into a fully transparent layer that lays on top of your website. But most importantly, for us, safety comes first, so all Surfly sessions are HTTPS secured. Also, we even offer the option of installing the servers for you on premise.

---
language: "en"
---
# Huddle Mode

'Huddle Mode' revolutionizes collaborative sessions by removing the need for a single presenter. Every participant can now choose what they want to see, fostering a truly collaborative experience akin to popular tools like Figma, Miro, and Mural.

To get started, simply disable the *Presenter mode* as a [**host**](https://help.surfly.com/en/what-do-leader-and-follower-mean-in-a-surfly-sessi.md) by toggling the 'Presenter mode' option in the [**Participants' List**](https://help.surfly.com/en/new-way-to-access-the-participant-list-in-a-sessio.md).  
![2qwqwqwqw.gif](https://help.surfly.com/__attachments/a_dd809026b54c123604782eee1b4e039f53ebcc6b3b6a1aa78cf58f467ecd929f/2qwqwqwqw.gif?cb=b889f46fff7415063a92a1d929095844)

Each participant can then open their own content by clicking the '+' button in the Surfly tab bar and effortlessly switch between active participants by selecting their [**profile picture**](https://help.surfly.com/en/customizing-user-icons-with-free-gravatar-integrat.md).  
![1qwqwqwqw.gif](https://help.surfly.com/__attachments/a_b7216615dd028b12dee1a776f6d9dde77a85cc2c3370506edd6cc04055bd2220/1qwqwqwqw.gif)

In terms of security and performance, 'Huddle Mode' ensures high-quality and low-latency collaboration by rendering web applications in each participant's browser without relying on video streaming or remote rendering.

## It's important to note the following differences from Surfly's Presenter mode:

* Control/interaction switching is not possible in 'Huddle Mode.'

* Avoid combining session recording with 'Huddle Mode' due to limited control over recorded content.

* Participants can only follow the active content of another participant. When a participant starts following another participant, their own content is no longer considered active and cannot be followed by other participants. However, participants can always switch back to their own content whenever they choose to.

^Please refer to the following note for additional details, illustrated through an example.^

* ^If participant A is following participant B, participants C and D cannot follow participant A. However, both participants C and D can follow participant B. Furthermore, participant C can follow participant D, and participant D can follow participant C.^

* ^If participant A is already following participant B, and participant C starts following participant D, participant D can only follow participant B. If participant D tries to follow participant B, participant C will switch back to their own view.^

## The introduction of 'Huddle Mode' unlocks endless possibilities for innovative use cases. Here are a few examples to inspire you:

### Collaborative and Interactive Standups

Enhance your daily standup meetings by utilizing 'Huddle Mode' to facilitate seamless collaboration among participants. With 'Huddle Mode,' each individual can prepare and share content from their own logged-in web applications or projects, eliminating the hassle of constantly switching screens. This streamlined approach promotes efficient discussions and enables a more interactive standup experience.

### Online Classroom Experience

With 'Huddle Mode,' teachers can seamlessly transition from presenting material to creating an interactive online classroom. By disabling the presenter mode, students can open specific URLs and complete exercises while teachers monitor individual progress. This fosters active learning and enhances student engagement in the virtual classroom.

### Shared Shopping/Travel Booking

Bring your friends together in a session, where each participant can search for exciting locations, rooms, or travel options individually. Utilize video chat and switch between participants' views to understand their preferences and engage in discussions about the choices. Enjoy a collaborative and interactive shopping or travel booking experience with your friends, all in one virtual space.

---
language: "en"
---
# I can only browse Wikipedia with Surfly, what's going on?

You'll need to activate your account before you can co-browse with Surfly.

Please look for the activation email you received after registering, and click the link to activate your account.

---
language: "en"
---
# Integration & Customizations

* [How to integrate Surfly](https://help.surfly.com/en/how-to-integrate-surfly.md)
[How do I add Surfly's co-browsing to my website?](https://help.surfly.com/en/how-do-i-add-surfly-s-co-browsing-to-my-website.md) [Surfly in your Local Language](https://help.surfly.com/en/translate-ui-surfly-in-your-local-language.md) [Surfly Webhooks: Customisation, Notifications, and Integration](https://help.surfly.com/en/surfly-webhooks-customisation-notifications-and-in.md)

---
language: "en"
---
# Introduction

* [What is Surfly?](https://help.surfly.com/en/what-is-surfly.md)
* [What can I do with Surfly?](https://help.surfly.com/en/what-can-i-do-with-surfly.md)
* [Why should my company use Surfly?](https://help.surfly.com/en/why-should-my-team-use-surfly-s-co-browsing.md)
* [How is co-browsing different from screen sharing?](https://help.surfly.com/en/how-is-co-browsing-different-from-screen-sharing.md)
* [How is Surfly different from other co-browsing solutions?](https://help.surfly.com/en/how-is-surfly-different-from-other-co-browsing-sol.md)
* [What is Surfly's Universal Cobrowsing and why is it universal?](https://help.surfly.com/en/what-is-surflys-universal-cobrowsing-and-why-is-it.md)
* [How to get a demo and a free trial?](https://help.surfly.com/en/how-to-get-a-demo-and-a-trial.md)

---
language: "en"
---
# Is Surfly GDPR compliant?

**Short answer: Yes.**

There are two ways in which we process data: directly and indirectly. But for us, that applies even more than for other companies. Why? On the one hand, we process data through our own website: [++https://www.surfly.com++](https://surfly.com/) (check out our [++privacy++](https://www.iubenda.com/privacy-policy/25094004)- and [++cookie++](https://www.iubenda.com/privacy-policy/25094004/cookie-policy) policies), and [++https://surfly.com++](https://surfly.com/). These domains are hosted on different servers, and the latter is used for the Surfly dashboard.

## Your personal information

You can only get access to the dashboard if you have a Surfly account. When you sign up with your name, company name, and email address, this is the only information we store about you. When you delete your account, your personal info will be removed from our database. If you sign up for a paid plan and enter your credit card info, we send this to [++Chargebee++](https://www.chargebee.com/security/) and they handle the rest.

### Your session data

With indirectly, we refer to our proxy server. All requests made during a co-browsing session go through our servers.

What does this mean with regards to GDPR?

* When a Surfly co-browsing session is started on a website, Surfly sets one cookie. In this, we store the session ID, and the cookie expires when the co-browsing session is ended.

* All other cookies set during co-browsing go through our proxy and are therefore cookies that actually come from the websites that are being co-browsed. The responsibility of regulating these cookies belongs to those respective websites.

* We don't store user data.

[Next Page](https://help.surfly.com/llms-full.txt/1)
