# Getting Started with Sinch In‑app Calling for JavaScript SDK

This guide shows you how to integrate your JavaScript application with the In‑app Calling SDK. Because this is a getting started guide, it only covers signing in and making/receiving audio calls. For more complex examples, see the [reference app](https://github.com/sinch/rtc-reference-applications/tree/master/javascript) or the [SDK documentation](/docs/in-app-calling/js-cloud/).

## Prerequisites

- An editor of your choice.
- Latest version of the Chrome web browser.
- An HTTP server (for example, [`http-server`](https://www.npmjs.com/package/http-server)) to host the files.


## Create a project

Create empty JavaScript files named `index.js` and `sw.js`, and an HTML file named `index.html` in the same folder.

## Add the Sinch Voice and Video SDK

1. Add the following script tag to `index.html` in the `<head>` section:



```html
<script src="https://cdn.sinch.com/latest/sinch-rtc-min.js"></script>
```

1. Add the following script tag to the bottom of `index.html` in the `<body>` section:



```html
<script type="module" src="index.js"></script>
```

1. Add the following JavaScript code to `sw.js`. It is a service worker for handling push notifications:



```javascript
this.addEventListener("push", (event) => {
  console.log("ServiceWorker Push: ", event);
  const body = event.data.json();
  event.waitUntil(
    clients
      .matchAll({ includeUncontrolled: true, type: "window" })
      .then((clients) => {
        clients.forEach((client) => {
          client.postMessage({
            visible: client.visibilityState === "visible",
            data: body,
          });
        });
      })
  );
});
```

## Interact with the Voice and Video SDK

The `SinchClient` object is the main SDK entry point. Once created, it provides SDK features such as video, audio, or PSTN calls. Initialize `SinchClient` once and retain its instance for the entire lifetime of the application.

In `index.js`, add the following code:


```javascript
const APP_KEY = "enter-application-key";
const APP_SECRET = "enter-application-secret";
const ENVIRONMENT_HOST = "ocra.api.sinch.com";

class SinchClientWrapper {
  constructor(userId, ui) {
    this.userId = userId;
    this.ui = ui;

    const sinchClient = Sinch.getSinchClientBuilder()
      .applicationKey(APP_KEY)
      .userId(userId)
      .environmentHost(ENVIRONMENT_HOST)
      .build();

    sinchClient.addListener(this.#sinchClientListener());
    sinchClient.setSupportManagedPush();
    sinchClient.start();

    this.sinchClient = sinchClient;
  }
}
```

This creates a `SinchClientWrapper` class and implements its constructor.

To make this example work for you, you need to update some values:

| Parameter | Your value |
|  --- | --- |
| `APP_KEY` | You can find your key on your [Build dashboard](https://dashboard.sinch.com/voice/apps). |
| `APP_SECRET` | You can find your secret on your [Build dashboard](https://dashboard.sinch.com/voice/apps). |


There are a few other elements to notice:

- The `environmentHost` parameter is the REST API endpoint the SDK targets.
- The `userId` parameter is the user identifier registered within your application (provided after clicking the **Login** button).
- `setSupportManagedPush()` enables receiving notifications about incoming calls when the application is not in the foreground.
In production, this feature should almost always be enabled; without it, incoming calls cannot be received while the app is unfocused.


When starting, the `SinchClientListener.onCredentialsRequired` method executes. Inside this callback you must provide a JWT token signed with your application secret. In production, generate this token on your backend; never embed the secret in client-side code. See [Authentication & Authorization](https://developers.sinch.com/docs/in-app-calling/js/application-authentication/) for details.

For this step‑by‑step guide we mimic a backend authentication server with a helper `JWT` class that creates the token locally based on `userId` and your application credentials, and then registers it with the Sinch SDK:


```javascript
class SinchClientWrapper {
  // constructor ...

  #sinchClientListener() {
    return {
      onCredentialsRequired: (sinchClient, clientRegistration) => {
        // TODO: implement this in a backend server
        new JWT(APP_KEY, APP_SECRET, this.userId)
          .toJwt()
          .then(clientRegistration.register)
          .catch((error) => {
            clientRegistration.registerFailed();
            console.error(error);
          });
      },
    };
  }
}
```

An implementation of the `JWT` class is available in the reference app: [`jwt.js`](https://github.com/sinch/rtc-reference-applications/blob/master/javascript/samples/common/jwt.js).

## Communication between UI and Sinch Client

To communicate between your application UI layer and the Sinch client, keep a reference to `SinchClientWrapper` inside the UI class, and a reference to the UI inside the wrapper.

1. Inside `index.js`, create a `UI` class that handles login and creation of `SinchClientWrapper`:



```javascript
class UI {
  constructor() {
    this.#handleLogin();
    console.log("UI started");
  }

  #handleLogin() {
    document.getElementById("login").addEventListener("click", () => {
      const userId = document.getElementById("userid").value;
      this.#hideElement("login-container");
      this.sinchClientWrapper = new SinchClientWrapper(userId, this);
    });
  }

  #hideElement(id) {
    const element = document.getElementById(id);
    element.style = "display: none";
  }
}
```

1. At the bottom of `index.js`, instantiate the `UI` class:



```javascript
new UI();
```

## Log in to the application

When the user starts the application they enter a username that becomes the `userId` and is used to create a Sinch client. This identifier is also used as the callee reference when placing audio calls.

1. Create a simple layout containing input fields and a login button in the top `<body>` section of `index.html`:

```html
<div id="login-container">
  <input id="userid" placeholder="Enter user id" type="text" />
  <button id="login">Login</button>
</div>
```
2. Return to the `SinchClientWrapper` implementation. Inside `onClientStarted` and `onClientFailed` add logging statements:

```javascript
class SinchClientWrapper {
  // constructor ...

  #sinchClientListener() {
    return {
      // onCredentialsRequired ...

      onClientStarted: (sinchClient) => {
        console.log("Sinch - Start client succeded");
      },

      onClientFailed: (sinchClient, error) => {
        console.log("Sinch - Start client failed");
        console.error(error);
      },
    };
  }
}
```
3. Run an HTTP server from your working directory, open `index.html`, and enter a username. Check the browser console to verify the client started successfully.


## Next steps

Now that your application is created, you can configure it to make a call.

Make a call