> For the complete documentation index, see [llms.txt](https://everyday-digital.gitbook.io/falkor-dev-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://everyday-digital.gitbook.io/falkor-dev-docs/pathways/webtracking/javascript-api.md).

# Serverless

The **Web Tracking API** allows for tracking of a [pathway](https://docs.falkor.io/pathways/create-a-pathway) activity outside of your app. This option is **perfect if your web activity is server-less,** or if it is a **single-purpose** interactive experience. Examples of these could be web games, static websites, or stand-alone learning packages.

In a **serverless** scenario, the **platform acts as the** **server backbone** which allows you to **push and pull data** for a user on a web activity without the need for server-side technologies (e.g database or server-side languages).

### Examples of Serverless Web Activities

* **Web Game.** You have built a web game that you would like to add as a pathway activity. You want users to complete the game / earn a certain score in order for the pathway activity to be considered complete/fulfilled.<br>
* **Single Website Page OR Web App.** You have developed an interactive experience and want users to complete certain actions&#x20;

  in order for the pathway activity to be considered complete/fulfilled.<br>
* **E-Learning/Online Module.** You have developed an e-learning module that is not hosted in a Learning Management System (LMS) and want users to complete the module in order for the pathway activity to be considered complete/fulfilled.

## JavaScript Web Tracking

### JavaScript SDK

The JavaScript SDK is JavaScript implementation of the existing endpoints for the web tracking API. For more complex integrations we recommend reviewing the curl [push](/falkor-dev-docs/pathways/webtracking/server-api.md#push-data) / [pull](/falkor-dev-docs/pathways/webtracking/server-api.md#pull-data) endpoints provided in [server-side platforms](/falkor-dev-docs/pathways/webtracking/server-api.md). These endpoints are used in the JavaScript SDK.

<table><thead><tr><th width="150.062656641604"></th><th></th></tr></thead><tbody><tr><td><strong>Platform</strong></td><td><strong>Hosted URL</strong></td></tr><tr><td>Falkor</td><td>https://api.falkor.io/js-sdk/web-tracking.min.js</td></tr><tr><td>ByteKast UK</td><td>https://api.uk.bytekast.io/js-sdk/web-tracking.min.js</td></tr><tr><td>ByteKast SA</td><td>https://api.bytekast.io/js-sdk/web-tracking.min.js</td></tr><tr><td>Full Source</td><td>https://api.falkor.io/js-sdk/web-tracking/web.tracking.class.js</td></tr></tbody></table>

### Initialize the SDK

Before making use of **the pull and push method** you will need to **initialize the Javascript SDK** with your Pathway `publicKey`. The initialization automatically consumes & handles the `webToken` query parameter provided in the URL; this means you do not need to do anything with the generated `webToken`.

{% hint style="info" %}
The `publicKey` is provided when you add a [Web Activity](https://docs.falkor.io/pathways/pathway-activities/web-activity) on Pathways
{% endhint %}

```
<script src="js/web-tracking.min.js"></script> 
<script> 
    
    // Initialize WebTracking
    const webTrackingClient = initWebTracking({
        publicKey : `<Public API Key>`,
        baseURL   : `<Base API URL>`,
        /* Optional if just tracking visit */
        autoComplete: 1,
        /* Optional if just testing a single web Token */
        webToken : `<URL WebToken>`
    }); 
    
</script>
```

{% hint style="info" %}
**`autoComplete`** is only useful if you are simply wanting to complete the activity as the user visits the page.&#x20;

The **`webToken`** will automatically looked for in the URL. If you are testing and using one token you can also manually provide this parameter in the **`initWebTracking`** method. See how [Web Activity links work](/falkor-dev-docs/pathways/webtracking.md#how-it-works).
{% endhint %}

### Pull Data

To **pull data for the activity** you need to use the pull method. This method **will return a Promise** and should be done in an **asynchronous call**. The pull method **will contain previously pushed progression and data** for the user on a specific activity.&#x20;

```
/**
 * The function below pulls data from the platform. The response will 
 * contain progress, complete, result, data and user.
 * 
 * progress (Float): The stored user's progress percentage 0 - 100.
 * complete (Boolean): The stored user's completion state.
 * result (String): A stored result string (max 48 characters).
 * user (Object): Contains name, surname and icon.
 * data (Object): A stored data result.
 */

async function pullWebTrackingData(){

    let response = await webTrackingClient.pull();
    // Handle response
}
```

**The pull method makes a CURL call as shown below**

```
curl -X POST \
  v1/webtracking/pull \
  -H 'Public-API-Key: <Your Public API Key>' \
  -d '{
	"webToken" : "<webToken>"
}'
```

| Key          | Type                                                                |
| ------------ | ------------------------------------------------------------------- |
| **progress** | Float. The stored user's progress as a percentage of 0 to 100.      |
| **complete** | Int. The stored user's completion state. 1 = true, 0 = false.       |
| **user**     | Object. Contains information about the user, including a userToken. |
| **message**  | String. A stored message string (max 48 characters).                |
| **data**     | Object. A stored data result as a JSON string.                      |

###

### Push Data

To **push data to Falkor for the activity** you need to use the **"push" method**. This method **will return a Promise** and can be used **asynchronously**. When you push data, it **stores the information parsed**.

{% hint style="info" %}
The result parameter **allows for storing a short message**. This message is displayed on the user's Falkor app and creates an opportunity to display a summary of completion or progression to the user.
{% endhint %}

```
/**
 * The function below illustrates how to push data to the platform. The
 * required paramaters are complete and progress. You can optionally
 * set result and data.
 * 
 * progress (Float): Store the user's progress percentage 0 - 100.
 * complete (Int): Store the completion state 1 = true, 0 = false
 * result (String): Store a string (max 48 characters).
 * data (String): Store a valid json string.
 */

async function pushWebTrackingData(){

    let response = await webTrackingClient.push({
        /* Required */
        progress : 50,
        complete : 0,
        /* Optional */
        message : 'A custom string',
        data   : JSON.stringify({
            buttonPushes: 8
            
        })
    });
    
    // Response returns the updated state
}
```

**The push method makes a CURL call as shown below**

```
curl -X POST \
  v1/webtracking/push \
  -H 'Public-API-Key: <Your Public API Key>' \
  -d '{
    "webToken": "<webToken>",
    "progress": 50,
    "completed": 0,
    "message": "A custom string",
    "data": "{\"buttonPushes\":8}"
}'
```

| Key          | Type                                                           |
| ------------ | -------------------------------------------------------------- |
| **progress** | Float. Store the user's progress as a percentage of  0 to 100. |
| **complete** | Int. Store the completion state 1 = true, 0 = false.           |
| **message**  | Store a string (max. 48 characters).                           |
| **data**     | Store a valid json string (max. 65,535 characters).            |

## Full Example: "Button Game"

Here is a simple **example of using the Javascript Web Tracking API**. Along a pathway, the users are presented with a Web Activity that requires them to push a button 10 times in order to complete/fulfil the activity.

```
<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1" />


        <style>

            body,html{padding: 0; margin: 0; font-family: sans-serif; color:#fff}

            .counter{background:rgba(0,0,0,0.2); width:180px; height:180px; display: flex; align-items: center; justify-content: center; color: #fff; border-radius: 50%; font-size: 100px; margin:0 auto}

            .button{padding:15px; border-radius: 45px; background: rgba(0,0,0,0.2); color: #fff; text-align: center; margin:15px auto; max-width: 220px;}

            .avatar-icon{position: fixed; top:15px; right: 15px; width:48px; height:48px; background:white; border-radius: 50%;}



            body{background:#3498db}
        </style>

    </head>
    <body>

        <div class="avatar-icon"></div>

        <div style="height: 100vh; display:flex; align-items:center; justify-content:center">
            <div>
                <div class="counter">0</div>
                <div class="button">Push</div>

                <p class="message" style="text-align: center;">&nbsp;</p>
            </div>
        </div>

    </body>
    
</html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://beta.falkor.io/api/js-sdk/web-tracking.min.js"></script>
<script> 
    
    // Initialize WebTracking
    const webTrackingClient = initWebTracking({
        publicKey : `<Public API Key>`,
        baseURL   : `<Base API URL>`
    });

    console.log(webTrackingClient);
    
    // Button counter default state
    var counter = 0;
    
    
    $('.button').click(_ => {

        counter+=1;
        
        $('.counter,.counter-text').text(counter);
        
        // Check if the counter has been pressed 10 times
        let completed = counter >= 10 ? 1 : 0;
        let message   = completed ? `You pushed the button ${counter} times 🎉🎉🎉` : `You pushed the button ${counter} times`
    
        // Call push to send data to Falkor
        pushWebTrackingData(counter,message,completed);

    });
    
    
    /**
     * The function below illustrates how to push data. The
     * required paramaters are complete and progress. You can optionally
     * set result and data.
     * 
     * progress (Float): Store the user's progress percentage 0 - 100.
     * complete (Int): Store the completion state 1 = true, 0 = false
     * result (String): Store a string (max 48 characters).
     * data (String): Store a valid json string.
     */
     
    async function pullDataWebTracking(){
        
        // Pull data asynchronously
        let response = await webTrackingClient.pull();

        // Parse Previously Stored Data
        let data     = (response.data ? JSON.parse(response.data) : {})
    
        // Set the counter to previously pushed
        if (data.buttonPushes){
            counter = data.buttonPushes;
        }
        
        // Set the users icon
        $('.avatar-icon').html(`<img style="width:100%; height:auto; border-radius:50%" src="${response.user.icon}" />`);
        
        // Update the UI with a message using their name and how many
        // times they have currently pushed the button.
        
        $('.message').html(`
            <h3>Push 10 times to complete</h3>
            <p>
                Welcome <strong>${response.user.firstname}</strong> you have pushed the button <span class="counter-text">${counter}</span> times
            </p>
        `);

        // Update counter elements
        $('.counter,.counter-text').text(counter);


    }
    
    /**
     * The function below illustrates how to push data. The
     * required paramaters are complete and progress. You can optionally
     * set result and data.
     * 
     * progress (Float): Store the user's progress percentage 0 - 100.
     * complete (Int): Store the completion state 1 = true, 0 = false
     * result (String): Store a string (max 48 characters).
     * data (String): Store a valid json string.
     */

    async function pushWebTrackingData(counter,message,completed){
    
        // Push new data
        let response = await webTrackingClient.push({
            progress  : 100 * counter / 10,
            complete  : completed,
            message   : message,
            data      : JSON.stringify({
                buttonPushes : counter,
                lastPush     : new Date().getUTCDate
            })
        });
        
        // Response returns the updated state
        if (response.status == 'success'){
            console.log('Saved');
        }
        
    }
    
    
    pullDataWebTracking();
    
</script>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://everyday-digital.gitbook.io/falkor-dev-docs/pathways/webtracking/javascript-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
