# Sinch Client

The *SinchClient* is the Sinch SDK entry point. It's used to configure the user’s and device’s capabilities, as well as to provide access to feature classes such as the *CallController*, *AudioController*, and *VideoController*.

## Relation to UserController

Deprecation
`UserController` is a separate component and is deprecated. Prefer building and starting `SinchClient` directly.

## Create the *SinchClient*

Set up the Sinch client using [SinchClientBuilder](https://download.sinch.com/android/latest/reference/sinch-rtc/com.sinch.android.rtc/-sinch-client-builder/index.html):

```kotlin

val sinchClient = SinchClient.builder()
                   .context(context)
                   .applicationKey("<application key>")
                   .environmentHost("ocra.api.sinch.com")
                   .userId("<user id>")
                   .pushConfiguration(pushConfiguration)
                   .build()
```

- The *Application Key* is obtained from the [Sinch Developer Dashboard - Apps](https://dashboard.sinch.com/voice/apps).
- The *User ID* should uniquely identify the user on the particular device.
- The term *Ocra* in the hostname `ocra.api.sinch.com` is the name of the Sinch API that SDK clients target.
- The *Push Configuration* lets the SDK send push messages to notify about incoming calls. See the [Push notifications](/docs/in-app-calling/android/push-notifications) section for more information.


## Start the Sinch Client

Before starting the client, add a [SinchClientListener](https://download.sinch.com/android/latest/reference/sinch-rtc/com.sinch.android.rtc/-sinch-client-listener/index.html):

```kotlin
sinchClient.addSinchClientListener(object: SinchClientListener() {

    override fun onClientStarted(client: SinchClient) { }
    override fun onClientFailed(client: SinchClient, error: SinchError) { }
    override fun onCredentialsRequired(clientRegistration: ClientRegistration) {
      // You have to implement this method, it can't be no-op.
    }
    override fun onLogMessage(level: Int, area: String, message: String) { }
})

sinchClient.start()
```

When starting the client (`sinchClient.start()`), the client asks for a token via [`SinchClientListener.onCredentialsRequired()`](https://download.sinch.com/android/latest/reference/sinch-rtc/com.sinch.android.rtc/-sinch-client-listener/index.html).
See [Authentication & Authorization](/docs/in-app-calling/android/application-authentication) for details.

Listener threading
All listener callbacks emitted by the Sinch SDK are invoked on the same thread that `SinchClientBuilder.build` is called on. If that thread is not the main thread, it must have an associated `Looper`.

### Authorizing the Client / User

When the *SinchClient* starts with a given *User ID*, you must provide an authorization token to register with the Sinch backend. Implement [`SinchClientListener.onCredentialsRequired()`](https://download.sinch.com/android/latest/reference/sinch-rtc/com.sinch.android.rtc/-sinch-client-listener/index.html) and supply a JWT signed with the *Application Secret*.

The sample applications included in the Sinch SDK include a class `JWT` that shows how to create the JWT and sign it with the *Application Secret*.

```kotlin
class MySinchClientListener: SinchClientListener() {

        override fun onCredentialsRequired(clientRegistration: ClientRegistration) {
            val jwt = JWT.create(APP_KEY, APP_SECRET, userName)
            clientRegistration.register(jwt)
        }
}
```

See [Authentication & Authorization](/docs/in-app-calling/android/application-authentication) for details.

Secrets in production
Do not embed the Application Secret in a production app. The example above only shows how to provide a signed JWT to the *SinchClient*. Implement the required functionality on your backend and fetch a signed registration token when required.

## Lifecycle management of a *SinchClient* instance

We recommend that you initiate the *SinchClient*, start it, but not terminate it, during the lifetime of the running application. That also implies that the *SinchClient* instance should be *retained* by the application code. It's best to keep the client instance alive and started unless there are reasons specific to your application.

The *SinchClient* can of course be completely stopped and also disposed.

Receiving calls after stop
Stopping or disposing of a *SinchClient* does not prevent receiving incoming calls if the user was previously registered. When an incoming call push notification arrives, instantiate a new *SinchClient* and forward the push payload to it.

When the app is done using the `SinchClient`, it can be stopped and disposed using [SinchClient.terminateGracefully()](https://download.sinch.com/android/latest/reference/sinch-rtc/com.sinch.android.rtc/-sinch-client/terminate-gracefully.html).

Example of how to completely dispose the `SinchClient`:

```kotlin
sinchClient?.terminateGracefully()
sinchClient = null
```