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 or the SDK documentation.
- An editor of your choice.
- Latest version of the Chrome web browser.
- An HTTP server (for example,
http-server) to host the files.
Create empty JavaScript files named index.js and sw.js, and an HTML file named index.html in the same folder.
- Add the following script tag to
index.htmlin the<head>section:
<script src="https://cdn.sinch.com/latest/sinch-rtc-min.js"></script>- Add the following script tag to the bottom of
index.htmlin the<body>section:
<script type="module" src="index.js"></script>- Add the following JavaScript code to
sw.js. It is a service worker for handling push notifications:
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,
});
});
})
);
});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:
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 | Find your key on your dashboard. |
APP_SECRET | Find your secret on your dashboard. The secret is only visible immediately after creation—store it securely. |
There are a few other elements to notice:
The
environmentHostparameter is the REST API endpoint the SDK targets.The
userIdparameter 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.NoteIn 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 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:
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.
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.
- Inside
index.js, create aUIclass that handles login and creation ofSinchClientWrapper:
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";
}
}- At the bottom of
index.js, instantiate theUIclass:
new UI();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.
Create a simple layout containing input fields and a login button in the top
<body>section ofindex.html:<div id="login-container"> <input id="userid" placeholder="Enter user id" type="text" /> <button id="login">Login</button> </div>Return to the
SinchClientWrapperimplementation. InsideonClientStartedandonClientFailedadd logging statements: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); }, }; } }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.
Now that your application is created, you can configure it to make a call.