<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## create

The SDK creation factory. Create an instance of the SDK by calling this factory with the desired configurations.
The SDK instance will be referred as 'api' throughout the rest of the documentation content.

### Parameters

*   `config` **[config][1]** The configuration object.

### Examples

```javascript
// Instantiate the SDK.
import { create } from '@rbbn/webrtc-js-sdk'
const client = create({
    authentication: { ... },
    logs: { ... },
    ...
});
// Use the SDK's API.
client.on( ... );
```

Returns **[api][2]** The SDK instance.

## config

The configuration object. This object defines what different configuration
values you can use when instantiating the SDK using the [create][3] function.

### config.logs

Configuration options for the Logs feature.

The SDK will log information about the operations it is performing. The
amount of information will depend on how the Logs feature is configured.

The format of logs can also be customized by providing a
[LogHandler][4]. This function will receive a
[LogEntry][5] which it can handle as it sees fit. By
default, the SDK will log information to the console. For more
information, see the [Logs feature][6] description.

#### Parameters

*   `logs` **[Object][7]** Logs configs.

    *   `logs.logLevel` **[string][8]** Log level to be set. See [logger.levels][9]. (optional, default `'debug'`)
    *   `logs.handler` **[logger.LogHandler][10]?** The function to receive log entries from the
        SDK. If not provided, a default handler will be used that logs entries
        to the console.
    *   `logs.logActions` **([Object][7] | [boolean][11])** Options specifically for action logs when
        logLevel is at DEBUG+ levels. Set this to false to not output action logs. (optional, default `false`)

        *   `logs.logActions.handler` **[logger.LogHandler][10]?** The function to receive action
            log entries from the SDK. If not provided, a default handler will be used
            that logs actions to the console.
        *   `logs.logActions.actionOnly` **[boolean][11]** Only output information
            about the action itself. Omits the SDK context for when it occurred. (optional, default `false`)
        *   `logs.logActions.collapsed` **[boolean][11]** Whether logs should be
            minimized when initially output. The full log is still output and can be
            inspected on the console. (optional, default `false`)
        *   `logs.logActions.diff` **[boolean][11]** Include a diff of what SDK
            context was changed by the action. (optional, default `false`)
        *   `logs.logActions.level` **[string][8]** Log level to be set
            on the action logs (optional, default `'debug'`)
        *   `logs.logActions.exposePayloads` **[boolean][11]** Allow action payloads
            to be exposed in the logs, potentially displaying sensitive information. (optional, default `true`)

### config.connectivity

Configuration options for the Connectivity feature.
The SDK can only use keepalive as the connectivity check.

Keep Alive: The client sends "keepalive" messages (to the server) on the websocket at regular intervals. This lets the server know that the client is still connected, and that it should "keep the connection alive".

For more information on keepalive see here: [https://en.wikipedia.org/wiki/Keepalive][12]

#### Parameters

*   `connectivity` **[Object][7]** Connectivity configs.

    *   `connectivity.pingInterval` **[Number][13]** Time in between websocket ping attempts (milliseconds). (optional, default `30000`)
    *   `connectivity.reconnectLimit` **[Number][13]** Number of failed reconnect attempts before reporting an error. Can be set to 0 to not limit reconnection attempts. (optional, default `5`)
    *   `connectivity.reconnectDelay` **[Number][13]** Base time between websocket reconnect attempts (milliseconds). (optional, default `5000`)
    *   `connectivity.reconnectTimeMultiplier` **[Number][13]** Reconnect delay multiplier for subsequent attempts. The reconnect delay time will be multiplied by this after each failed reconnect attempt to increase the delay between attempts. eg. 5000ms then 10000ms then 20000ms delay if value is 2. (optional, default `1`)
    *   `connectivity.reconnectTimeLimit` **[Number][13]** Maximum time delay between reconnect attempts (milliseconds). Used in conjunction with the reconnect time multiplier to prevent overly long delays between reconnection attempts. (optional, default `640000`)
    *   `connectivity.autoReconnect` **[Boolean][11]** Flag to determine whether the SDK will attempt to automatically reconnect after connectivity disruptions. (optional, default `true`)
    *   `connectivity.checkConnectivity` **[Boolean][11]** Flag to determine whether the SDK should check connectivity. (optional, default `true`)
    *   `connectivity.webSocketOAuthMode` **[string][8]** When set to 'query', the OAuth bearer access token will be appended as a query string parameter to the websocket address. (optional, default `none`)

### config.notifications

Configuration options for the notification feature.

#### Parameters

*   `notifications` **[Object][7]** The notifications configuration object.

    *   `notifications.idCacheLength` **[number][13]** Default amount of event ids to remember for de-duplication purposes. (optional, default `100`)
    *   `notifications.incomingCallNotificationMode` **[string][8]** Communication channel mode used for incoming call notifications. Supported values are 'any-channel' or 'push-channel-only'. (optional, default `'any-channel'`)
    *   `notifications.pushRegistration` **[Object][7]?** Object describing the server to use for push services.

        *   `notifications.pushRegistration.server` **[string][8]?** Hostname for the push registration server.
        *   `notifications.pushRegistration.port` **[string][8]?** Port for the push registration server.
        *   `notifications.pushRegistration.protocol` **[string][8]?** Protocol for the push registration server.
        *   `notifications.pushRegistration.version` **[string][8]?** Version for the push registration server.

### config.request

Configurable options for the Request plugin.

The SDK uses the Request plugin to make REST requests to the Gateway.

#### Parameters

*   `request` **[Object][7]** Request configuration

    *   `request.restTimeout` **[Number][13]** The timeout for REST requests, in milliseconds. After this time, the request will be considered failed. (optional, default `30000`)

### config.authentication

Configuration options for the Authentication feature.

#### Parameters

*   `authentication` **[Object][7]** Authentication configs.

    *   `authentication.server` **[Object][7]** 

        *   `authentication.server.base` **[string][8]** Hostname of the server to be used for requests.
        *   `authentication.server.protocol` **[string][8]** Protocol to be used for requests. (optional, default `'https'`)
        *   `authentication.server.port` **[number][13]** Port to be used for requests. (optional, default `443`)

### config.subscription

Configuration options for the Subscription feature.

#### Parameters

*   `subscription` **[Object][7]** Subscription config.

    *   `subscription.expires` **[number][13]** The lifetime (in seconds) of a subscription. The SDK will automatically refresh the subscription before it expires. Cannot be less than minimum threshold of 60 seconds. (optional, default `3600`)
    *   `subscription.serviceUnavailableMaxRetries` **[number][13]** The maximum number of times this client will retry in order to subscribe for a
        given service, while getting 'Service Unavailable' from backend. (optional, default `3`)
    *   `subscription.websocket` **[Object][7]** 

        *   `subscription.websocket.server` **[string][8]** Hostname of the server to be used for websocket notifications.
        *   `subscription.websocket.protocol` **[string][8]** Protocol to be used for websocket notifications. (optional, default `wss`)
        *   `subscription.websocket.port` **[Number][13]** Port to be used for websocket notifications. (optional, default `443`)

### config.call

Configuration options for the call feature.

#### Parameters

*   `call` **[Object][7]** The call configuration object.

    *   `call.defaultPeerConfig` **[call.RTCPeerConnectionConfig][14]?** A key-value dictionary that corresponds
        to the available RTCPeerConfiguration which is normally passed when creating an RTCPeerConnection.
        See [RTCPeerConnection's configuration parameters][15] for more information.
        This is the recommended way of setting ICE servers and other RTCPeerConnection-related configuration.
    *   `call.iceCollectionIdealTimeout` **[number][13]** The amount of time to wait for an ideal candidate in milliseconds.
        The default is 1000ms. An ideal list of candidates is a complete list of candidates considering the RTCPeerConnection configuration.
        Note that this values will not be considered if a custom function is passed through the `iceCollectionCheckFunction`, and
        any timeouts must be handled by the custom function. (optional, default `1000`)
    *   `call.iceCollectionMaxTimeout` **[number][13]** The maximum amount of time to wait for ICE collection in milliseconds.
        The default is 3000ms. After this time has been reached, the call will proceed with the currently gathered candidates.
        Note that this values will not be considered if a custom function is passed through the `iceCollectionCheckFunction`, and
        any timeouts must be handled by the custom function. (optional, default `3000`)
    *   `call.iceCollectionCheckFunction` **[Function][16]?** Override the default IceCollectionCheckFunction to manually decide when
        to proceed with operations, error out, or wait for the appropriate states and candidates. The function will receive an object containing
        the ice collection info. See [IceCollectionInfo][17] for more details. The function must return
        a results object with details on how to proceed with the ICE collection check or operatiaon. See [IceCollectionResult][18]
        object for details on the format of the return object. See [IceCollectionCheckFunction][19] for
        more information on the form of the function, as well as information about the default IceCollectionCheckFunction that is used if nothing is provided.
    *   `call.serverTurnCredentials` **[boolean][11]** Whether server-provided TURN credentials should be used. (optional, default `true`)
    *   `call.sdpHandlers` **[Array][20]<[call.SdpHandlerFunction][21]>?** List of SDP handler functions to modify SDP. Advanced usage.
    *   `call.earlyMedia` **[boolean][11]** Whether early media should be supported for calls. Not supported on Firefox. (optional, default `false`)
    *   `call.resyncOnConnect` **[boolean][11]** Whether the SDK should re-sync all call states after connecting (requires WebRTC Gateway 4.7.1+). (optional, default `false`)
    *   `call.removeBundling` **[boolean][11]** Whether to remove a=group attributes to stop media bundling from incoming and outgoing SDP messages. (optional, default `false`)
    *   `call.ringingFeedbackMode` **[string][8]** The mode for sending ringing feedback to the Caller ('auto', 'manual').
        By default, feedback will be automatically sent when a call has been received. In 'manual' mode, the application
        must initiate the feedback being sent. See the `call.sendRingingFeedback` API for more info. (optional, default `'auto'`)
    *   `call.callAuditTimer` **[number][13]** Time interval, in milliseconds between call audits. (optional, default `25000`)
    *   `call.mediaConnectionRetryDelay` **[number][13]** Delay, in milliseconds for the passive side of a call to wait before trying a media reconnection. (optional, default `3000`)
    *   `call.normalizeDestination` **[boolean][11]** Specifies whether or not SIP address normalization will be applied. (optional, default `true`)

## api

The 'api' is the type returned by the create function.
It contains various top-level functions that pertain to SDK global instance
as well as several nested namespaces that pertain to various features (e.g. call, contacts, presence, etc).

### getVersion

Returns the current version of the API.

### destroy

Destroys the SDK, and removes its state, rendering the SDK unusable.
Useful when a user logs out and their call data needs to be destroyed.
The SDK must be recreated to be usable again.
The destroy command is async, and will happen on the next tick
so as not to interfere with any ongoing events.

#### Examples

```javascript
// Instantiate the SDK.
import { create } from '@rbbn/webrtc-js-sdk'
const config = {
    authentication: { ... },
    logs: { ... },
    ...
}
let client = create(config);
client.on( ... )
// Use the SDK
...
// Destroy the SDK, then recreate on the next step
client.destroy()
client = create(config)
client.on( ... )
```

### getConfig

Gets the current configuration Object. This is the object that is initially set as part of SDK creation using 'create' function.

Returns **[Object][7]** A configuration Object.

### updateConfig

Update the configuration values for the SDK to use.

This API will only modify the configurations provided, leaving other configurations
as they were originally set, by performing a merge of the new values into the
previous values.

Please note that the object provided to the `updateConfig` API may be different
than the object retrieved from the [getConfig][22] API. This may happen when a format
change has happened and the SDK modifies the provided format to alleviate
backwards-compatibility issues. We recommend ensuring the configurations you
provide are as described by the [config][23] section.

#### Parameters

*   `newConfigValues` **[Object][7]** Key-value pairs that will be placed into the store. See [config][23] for details on what key-value pairs are available for use.

#### Examples

```javascript
// Instantiate the SDK with certain configs.
const client = create({
  authentication: { ... },
  logs: { ... },
  ...
})

// Modify a subsection of the configs at a later time.
// This will only update the specified configurations.
client.updateConfig({
    logs: {
      loglevel: 'DEBUG'
    }
})
```

### on

Add an event listener for the specified event type. The event is emitted by the SDK instance.

#### Parameters

*   `type` **[string][8]** The event type for which to add the listener.
*   `listener` **[Function][16]** The listener for the event type. The parameters of the listener depend on the event type.

#### Examples

```javascript
// Listen for events of a specific type emitted by the SDK.
client.on('dummy:event', function (params) {
   // Handle the event.
})
```

### off

Removes an event listener for the specified event type. The event is emitted by the SDK instance.

#### Parameters

*   `type` **[string][8]** The event type for which to remote the listener.
*   `listener` **[Function][16]** The listener to remove.

### subscribe

Adds a global event listener to SDK instance.

#### Parameters

*   `listener` **[Function][16]** The event listener to add. The parameters are (type, ...args), where args depend on the event type.

### unsubscribe

Removes a global event listener from SDK instance.

#### Parameters

*   `listener` **[Function][16]** The event listener to remove.

### getBrowserDetails

Retrieve information about the browser being used.

Browser information being defined indicates that the browser supports
basic webRTC scenarios.

#### Examples

```javascript
const details = client.getBrowserDetails()

log(`Browser in use: ${details.browser}, version ${details.version}.`)
```

Returns **[Object][7]** Object containing `browser` and `version` information.

### getUserInfo

Retrieves information about the current user.

Returns **[Object][7]** user The user data.

Returns **[string][8]** user.username The username of the current user. Note that this username can take different encoded forms.
It's not meant to be displayed to a user.

Returns **[string][8]** user.token The current access token.

### setCredentials

Sets the user credentials necessary to make requests to the platform.

The SDK will emit an [auth:change][24] event when the credentials
are set. If there was an issue with the credentials, an [auth:error][25]
event will be emitted instead.

The currently set user information can be retrieved using the [getUserInfo][26] API.

If credentials have previously been set, they cannot be set again if there is an active
subscription. An [auth:error][25] will be emitted in
this scenario.

#### Parameters

*   `credentials` **[Object][7]** The credentials object.

    *   `credentials.username` **[string][8]** The username including the application's domain.
    *   `credentials.password` **[string][8]** The user's password.
    *   `credentials.authname` **[string][8]?** The user's authorization name.

#### Examples

```javascript
client.setCredentials({
  username: 'alfred@example.com',
  password: '********'
  authname: '********'
});
```

Returns **[undefined][27]** 

### setCredentials

Sets the user credentials necessary to make requests to the platform, using HMAC token authentication.

An HMAC token is used to verify a user via the user's authorization within an of organization. HMAC tokens
are generated by using the HmacSHA1 algorithm and a key on a data object containing an
`authenticationTokenRequest` object with the following properties:

*   subscriberId - The user's subscriber ID in the organization.
*   organizationId - The ID of the organization the user is a part of.

The SDK will emit an [auth:change][24] event when the credentials
are set. If there was an issue with the credentials, an [auth:error][25]
event will be emitted instead.

The currently set user information can be retrieved using the [getUserInfo][26] API.

If credentials have previously been set, they cannot be set again if there is an active
subscription. An [auth:error][25] will be emitted in
this scenario.

#### Parameters

*   `credentials` **[Object][7]** The credentials object.

    *   `credentials.username` **[string][8]** The username.
    *   `credentials.hmacToken` **[string][8]** An HMAC token for the user with the provided user ID.

#### Examples

```javascript
const hmacToken = HmacSHA1Algorithm({
  authenticationTokenRequest: {
    subscriberId: 'alfred',
    organizationId: 'example.com'
  }
}, key)

client.setCredentials({
  username: 'alfred@example.com',
  hmacToken
});
```

Returns **[undefined][27]** 

### setCredentials

Sets the user credentials necessary to make requests to the platform, using bearer token authentication.

The bearerAccessToken provided establishes what can be accessed by the SDK. The bearerAccessToken
can be set again after subscription as long as the subscribed username is passed with the updated bearerAccessToken.

The SDK will emit an [auth:change][24] event when the credentials
are set. If there was an issue with the credentials, an [auth:error][25]
event will be emitted instead.

The currently set user information can be retrieved using the [getUserInfo][26] API.

If credentials have previously been set, they cannot be set again if there is an active
subscription. An [auth:error][25] will be emitted in
this scenario.

#### Parameters

*   `credentials` **[Object][7]** The credentials object.

    *   `credentials.username` **[string][8]** The username without the application's domain.
    *   `credentials.bearerAccessToken` **[string][8]** A bearerAccessToken retrieved using the authentication APIs of the platform.

#### Examples

```javascript
client.setCredentials({
  username: 'alfred@example.com',
  bearerAccessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
});
```

Returns **[undefined][27]** 

### setCredentialsAsync

Sets the user credentials necessary for REST authorization to the configured WebRTC Gateway.

This API is equivalent to the [setCredentials][28] API, but provides feedback via a return value instead
of emitting events. This API will not cause any authentication events to be emitted during this operation.

There are no pre-requisites for this API. Credentials will be updated if existing credentials were already set.
If there is an active subscription using the credentials, the username cannot be changed, but the authorization
method can be changed. For example, if using a token method, to provide a new token before the previous one expires.

Note: Though this API's name is suffixed with "Async", it is not asynchronous and does not return a promise.
It is a synchronous operation that will return immediately after setting the credentials. The "Async"
suffix is used to indicate the new APIs that provide feedback via return values instead of events, which
are promise-based but with a few exceptions such as this API.

#### Parameters

*   `credentials` **[Object][7]** The credentials object.

#### Examples

```javascript
// Set credentials using the username/password method.
try {
  // Though "Async", does not return a promise. See Note in API description.
  client.setCredentialsAsync({ username, password })
  // Credentials set successfully.
} catch (error) {
  // Credentials could not be set.
  const { code, message } = error
}
```

*   Throws **BasicError** Throws an error if the credentials cannot be set.

Returns **[undefined][27]** Returns after credentials have been set.

### BasicError

The Basic Error object. Provides information about an error that occurred in the SDK.

Type: [Object][7]

#### Properties

*   `code` **[string][8]** The code of the error. If no code is known, this will be 'NO_CODE'.
*   `message` **[string][8]** A human-readable message to describe the error. If no message is known, this will be 'An error occurred'.

### request:error

An error occurred with server authorization.

This event will be emitted anytime a REST request to the server is rejected
due to an authorization issue. This may occur for invalid credentials or
expired tokens, depending on which form of authentication the application
has chosen to use.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.

### auth:change

The authentication credentials have changed.

This event is triggered after calling the [setCredentials][30] API.

The current user information can be retrieved using the [getUserInfo][26] API.

#### Parameters

*   `params` **[Object][7]** 

### auth:error

There was an error with authentication credentials.

This event is triggered after calling the [setCredentials][30] API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.

## call

The 'call' namespace (within the 'api' type) is used to make audio and video calls to and from
SIP users and PSTN phones.

Call functions are all part of the 'call' namespace.

### make

Starts an outgoing call to a [SIP_URI][31] or a
[TEL_URI][32].

The call will be tracked by a unique ID that is returned by the API. The
application will use this ID to identify and control the call after it
has been initiated.

The [call.getById][33] API can be used to retrieve
the current information about the call.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:start][35] event
locally when the operation completes. When the remote participant
receives the call, a [call:receive][36]
event will be emitted remotely for them.

The SDK requires access to the machine's media devices (eg. microphone)
in order to make a call. If it does not already have permissions to
use the devices, the user may be prompted by the browser to give
permissions.

Detached media can be used when starting a call. Detached media is created
locally outside of a call and must be managed by the application. It can
be used when making a call by passing an array of detached track ids in
the media object. You can start a call with a mixture of detached
and requested media, however, you can only use one of each type (audio, video,
screen). For example, you could include a detached track id for video, and set
MediaConstraint.audio: true, but you can't set MediaConstraint.video: true
if you have passed in a detached track id of kind video.

#### Parameters

*   `destination` **([call.SIP_URI][37] | [call.TEL_URI][38])** The desired destination.
*   `media` **[Object][7]** The media options the call should be initialized with.

    *   `media.audio` **[boolean][11]** Whether the call should have audio on start. Currently, audio-less calls are not supported. (optional, default `false`)
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the call's audio.
    *   `media.video` **[boolean][11]** Whether the call should have video on start. (optional, default `false`)
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
    *   `media.screen` **[boolean][11]** Whether the call should have screenshare on start. (Note: Screensharing is not supported on iOS Safari.) (optional, default `false`)
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** List of detached medias containing tracks to be attached to this call.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.displayName` **[string][8]?** Custom display name to be provided to the destination. Not supported in all environments and may use default display name.
    *   `options.customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic

#### Examples

```javascript
// Listen for the event emitted after making a call.
client.on('call:start', function (params) {
  const { callId, error } = params
  if (error) {
    // Call failed to initialize.
  } else {
    // Call was initialized, and the recipient user will be notified.
  }
})
// Make an audio-only call.
const newCallId = client.call.make(destination, { audio: true })
```

Returns **[string][8]** The generated ID of the newly created call.

### makeAsync

Starts an outgoing call to a [SIP_URI][31] or a
[TEL_URI][32].

This API is equivalent to the [call.make][46] API, but provides feedback via a returned promise. This API
will not emit events specifically about the operation's completion, but will emit events to indicate changes
to call tracking.

The SDK will emit a [call:start][35] event when the the call is available in state,
where it will be in Initiating state. After that, a [call:stateChange][47]
event will be emitted when the call changes state, either to Initiated on success or Ended on failure.
When the remote participant receives the call, a [call:receive][36] event will
be emitted for them.

The call will be tracked by a unique ID that is available on the [CallObject][48] provided
through the promise resolve, or through the [call:start][35] event before the
promise resolves. The [call.getById][33] API can be used to retrieve the current information about the
call.

The SDK requires access to the machine's media devices (eg. microphone)
in order to make a call. If it does not already have permissions to
use the devices, the user may be prompted by the browser to give
permissions.

Detached media can be used when starting a call. Detached media is created
locally outside of a call and must be managed by the application. It can
be used when making a call by passing an array of detached track ids in
the media object. You can start a call with a mixture of detached
and requested media, however, you can only use one of each type (audio, video,
screen). For example, you could include a detached track id for video, and set
MediaConstraint.audio: true, but you can't set MediaConstraint.video: true
if you have passed in a detached track id of kind video.

#### Parameters

*   `destination` **([call.SIP_URI][37] | [call.TEL_URI][38])** The desired destination.
*   `media` **[Object][7]** The media options the call should be initialized with.

    *   `media.audio` **[boolean][11]** Whether the call should have audio on start. Currently, audio-less calls are not supported. (optional, default `false`)
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the call's audio.
    *   `media.video` **[boolean][11]** Whether the call should have video on start. (optional, default `false`)
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
    *   `media.screen` **[boolean][11]** Whether the call should have screenshare on start. (Note: Screensharing is not supported on iOS Safari.) (optional, default `false`)
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** List of detached medias containing tracks to be attached to this call.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.displayName` **[string][8]?** Custom display name to be provided to the destination. Not supported in all environments and may use default display name.
    *   `options.customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic

#### Examples

```javascript
// Make an audio-only call.
try {
  const call = await client.call.makeAsync(destination, { audio: true })
  // Call is Initiated, waiting for remote user to answer.
} catch (error) {
  // Handle error.
  const { code, message } = error
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[call.CallObject][50]>** A promise that resolves to the call object when call has been successfully initiated.

### answer

Answers an incoming call.

The specified call to answer must be in a ringing state with an incoming
direction. The call will become connected as a result of the operation.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. This indicates that the
call has connected with the remote participant. The
[call.getById][33] API can be used to retrieve the latest call state
after the change. Further events will be emitted to indicate that the
call has received media from the remote participant. See the
[call:newTrack][51] event for more
information about this.

The SDK requires access to the system's media devices (eg. microphone)
in order to answer a call. If it does not already have permissions to
use the devices, the user may be prompted by the browser to give
permissions.

#### Parameters

*   `callId` **[string][8]** The ID of the call to answer.
*   `media` **[Object][7]** The media options the call should be initialized with.

    *   `media.audio` **[boolean][11]** Whether the call should create an audio track, on start. Currently, audio-less calls are not supported. (optional, default `false`)
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the call's audio.
    *   `media.video` **[boolean][11]** Whether the call should create a video track, on start. (optional, default `false`)
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
    *   `media.screen` **[boolean][11]** Whether the call should create a screenshare track, on start. (Note: Screensharing is not supported on iOS Safari.) (optional, default `false`)
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** List of detached medias containing tracks that can also be used when answering the call.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic

### answerAsync

Answers an incoming call.

This API is equivalent to the [call.answer][52] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the
call's state changes.

The specified call to answer must be in a ringing state with an incoming
direction. The call will become connected as a result of the operation.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. This indicates that the
call has connected with the remote participant. The
[call.getById][33] API can be used to retrieve the latest call state
after the change. Further events will be emitted to indicate that the
call has received media from the remote participant. See the
[call:newTrack][51] event for more
information about this.

The SDK requires access to the system's media devices (eg. microphone)
in order to answer a call. If it does not already have permissions to
use the devices, the user may be prompted by the browser to give
permissions.

#### Parameters

*   `callId` **[string][8]** The ID of the call to answer.
*   `media` **[Object][7]** The media options the call should be initialized with.

    *   `media.audio` **[boolean][11]** Whether the call should create an audio track, on start. Currently, audio-less calls are not supported. (optional, default `false`)
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the call's audio.
    *   `media.video` **[boolean][11]** Whether the call should create a video track, on start. (optional, default `false`)
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
    *   `media.screen` **[boolean][11]** Whether the call should create a screenshare track, on start. (Note: Screensharing is not supported on iOS Safari.) (optional, default `false`)
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** List of detached medias containing tracks that can also be used when answering the call.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic

#### Examples

```javascript
try {
    await client.call.answerAsync(callId, { audio: true })
    // Call answered successfully.
    // client.call.getById(callId).state === 'Connected'
} catch (error) {
    // Failed to answer; call is unchanged.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### reject

Rejects an incoming call.

The specified call to reject must be in a ringing or initiated state with an incoming
direction. The call will be ended as a result of the operation.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant
will be notified, through their own [call:stateChange][47]
event, that the call was rejected.

#### Parameters

*   `callId` **[string][8]** The ID of the call to reject.

### rejectAsync

Rejects an incoming call.

This API is equivalent to the [call.reject][53] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the
call's state changes.

The specified call to reject must be in a Ringing or Initiated state with an incoming
direction. The call will be Ended as a result of the operation.

This operation changes the state of the call on success, and so will emit a
[call:stateChange][47] event locally when the operation
completes. The remote participant will be notified, through their own
[call:stateChange][47] event, that the call was rejected.

#### Parameters

*   `callId` **[string][8]** The ID of the call to reject.

#### Examples

```javascript
try {
    await client.call.rejectAsync(callId)
    // Call rejected successfully.
    // client.call.getById(callId).state === 'Ended'
} catch (error) {
    // Failed to reject; call is unchanged.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### ignore

Ignores an incoming call.

The specified call to ignore must be an incoming call in Ringing state. The call will be Ended as a result
of the operation.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant
will not be notified that the call was ignored.

#### Parameters

*   `callId` **[string][8]** The ID of the call to ignore.

### ignoreAsync

Ignores an incoming call.

This API is equivalent to the [call.ignore][54] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the
call's state changes.

The specified call to ignore must be an incoming call in Ringing state. The call will be Ended as a result
of the operation.

This operation changes the state of the call on success, and so will emit a
[call:stateChange][47] event locally when the operation
completes. The remote participant will not be notified that the call was ignored.

#### Parameters

*   `callId` **[string][8]** The ID of the call to ignore.

#### Examples

```javascript
try {
    await client.call.ignoreAsync(callId)
    // Call ignored successfully.
    // client.call.getById(callId).state === 'Ended'
} catch (error) {
    // Failed to ignore; call is unchanged.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### forward

Forwards an incoming call to another user.

The specified destination will receive the Call instead of the current
user.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event after the operation completes.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `destination` **([call.SIP_URI][37] | [call.TEL_URI][38])** The destination to forward the call to.

### forwardAsync

Forwards an incoming call to another user.

This API is equivalent to the [call.forward][55] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the
call's state changes.

The specified destination will receive the Call instead of the current user.

This operation changes the state of the call on success, and so will emit a
[call:stateChange][47] event locally when the operation
completes.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `destination` **([call.SIP_URI][37] | [call.TEL_URI][38])** The destination to forward the call to.

#### Examples

```javascript
try {
    await client.call.forwardAsync(callId, destination)
    // Call forwarded successfully.
    // client.call.getById(callId).state === 'Ended'
} catch (error) {
    // Failed to forward; call is unchanged.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### end

Ends an ongoing call.

The SDK will stop all local media associated with the call. Events
will be emitted to indicate which media tracks were stopped. See the
[call:trackEnded][56] event for more
information.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant
will be notified, through their own
[call:stateChange][47] event, that the
call was ended.

#### Parameters

*   `callId` **[string][8]** The ID of the call to end.

### endAsync

Ends an ongoing call.

This API is equivalent to the [call.end][57] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the
call's state changes.

The SDK will stop all local media associated with the call. Events will be emitted to indicate which media
tracks were stopped. See the [call:trackEnded][56] event for more information.

The SDK will emit a [call:stateChange][47] event locally when the call is Ended.
The remote participant will be notified, through their own
[call:stateChange][47] event, that the call was ended.

#### Parameters

*   `callId` **[string][8]** The ID of the call to end.

#### Examples

```javascript
try {
    await client.call.endAsync(callId)
    // Call ended successfully.
    // client.call.getById(callId).state === 'Ended'
} catch (error) {
    // Failed to end; call is unchanged.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** Promise that resolves when the operation completes.

### hold

Puts a call on hold.

The specified call to hold must not already be locally held. Any/all
media received from the remote participant will stop being received,
and any/all media being sent to the remote participant will stop
being sent.

Some call operations cannot be performed while the call is on hold. The
call can be taken off hold with the [call.unhold][58] API.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant
will be notified of the operation through a
[call:stateChange][47] event as well.

#### Parameters

*   `callId` **[string][8]** The ID of the call to hold.

### holdAsync

Puts a call on hold.

This API is equivalent to the [call.hold][59] API, but provides feedback via a returned promise. This API
will not emit events specifically about the operation's completion, but may emit events if the call's state
changes and when tracks are removed from the call.

The specified call to hold must not already be locally held. Any/all media received from the remote
participant will stop being received, and any/all media being sent to the remote participant will
stop being sent.

Some call operations cannot be performed while the call is on hold. The call can be taken off hold with
the [call.unhold][58] API.

The SDK will emit a [call:stateChange][47] event locally if the operation
successfully places the call on hold. A [call:tracksRemoved][60]
event will also be emitted to indicate the tracks that were removed from the call. The remote
participant will receive equivalent events.

#### Parameters

*   `callId` **[string][8]** The ID of the call to hold.

#### Examples

```javascript
try {
    await client.call.holdAsync(callId)
    // Operation succeeded.
    // client.call.getById(callId).state === 'On Hold'
} catch (error) {
    // Operation failed.
    const { message, code } = error
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### unhold

Takes a call off hold.

The specified call to unhold must be locally held. If the call is not
also remotely held, call media will be reconnected as it was before
the call was held.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant
will be notified of the operation through a
[call:stateChange][47] event as well.

#### Parameters

*   `callId` **[string][8]** The ID of the call to unhold.

### unholdAsync

Takes a call off hold.

This API is equivalent to the [call.unhold][58] API, but provides feedback via a returned promise. This API
will not emit events specifically about the operation's completion, but may emit events if the call's state
changes and when tracks are added to the call.

The specified call to unhold must be locally held. If the call is not
also remotely held, call media will be reconnected as it was before
the call was held.

The SDK will emit a [call:stateChange][47] event locally if the operation
successfully unholds the call. A [call:tracksAdded][61]
event will also be emitted to indicate the tracks that were added to the call. The remote
participant will receive equivalent events.

#### Parameters

*   `callId` **[string][8]** The ID of the call to unhold.

#### Examples

```javascript
try {
    await client.call.unholdAsync(callId)
    // Operation succeeded.
    // client.call.getById(callId).state === 'Connected'
} catch (error) {
    // Operation failed.
    const { message, code } = error
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### addMedia

Add new media tracks to an ongoing call.
Will get new media tracks from the specific sources to add to the call.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:newTrack][51] event
both for the local and remote users to indicate a track has been
added to the Call.

#### Parameters

*   `callId` **[string][8]** The ID of the call to add media to.
*   `media` **[Object][7]** The media options to add to the call. (optional, default `{}`)

    *   `media.audio` **[boolean][11]** Whether to add audio to the call. (optional, default `false`)
    *   `media.video` **[boolean][11]** Whether to add video to the call. (optional, default `false`)
    *   `media.screen` **[boolean][11]** Whether to add the screenshare to the call. (Note: Screensharing is not supported on iOS Safari.) (optional, default `false`)
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** List of detached medias containing tracks to be attached to this call.
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the call's audio.
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
*   `options` **[Object][7]?**  (optional, default `{}`)

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic

### addMediaAsync

Add new media tracks to an ongoing call.
Will get new media tracks from the specific sources to add to the call.

This API is equivalent to the [call.addMedia][62] API, but provides feedback via a returned promise. This API
will not emit events specifically about the operation's completion, but may emit events if the call's state
changes.

The SDK will emit a [call:newTrack][51] event
both for the local and remote users to indicate a track has been
added to the Call.

#### Parameters

*   `callId` **[string][8]** The ID of the call to add media to.
*   `media` **[Object][7]** The media options to add to the call. (optional, default `{}`)

    *   `media.audio` **[boolean][11]** Whether to add audio to the call. (optional, default `false`)
    *   `media.video` **[boolean][11]** Whether to add video to the call. (optional, default `false`)
    *   `media.screen` **[boolean][11]** Whether to add the screenshare to the call. (Note: Screensharing is not supported on iOS Safari.) (optional, default `false`)
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** List of detached medias containing tracks to be attached to this call.
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the call's audio.
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
*   `options` **[Object][7]?**  (optional, default `{}`)

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic

#### Examples

```javascript
try {
  // Add video to a call.
  const { tracks } = await client.call.addMediaAsync(callId, { video: true })
} catch (error) {
  // Failed to add media.
  const { code, message } = error
  ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<{tracks: [Array][20], mediaId: [Array][20]}>** A promise that resolves when the operation is successful.

### removeMedia

Remove tracks from an ongoing call.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:trackEnded][56]
event for both the local and remote users to indicate that a track
has been removed.

#### Parameters

*   `callId` **[string][8]** The ID of the call to remove media from.
*   `tracks` **[Array][20]** A list of track IDs to remove.
*   `options` **[Object][7]?**  (optional, default `{}`)

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.

### removeMediaAsync

Remove tracks from an ongoing call.

This API is equivalent to the [call.removeMedia][63] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the call's
state changes.

The SDK will emit a [call:trackEnded][56] event for both the local and remote users
to indicate that a track has been removed.

#### Parameters

*   `callId` **[string][8]** The ID of the call to remove media from.
*   `tracks` **[Array][20]** A list of track IDs to remove.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.

#### Examples

```javascript
try {
  // Remove a specific track from a call.
  await client.call.removeMediaAsync(callId, [trackId])
} catch (error) {
  // Handle error
  const { code, message } = error
  ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### startVideo

Adds local video to an ongoing Call, to start sending to the remote
participant.

Can only be used in a basic media scenario, where the Call does not
already have video. For more advanced scenarios, the
[call.addMedia][62] API can be used.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:tracksAdded][61]
event both for the local and remote users to indicate a track has been
added to the Call.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic.

### startVideoAsync

Adds local video to an ongoing Call, to start sending to the remote participant.

This API is equivalent to the [call.startVideo][64] API, but provides feedback via a returned promise. This
API will not emit events specifically about the operation's completion, but may emit an event if the call's
state changes.

Can only be used in a basic media scenario, where the Call does not already have video. For more advanced
scenarios, the [call.addMedia][62] API can be used.

The SDK will emit a [call:tracksAdded][61] event both for the local and
remote users to indicate a track has been added to the Call.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `videoOptions` **[call.VideoOptions][40]?** Options for configuring the call's video.
*   `options` **[Object][7]?** 

    *   `options.bandwidth` **[call.BandwidthControls][43]?** Options for configuring media's bandwidth.
    *   `options.dscpControls` **[call.DSCPControls][45]?** Options for configuring DSCP markings on the media traffic.

#### Examples

```javascript
try {
  // Add video to a call.
  const { tracks } = await client.call.startVideoAsync(callId)
} catch (error) {
  // Failed to add video.
  const { code, message } = error
  ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<{tracks: [Array][20], mediaId: [Array][20]}>** A promise that resolves when the operation is successful.

### stopVideo

Removes local video from an ongoing Call, stopping it from being sent
to the remote participant.

Can only be used in a basic media scenario, where the Call has only one
video track. For more advanced scenarios, the
[call.removeMedia][63] API can be used.

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a [call:tracksRemoved][60]
event for both the local and remote users to indicate that a track
has been removed.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.

### stopVideoAsync

Removes local video from an ongoing Call, stopping it from being sent to the remote participant.

This API is equivalent to the [call.stopVideo][65] API, but provides feedback via a returned promise. This API
will not emit events specifically about the operation's completion, but may emit an event if the call's tracks
are modified.

Can only be used in a basic media scenario, where the Call has only one video track. For more advanced scenarios,
the [call.removeMedia][63] API can be used.

The SDK will emit a [call:tracksRemoved][60] event for both the local and remote
users to indicate that a track has been removed.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.

#### Examples

```javascript
try {
  // Remove video from a call.
  await client.call.stopVideoAsync(callId)
} catch (error) {
  // Failed to remove video.
  const { code, message } = error
  ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### replaceTrack

Replace a call's track with a new track of the same media type.

The operation will remove the old track from the call and add a
new track to the call. This effectively allows for changing the
track constraints (eg. device used) for an ongoing call.

Because it completely replaces an old track with a new one,
the old track's state characteristics are not carried over in the new track's state.
(e.g. if an old track's state was 'muted' and replacement of this track has occured,
the new track's state will be 'unmuted', as this is its default state)

The progress of the operation will be tracked via the
[call:operation][34] event.

The SDK will emit a
[call:trackReplaced][66] event
locally when the operation completes. The newly added track will need
to be handled by the local application. The track will be replaced
seamlessly for the remote application, which will not receive an event.

#### Parameters

*   `callId` **[string][8]** The ID of the call to replace the track of.
*   `trackId` **[string][8]** The ID of the track to replace.
*   `media` **[Object][7]** The media options. (optional, default `{}`)

    *   `media.audio` **[boolean][11]** Whether to create an audio track. (optional, default `false`)
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the audio track.
    *   `media.video` **[boolean][11]** Whether to create a video track. (optional, default `false`)
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the video track.
    *   `media.screen` **[boolean][11]** Whether to create a screen share track. (optional, default `false`)
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** The detached media containing the track to be attached to this
        call. Though this parameter is an array for consistency with other APIs, it should only contain one entry.

#### Examples

```javascript
const callId = ...
// Get the video track used by the call.
const videoTrack = ...

// Replace the specified video track of the call with a new
//    video track.
client.call.replaceTrack(callId, videoTrack.id, {
  // The track should be replaced with a video track using
  //    a specific device. This effectively changes the input
  //    device for an ongoing call.
  video: true,
  videoOptions: {
    deviceId: cameraId
  }
})
```

```javascript
const callId = ...
// Get the video track used by the call.
const videoTrack = ...

// Can also replace the specified video track of the call with a new
// screen sharing track because screen sharing is delivered as a video stream to remote peer.
// User will then be prompted to pick a specific screen to share and thus the device id will be selected.
client.call.replaceTrack(callId, videoTrack.id, {
  // The track should be replaced with a screen sharing track.
  // Note that 'screenOptions' property is not mandatory, as API will use default values
  // for properties like: width, height, frameRate.
  screen: true
})
```

### replaceTrackAsync

Replace a call's track with a new track of the same media type.

This API is equivalent to the [call.replaceTrack][67] API, but provides feedback via a returned promise.

The operation will remove the old track from the call and add a new track to the call. This effectively allows
for changing the track constraints (eg. device used) for an ongoing call. The track will be replaced seamlessly
for the remote application.

Because it completely replaces an old track with a new one, the old track's state characteristics are not carried
over in the new track's state. (e.g. if an old track's state was 'muted' and replacement of this track has
occured, the new track's state will be 'unmuted', as this is its default state)

#### Parameters

*   `callId` **[string][8]** The ID of the call to replace the track of.
*   `trackId` **[string][8]** The ID of the track to replace.
*   `media` **[Object][7]** The media options. (optional, default `{}`)

    *   `media.audio` **[boolean][11]** Whether to create an audio track. (optional, default `false`)
    *   `media.audioOptions` **[call.AudioOptions][39]?** Options for configuring the audio track.
    *   `media.video` **[boolean][11]** Whether to create a video track. (optional, default `false`)
    *   `media.videoOptions` **[call.VideoOptions][40]?** Options for configuring the video track.
    *   `media.screen` **[boolean][11]** Whether to create a screen share track. (optional, default `false`)
    *   `media.screenOptions` **[call.ScreenOptions][41]?** Options for configuring the call's screenShare.
    *   `media.medias` **[Array][20]<[media.DetachedMedia][42]>?** The detached media containing the track to be attached to this
        call. Though this parameter is an array for consistency with other APIs, it should only contain one entry.

#### Examples

```javascript
// ID of the current audio track of the call.
const audioTrackId = ...

// Replace the existing audio track of the call with a new audio track from a specific microphone.
try {
 const { newTrackId, oldTrack } = await client.call.replaceTrackAsync(callId, audioTrackId, {
   audio: true,
   audioOptions: { deviceId: microphoneId }
 })
   // Operation succeeded.
} catch (error) {
  // Operation failed.
  const { code, message } = error
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<{newTrackId: [string][8], oldTrack: [Object][7]}>** A promise that resolves when the operation is successful.

### restartMedia

Attempt to re-establish a media connection for a call.

This API will perform a "refresh" operation on the call with the intention
of resolving media issues that may have been encountered. This API is only
necessary after the Call's [mediaConnectionState][68]
has entered the `failed` state, but may be used in other scenarios.

After the operation completes successfully, the Call will be re-establishing
its media connection. By this time, or shortly after, the Call's
[mediaConnectionState][68] should have
transitioned to `checking` (via a
[call:mediaConnectionChange][69]
event) to signify the re-establishment. It will then transition to either
`connected` or `failed` state, similar to during the initial Call establishment.

If this operation fails, then the Call will not attempt the re-establishment
and will remain in the `failed` [mediaConnectionState][68].

Behaviour during the operation may differ slightly based on the browser.
Notably, Firefox will always transition to the `checking`
[mediaConnectionState][68] no matter what
the previous state was. Whereas Chrome will skip the `checking` state,
transitioning directly to either `connected` or `failed`. This has the
implication for Chrome that if the state does not change (for example,
the Call is in the `failed` state before the media restart operation,
and media re-establishment fails), then there will be no
[call:mediaConnectionChange][69]
event emitted. For this reason, Chrome-based applications may need a
short delay after receiving the [call:mediaRestart][70]
event before checking the Call's updated
[mediaConnectionState][68] to ensure the
application is acting on the "latest" state.

The SDK will emit a [call:mediaRestart][70]
event when the operation completes.

The progress of the operation will be tracked via the
[call:operation][34] event.

#### Parameters

*   `callId` **[string][8]** The ID of the call to act on.

### restartMediaAsync

Attempt to re-establish a media connection for a call.

This API is equivalent to the [call.restartMedia][71] API, but provides feedback via a returned promise instead
of emitting events.

This API will perform a "refresh" operation on the call with the intention
of resolving media issues that may have been encountered. This API is only
necessary after the Call's [mediaConnectionState][68]
has entered the `failed` state, but may be used in other scenarios.

If this operation fails, then the Call will not attempt the re-establishment
and will remain in the `failed` [mediaConnectionState][68].

Behaviour during the operation may differ slightly based on the browser.
Notably, Firefox will always transition to the `checking`
[mediaConnectionState][68] no matter what
the previous state was. Whereas Chrome will skip the `checking` state,
transitioning directly to either `connected` or `failed`. This has the
implication for Chrome that if the state does not change (for example,
the Call is in the `failed` state before the media restart operation,
and media re-establishment fails), then there will be no
[call:mediaConnectionChange][69]
event emitted. For this reason, Chrome-based applications may need a
short delay after receiving the [call:mediaRestart][70]
event before checking the Call's updated
[mediaConnectionState][68] to ensure the
application is acting on the "latest" state.

#### Parameters

*   `callId` **[string][8]** The ID of the call whose media needs to be restarted.

#### Examples

```javascript
try {
   await client.call.restartMediaAsync(callId)
   // Media was successfully re-synced.
} catch (error) {
   const { message, code } = error
   // Operation failed.
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### playAudioFile

Plays an audio file to the remote side of the Call. This API will temporarily
replace the Call's local audio track with an audio file for the duration
of the audio file.

The Call must be in `Connected` state and have a local audio track for this operation.

This API will not affect media other than the local audio track. Other media on
the Call, such as local video or remote audio, can be [muted][72]
or [unrendered][73] during this operation if desired.

This operation will use the browser's
[Audio constructor][74]
to read in the audio file. The `filePath` parameter will be used directly with `Audio`, so
can be either a relative file path to your audio file or a URL pointing to a file.

This API returns a promise that can be used to track the progress of the operation.
The promise will resolve after the operation completes or reject if an error is
encountered. Additionally, an extra `onPlaying` callback is provided on the Promise
to indicate when the audio file actually begins to play. See the code example below
for a sample.

The SDK will emit [call:operation][34] events locally
as the operation progresses. The remote endpoint will not receive an event for
this operation.

If an error is encountered during the operation and the SDK is unable to replace
the original local audio track, then that track will be forcibly ended and an
[media:trackEnded][75] event will be emitted
for it. This will release the microphone and avoid losing access to the track
while it is active, allowing the application to resolve the scenario by using
the [call.replaceTrack][67] API to revert the local audio track.

#### Parameters

*   `callId` **[string][8]** The ID of the Call to act on.
*   `filePath` **[string][8]** The path to the audio file.

#### Examples

```javascript
// The API returns a promise which will provide feedback about the operation.
client.call.playAudioFile(callId, filePath)
   .then(() => {
     // Audio file has finished playing; call has reverted to previous audio.
   })
   .catch(err => {
     // An error has occurred during the operation.
   })

// The returned promise can optionally provide feedback midway through the
//   operation. A chainable `onPlaying` method denotes when the audio file has
//   started to play and the Call's audio has been replaced.
client.call.playAudioFile(callId, filePath)
   .onPlaying(({ duration }) => {
     // Audio file has started playing; call audio is now the file.
     // Note: Calling `onPlaying` must be done before `then` and `catch` for it
     //    to be chainable.
   })
   .then(() => { ... })
   .catch(err => { ... })
```

Returns **[Promise][49]** Promise that resolves when the operation is complete.

### directTransfer

Performs a "direct" transfer on a call (also known as an unannounced or
blind transfer). This allows the current user to transfer the remote
participant of a call to another user, similar to a "forward"
operation.

The specified call must be locally held. After the operation, this call
will be ended, as indicated by a
[call:stateChange][47] event.

The "destination" user will receive an incoming call, and when answered,
they will be connected with the remote participant of the specified
call.

The progression of the operation will be tracked via the
[call:operation][34] event. The remote
participant being transferred will receive it as if it were a "remote
unhold" operation.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `destination` **([call.SIP_URI][37] | [call.TEL_URI][38])** The destination to transfer the call to.

### directTransferAsync

Performs a "direct" transfer on a call (also known as an unannounced or blind transfer). This allows the
current user to transfer the remote participant of a call to another user, similar to a "forward"
operation.

This API is equivalent to the [call.directTransfer][76] API, but provides feedback via a returned promise.
This API will only emit events that represent a change in state, and will resolve or reject the promise
to provide feedback about the operation itself.

The specified call must be locally held. After the transfer completes, this call will be ended, as indicated
by a [call:stateChange][47] event.

The "destination" user will receive an incoming call, and when answered, they will be connected with
the remote participant of the specified call. The remote participant being transferred will receive
it as if it were a "remote unhold" operation.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `destination` **([call.SIP_URI][37] | [call.TEL_URI][38])** The destination to transfer the call to.

#### Examples

```javascript
try {
   await client.call.directTransferAsync(callId, destination)
   // Operation success; call is now Ended.
} catch (error) {
   const { code, message } = error
   // Operation failed; call is still On Hold.
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### consultativeTransfer

Performs a "consultative" transfer between two ongoing calls (also known
as an announced or warm transfer). This allows the current user to
transfer the remote participant of a call to another user, after
having spoken to both users.

Both calls used for the transfer must be locally held. After the
operation, these calls will be ended, as indicated by a
[call:stateChange][47] event.

Both remote participants will see their call be unheld by the operation,
as indicated by a
[call:stateChange][47] event, and will
be connected to one another afterwards.

The progression of the operation will be tracked via the
[call:operation][34] event. Both local
calls will receive this event, since it is an operation on both calls,
and the remote calls will receive it as if it were a "remote unhold"
operation.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `otherCallId` **[string][8]** ID of the other call being acted on.

### consultativeTransferAsync

Performs a "consultative" transfer between two ongoing calls (also known
as an announced or warm transfer). This allows the current user to
transfer the remote participant of a call to another user, after
having spoken to both users.

This API is equivalent to the [call.consultativeTransfer][77] API, but provides feedback via a returned promise.
This API will only emit events that represent a change in state, and will resolve or reject the promise to
provide feedback about the operation itself.

Both calls used for the transfer must be locally held. After the operation, these calls will be ended, as
indicated by a [call:stateChange][47] event.

Both remote participants will see their call be unheld by the operation, as indicated by a
[call:stateChange][47] event, and will be connected to one another afterwards.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `otherCallId` **[string][8]** ID of the other call being acted on.

#### Examples

```javascript
try {
  await call.consultativeTransferAsync(callId, otherCallId)
} catch (error) {
  const { code, message } = error
  // Operation failed; calls are still On Hold.
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### join

Performs a "join" on two ongoing calls.
This allows the current user to establish a call with audio with two
remote users.

Both specified calls must be locally held. The new, "joined" call will be
audio-only, even if either previous call had video. Video cannot be
added to the "joined" call. Both remote participants will see their
call taken off hold, and will receive additional audio from other
participants after the operation. Both previous calls for the current
user will be ended after the operation, as indicated by a
[call:stateChange][47] event.

If the first call specified has custom parameters set, these parameters will be carried over to the new call.

The progress of the operation will be tracked via the
[call:operation][34] event. Both remote
participants will also receive this event as if it were a "remote
unhold" operation.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `otherCallId` **[string][8]** ID of the other call being acted on.

### joinAsync

Performs a "join" on two ongoing calls. This allows the current user to establish a call with audio with two
remote users.

This API is equivalent to the [call.join][78] API, but provides feedback via a returned promise.
This API will only emit events that represent a change in state, and will resolve or reject the promise to
provide feedback about the operation itself.

Both specified calls must be locally held. The new, "joined" call will be audio-only, even if either previous
call had video. Video cannot be added to the "joined" call. Both remote participants will see their call
taken off hold, and will receive additional audio from other participants after the operation. Both previous
calls for the current user will be ended after the operation, as indicated by a
[call:stateChange][47] event.

If the first call specified has custom parameters set, these parameters will be carried over to the new call.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `otherCallId` **[string][8]** ID of the other call being acted on.

<!---->

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### getAll

Retrieves the information of all calls made during the current session.

#### Examples

```javascript
let calls = client.call.getAll()
let currentCalls = calls.filter(call => {
    return call.state === client.call.states.CONNECTED
})
```

Returns **[Array][20]<[call.CallObject][50]>** Call objects.

### getById

Retrieves the information of a single call with a specific call ID.

#### Parameters

*   `callId` **[string][8]** The ID of the call to retrieve.

Returns **[call.CallObject][50]** A call object.

### sendRingingFeedback

Sends the "ringing feedback" notification to the remote participant of a call.

When using the 'manual' `ringingFeedbackMode` configuration, the application
is responsible for transitioning the call into the `Ringing` state. This
API will notify both ends of the call to enter `Ringing` state at the same
time. The application may decide not to send the "ringing feedback"
notification by not using this API. The `ringingFeedbackMode` configuration
must be set to 'manual' to use this API.

The specified call must be an incoming call in `Initiated` state. The call
will enter `Ringing` state as a result of the operation.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant will
be notified of the operation through a
[call:stateChange][47] event as well.

#### Parameters

*   `callId` **[string][8]** The ID of the call.

### sendRingingFeedbackAsync

Sends the "ringing feedback" notification to the remote participant of a call.

This API is equivalent to the [call.sendRingingFeedback][79] API, but provides feedback via a returned promise instead
of emitting events. This API will not emit events specifically about the operation's completion, but may
emit events if the call's state changes.

When using the 'manual' `ringingFeedbackMode` configuration, the application
is responsible for transitioning the call into the `Ringing` state. This
API will notify both ends of the call to enter `Ringing` state at the same
time. The application may decide not to send the "ringing feedback"
notification by not using this API. The `ringingFeedbackMode` configuration
must be set to 'manual' to use this API.

The specified call must be an incoming call in `Initiated` state. The call
will enter `Ringing` state as a result of the operation.

The SDK will emit a [call:stateChange][47]
event locally when the operation completes. The remote participant will
be notified of the operation through a
[call:stateChange][47] event as well.

#### Parameters

*   `callId` **[string][8]** The ID of the call.

<!---->

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### setCustomParameters

Set the [Custom Parameters][80] of a call, to be provided to the remote endpoint.

The provided parameters will be saved as part of the call data, to be used throughout the duration of the call.
All subsequent call operations will include these custom parameters. Therefore, invalid parameters, or
parameters not previously configured on the server, will cause subsequent call operations to fail. See
[Custom Parameters][80] for more information on constraints.

A Call's custom parameters are stored on the [CallObject][48], which can be retrieved using
the [call.getById][33] or [call.getAll][81] APIs.

The [call.sendCustomParameters][82] API can be used to send the custom parameters as a stand-alone REST request,
rather than as part of a call operation.

Custom parameters can be removed from a call's information by setting them as undefined (e.g.,
`call.setCustomParameters(callId)`). Subsequent call operations will then no longer send the custom parameters.

#### Parameters

*   `callId` **[string][8]** The ID of the call.
*   `customParameters` **([Array][20]<[call.CustomParameter][44]> | [undefined][27])** The custom parameters to set.

#### Examples

```javascript
// Set custom parameters on a call.
client.call.setCustomParameters(callId, [
   {
     name: 'Custom-Header',
     value: 'Custom Value'
   }
])
```

Returns **[undefined][27]** 

### sendCustomParameters

Send the custom parameters stored as part of an ongoing call to the Gateway. The server may either consume the
headers or relay them to another endpoint, depending on configuration.

Custom parameters are set on a call using the [call.setCustomParameters][83] API.

A Call's custom parameters are stored on the [CallObject][48], which can be retrieved using
the [call.getById][33] or [call.getAll][81] APIs.

#### Parameters

*   `callId` **[string][8]** The ID of the call being acted on.

### sendCustomParametersAsync

Send the custom parameters stored as part of an ongoing call to the Gateway. The server may either consume the
headers or relay them to another endpoint, depending on configuration.

This API is equivalent to the [call.sendCustomParameters][82] API, but provides feedback via a returned promise.

Custom parameters are set on a call using the [call.setCustomParameters][83] API.

A Call's custom parameters are stored on the [CallObject][48], which can be retrieved using
the [call.getById][33] or [call.getAll][81] APIs.

#### Parameters

*   `callId` **[string][8]** The ID of the call being acted on.

<!---->

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### sendDTMF

Send DTMF tones to a call's audio.

The provided tone can either be a single DTMF tone (eg. '1') or a
sequence of DTMF tones (eg. '123') which will be played one after the
other.

The specified call must be either in Connected, Ringing, or Early Media
state, otherwise invoking this API will have no effect.

The tones will be sent as out-of-band tones if supported by the call,
otherwise they will be added in-band to the call's audio.

The progress of the operation will be tracked via the
[call:operation][34] event.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `tone` **[string][8]** DTMF tone(s) to send. Valid characters are \['0','1','2','3','4','5','6','7','8','9','#','\*' and ','].
*   `duration` **[number][13]** The amount of time, in milliseconds, that each DTMF tone should last. (optional, default `100`)
*   `intertoneGap` **[number][13]** The length of time, in milliseconds, to wait between tones. (optional, default `70`)

### sendDTMFAsync

Send DTMF tones to a call's audio.

This API is equivalent to the [call.sendDTMF][84] API, but provides feedback via a returned promise.

The provided tone can either be a single DTMF tone (eg. '1') or a
sequence of DTMF tones (eg. '123') which will be played one after the
other.

The specified call must be either in Connected, Ringing, or Early Media
state, otherwise invoking this API will have no effect.

The tones will be sent as out-of-band tones if supported by the call,
otherwise they will be added in-band to the call's audio.

#### Parameters

*   `callId` **[string][8]** ID of the call being acted on.
*   `tone` **[string][8]** DTMF tone(s) to send. Valid characters are \['0','1','2','3','4','5','6','7','8','9','#','\*' and ','].
*   `duration` **[number][13]** The amount of time, in milliseconds, that each DTMF tone should last. (optional, default `100`)
*   `intertoneGap` **[number][13]** The length of time, in milliseconds, to wait between tones. (optional, default `70`)

<!---->

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### getStats

Retrieve a snapshot of the low-level information of the Call through statistical
report.

The data retrieved is a [RTCStatsReport][85]
object, which contains many individual
[RTCStats][86].
These are advanced statistics gathered by the browser providing insights
into the Call at a certain point in time. Aggregating reports over a
period of time would allow a low-level analysis of the Call for that
period. As an example, this could be done to determine the media quality
during the Call.

A Track ID can optionally be provided to get a report for a specific local
Track of the Call.

#### Parameters

*   `callId` **[string][8]** The ID of the Call to retrieve the report.
*   `trackId` **[string][8]?** ID of a local Track being used by the Call. If not
    provided, RTCStatsReport is generated for the Call itself.

#### Examples

```javascript
// Get a snapshot of the Call's stats.
//   This may be done on a regular interval to collect data over time.
try {
   // The API will return a promise that resolves with the stats.
   const result = await client.call.getStats(callId)
   // Report is a Map-like object so we can iterate through its data.
   result.forEach(stats => {
       // Handle the data on its own or collate with previously gathered stats
       //    for analysis.
       ...
   })
} catch (err) {
   // Handle the error.
   const { code, message } = err
   ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[RTCStatsReport][87]>** A promise that will resolve with the stats report, if operation succeeds.

### getAvailableCodecs

Retrieve the list of available and supported codecs based on the browser's capabilities for sending media.

This API will return a promise which, when resolved, it will contain the list of available and supported codecs.
In addition, the SDK emits a [call:availableCodecs][88] event
upon retrieving that list of codecs.

This API is a wrapper for the static method [RTCRtpSender.getCapabilities()][89].

#### Parameters

*   `kind` **[string][8]** The kind of media, i.e., 'audio' or 'video', to get the list of available codecs of.

#### Examples

```javascript
try {
   // The API will return a promise that resolves with the codecs.
   const result = await client.call.getAvailableCodecs('audio')
   // Iterate through the Array
   result.forEach(codec => {
       // Inspect the codec supported by browser by looking at its properties.
       ...
   })
} catch (err) {
   // Handle the error.
   const { code, message } = err
   ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[Array][20]>** A promise that will resolve with an array of available codecs.
If there was an error, it will return undefined.

### getReport

Retrieve the call metrics report for a call.

The object returned from this API will be in JSON format. The top level object is the report and will include
a timeline of events that were recorded during a call as well as a map object containing computed metrics.

Any event in a timeline will have it's own timeline that may have recorded events. Events in a timeline are scoped
to that timelines event or report.

The report and some events may have additional data included in a data property.

See event documentation [here][90].
See metrics documentation [here][91].

#### Parameters

*   `callId` **[string][8]** The id of the call to retrieve the report on.

Returns **[Object][7]** An object containing all metrics and data tracked against this call.

### setSdpHandlers

Set [SDP Handler Functions][92] that will be run as part of a pipeline for all future calls.
This will replace any SDP Handlers that were previously set.

SDP handlers can be used to make modifications to the SDP (e.g., removing certain codecs)
before they are processed or sent to the other side.

This is an advanced feature, changing the SDP handlers mid-call may cause
unexpected behaviour in future call operations for that call.

#### Parameters

*   `sdpHandlers` **[Array][20]<[call.SdpHandlerFunction][21]>** The list of SDP handler functions to modify SDP.

Returns **[undefined][27]** 

### states

Possible states that a Call can be in.

A Call's state describes the current status of the Call. An application
should use the state to understand how the Call, and any media
associated with the Call, should be handled. Which state the Call is
in defines how it can be interacted with, as certain operations can
only be performed while in specific states, and tells an application
whether the Call currently has media flowing between users.
Unless stated otherwise, the Call's state pertains to both caller & callee.

The Call's state is a property of the [CallObject][48],
which can be retrieved using the [call.getById][33] or
[call.getAll][81] APIs.

The SDK emits a [call:stateChange][47]
event when a Call's state changes from one state to another.

Type: [Object][7]

#### Properties

*   `INITIATING` **[string][8]** The (outgoing) call is being started. While in this state, no Call operations can be performed until Call gets into Initiated state.
*   `INITIATED` **[string][8]** A call has been started and both the callee and caller may now perform further operations on the call object.
*   `RINGING` **[string][8]** The call has been received by both parties, and is waiting to be answered.
*   `EARLY_MEDIA` **[string][8]** The call has not been answered, but media
    is already being received. This may be network-ringing media, IVR
    system media, or other pre-answer medias. When early media is
    supported, this state may replace the Ringing state. This is a state valid only for caller's side.
*   `CANCELLED` **[string][8]** The call was disconnected before it could be answered. This is a state valid only for callee's side.
*   `CONNECTED` **[string][8]** Both parties are connected and media is flowing.
*   `ON_HOLD` **[string][8]** Both parties are connected but no media is flowing.
*   `ENDED` **[string][8]** The call has ended.

#### Examples

```javascript
// Use the call states to know how to handle a change in the call.
client.on('call:stateChange', function (params) {
   const call = client.call.getById(params.callId)
   // Check if the call now has media flowing.
   if (call.state === client.call.states.CONNECTED) {
     // The call is now active, and can perform midcall operations.
   }
})
```

### mediaConnectionStates

Possible states that a Call's media connection can be in.

A Call's media connection state describes the current status of media within the call.
An application should use this state to understand whether the Call participants are
able to see/hear each other or may be experiencing connection issues. The media connection
state can be used alongside the [Call state][93] to determine if media issues
are occurring while the participants are expecting to be connected.

An important state to check for is the `FAILED` state. This state signifies that there is no
media connection between the call participants and an action must be taken to resolve the
problem. Using the [call.restartMedia][71] API will attempt to reconnect the media. See
the [call.restartMedia][71] API description for more information.

These states are direct reflections of the possible
[RTCPeerConnection.iceConnectionState][94] values.

The Call's media connection state is a property of the [CallObject][48],
which can be retrieved using the [call.getById][33] or
[call.getAll][81] APIs.

The SDK emits a [call:mediaConnectionChange][69]
event when a Call's media connection state changes from one state to another.

Type: [Object][7]

#### Properties

*   `NEW` **[string][8]** The Call is initializing the local side of the connection and waiting on information from the remote side.
    When the information is received, the state will transition into `checking` as the Call automatically begins the connection process.
*   `CHECKING` **[string][8]** The Call has received information from the remote endpoint and is working to establish the media connection.
    When finished, the state will transition to either `connected` or `failed`.
*   `CONNECTED` **[string][8]** A usable connection has been made and the Call will now have media.
    The connection may not be optimal, though, so the Call will continue establishment to improve the connection before going into the `completed` state.
*   `COMPLETED` **[string][8]** The media connection process has fully completed and the optimal connection has been established. While in this state,
    the Call endpoints will receive each other's media.
*   `DISCONNECTED` **[string][8]** Media has become disconnected and the Call endpoints have stopped receiving each other's media.
    The Call will automatically attempt to reconnect, transitioning back to `completed` if successful or to `failed` if not.
*   `FAILED` **[string][8]** The connection has failed and cannot be recovered automatically. A full media connection refresh is required to reestablish a connection. See the [call.restartMedia][71] API.
*   `CLOSED` **[string][8]** The connection has been shut down and is no longer in use.

#### Examples

```javascript
// Use the media connection states to check the status of the media connection of the Call.
client.on('call:mediaConnectionChange', function (params) {
  // Retrieve the state of the Call this event is for.
  const call = client.call.getById(params.callId)
  const mediaConnectionStates = client.call.mediaConnectionStates

  // Check the mediaConnectionState to determine which scenario the call is in.
  switch (call.mediaConnectionState) {
    case mediaConnectionStates.CONNECTED:
    case mediaConnectionStates.COMPLETED:
      // Media established: The Call's media is connected. The Call's participants
      //    are able to see/hear each other.
      // These states will occur after Call establishment.
      ...
      break
    case mediaConnectionStates.NEW:
    case mediaConnectionStates.CHECKING:
    case mediaConnectionStates.DISCONNECTED:
      // Media pending: The Call's media is not connected. The Call is working
      //    to connect media automatically.
      // These states will occur during Call establishment and may occur midcall if there are
      //    connection issues (eg. poor network quality) or a Call participant has changed (eg. transfer).
      ...
      break
    case mediaConnectionStates.FAILED:
     // Media has failed. The call requires a media refresh to reestablish.
     // This state will occur after the `DISCONNECTED` state is encountered.
     ...
      break
    case mediaConnectionStates.CLOSED:
      // Media ended due to the Call being ended.
      // This state will occur after Call establishment.
      ...
      break
  }
}
```

### reportEvents

Events used in the SDK's call reports.

As a call progresses, the operation(s)/function(s) being performed throughout
the duration of a call are recorded as events in a call report.
The call report can be retrieved via the [call.getReport][95] API.
An application can use these event names to find the associated event(s)
in the call report for more information on the event.
See *Call Reports* tutorial for more information on call reports and events.

Type: [Object][7]

#### Properties

*   `MAKE` **[string][8]** Starts when the make operation starts. Ends when the make operation finishes.
*   `SEND_RINGING_FEEDBACK` **[string][8]** Starts when the send ringing feedback operation starts. Ends when the ringing feedback operation finishes.
*   `RECEIVE_CALL` **[string][8]** Starts when the SDK receives a call and ends when the incoming call is setup.
*   `REMOTE_RINGING` **[string][8]** 
*   `ANSWER` **[string][8]** Starts when the answer operation starts. Ends when the answer operation finishes.
*   `GET_USER_MEDIA` **[string][8]** Starts when user media is requested from the browser and ends when the media is created.
*   `PROCESS_MEDIA_LOCAL` **[string][8]** Starts when the local media begins processing, and ends when the offer is set and ice collection completes.
*   `PROCESS_MEDIA_REMOTE` **[string][8]** Starts when the remote response is received, and ends when the remote media is set.
*   `ICE_COLLECTION` **[string][8]** Starts when ice candidate collection starts and ends when collection is complete.
*   `RELAY_CANDIDATE_COLLECTED` **[string][8]** Starts and ends when a relay candidate is collected. Event data contains info on the candidate.
*   `IGNORE` **[string][8]** Starts when the ignore operation starts. Ends when the ignore operation finishes.
*   `REJECT` **[string][8]** Starts when the reject operation starts. Ends when the reject operation finishes.
*   `FORWARD_CALL` **[string][8]** Starts when the forward call operation starts. Ends when the forward operation finishes.
*   `END_LOCAL` **[string][8]** Starts when the end operation starts. Ends when the end operation finishes.
*   `END_REMOTE` **[string][8]** Starts when the call status update ended operation starts. Ends when the call status update ended operation finishes.
*   `ADD_BASIC_MEDIA` **[string][8]** Starts when the add basic media operation starts. Ends when the add basic media operation finishes.
*   `ADD_MEDIA_LOCAL` **[string][8]** Starts when the add media operation starts. Ends when the add media operation finishes.
*   `ADD_MEDIA_REMOTE` **[string][8]** Starts when a remote add media notification is received and ends when the operation is handled.
*   `REMOVE_BASIC_MEDIA` **[string][8]** Starts when the remove basic media operation starts. Ends when the remove basic operation finishes.
*   `REMOVE_MEDIA` **[string][8]** Starts when the remove media operation starts. Ends when the remove media operation finishes.
*   `REMOVE_MEDIA_REMOTE` **[string][8]** Starts when a remote remove media notification is received and ends when the operation is handled.
*   `MEDIA_RESTART` **[string][8]** Starts when the media restart operation starts. Ends when the media restart operation finishes.
*   `REPLACE_TRACK` **[string][8]** Starts when the replace track operation starts. Ends when the replace track operation finishes.
*   `HOLD_LOCAL` **[string][8]** Starts when the hold operation starts. Ends when the hold operation finishes.
*   `HOLD_REMOTE` **[string][8]** Starts when a remote hold notification is received and ends when the operation is handled.
*   `UNHOLD_LOCAL` **[string][8]** Starts when the unhold operation starts. Ends when the unhold operation finishes.
*   `UNHOLD_REMOTE` **[string][8]** Starts when a remote unhold notification is received and ends when the operation is handled.
*   `REST_REQUEST` **[string][8]** Starts when a REST request is to be made for an operation and ends when a response is received, or it times out.
*   `PLAY_AUDIO` **[string][8]** Starts when the play audio operation starts. Ends when the play audio operation finishes.
*   `START_MOH` **[string][8]** Starts when the start music on hold operation starts. Ends when the start music on hold operation finishes.
*   `STOP_MOH` **[string][8]** Starts when the stop music on hold operation starts. Ends when the stop music on hold operation finishes.
*   `SEND_CUSTOM_PARAMETERS` **[string][8]** Starts when the send custom parameters operation starts. Ends send custom parameters operation finishes.
*   `GET_STATS` **[string][8]** Starts when the get stats operation starts. Ends when the get stats operation finishes.
*   `SEND_DTMF` **[string][8]** Starts when the send DTMF operation starts. Ends when the DTMF operation finishes.
*   `RESYNC` **[string][8]** Starts when the resync operation starts. Ends when the resync operation finishes.
*   `DIRECT_TRANSFER` **[string][8]** Starts when the direct transfer operation starts. Ends when the direct transfer operation finishes.
*   `CONSULTATIVE_TRANSFER` **[string][8]** Starts when the consultative transfer operation starts. Ends when the consultative transfer operation finishes.
*   `JOIN` **[string][8]** Starts when the join operation starts. Ends when the join operation finishes.
*   `GET_AVAILABLE_CODECS` **[string][8]** Starts when the get available codecs operation starts. Ends when the get available codecs operation finishes.
*   `SLOW_START` **[string][8]** Starts when the slow start operation starts. Ends when the slow stop operation finishes.

#### Examples

```javascript
const report = client.call.getReport('callId')
const getAvailableCodecsEvent = report.timeline.find(event => event.type === client.call.reportEvents.GET_AVAILABLE_CODECS)
log(`Took ${getAvailableCodecsEvent.end - getAvailableCodecsEvent.start}ms to get available codecs.`)
```

### metrics

List of metrics available as part of a Call Report.
Metrics are calculated only for the successful scenarios.

As a call progresses, timings are calculated for the duration of operations and
other events. They are recorded in a call report that can be retrieved via
the [call.getReport][95] API.

Type: [Object][7]

#### Properties

*   `CALL_DURATION` **[string][8]** The duration of a completed call starting from the make call API call or incoming call notification until the call ends.
*   `MAKE_CALL_PRE_LOCAL_SETUP` **[string][8]** The amount of time it takes from when the `make call` operation starts up until right before we set local description.
*   `MAKE_CALL_LOCAL_SETUP` **[string][8]** The amount of time it takes from when a call is made until the call is setup locally. This does not include any remote session creation.
*   `MAKE_CALL_REMOTE_SETUP` **[string][8]** The amount of time it takes from when the create session request is sent until the SDK processes the response.
*   `TIME_TO_MAKE` **[string][8]** For outgoing calls, the time for the `make` operation to complete.
*   `ANSWER_CALL_LOCAL_SETUP` **[string][8]** The amount of time it takes from when the `answer call` operation starts until it is setup locally.
    (i.e. from the time an incoming call is answered until media is connected)
*   `ANSWER_CALL_PRE_LOCAL_SETUP` **[string][8]** The amount of time it takes from when the `answer call` operation starts up until right before we set local description.
*   `TIME_TO_ANSWER` **[string][8]** For incoming calls, the time for the `answer` operation to complete.
*   `TIME_FROM_RECEIVE_TO_ANSWER` **[string][8]** For incoming calls, the time from the call first being received until it has been answered. Includes call processing and setup, as well as time for the answer API to have been called.
*   `TIME_TO_CALL_SETUP_DURATION` **[string][8]** For incoming calls, the time from the call first being received until media is connected. Similar to `TIME_FROM_RECEIVE_TO_ANSWER`, but without the `answer` REST request.
*   `TIME_TO_RINGING` **[string][8]** The amount of time it takes from when a call is made until the SDK recieves the remote ringing notification.
*   `TIME_TO_IGNORE` **[string][8]** The amount of time it takes for the ignore call to complete.
*   `TIME_TO_REJECT` **[string][8]** The amount of time it takes for the reject call to complete.
*   `TIME_TO_ADD_MEDIA` **[string][8]** The amount of time it takes from when the local `add media` operation starts until it has finished.
*   `TIME_TO_ADD_MEDIA_REMOTE` **[string][8]** The amount of time it takes from when the SDK receives a remote `add media` notification until it is handled and operation completes.
*   `TIME_TO_REMOVE_MEDIA` **[string][8]** The amount of time it takes from when the local `remove media` operation starts until it has finished.
*   `TIME_TO_REMOVE_MEDIA_REMOTE` **[string][8]** The amount of time it takes from when the SDK receives a remote `remove media` notification until it is handled and operation completes.
*   `TIME_TO_RESTART_MEDIA` **[string][8]** The amount of time it takes from when the `restart media` operation starts until it has finished.
*   `TIME_TO_HOLD_LOCAL` **[string][8]** The amount of time it takes from when the local `hold` operation starts until it has finished.
*   `TIME_TO_HOLD_REMOTE` **[string][8]** The amount of time it takes from when the SDK receives a remote `hold` notification until it is handled and operation completes.
*   `TIME_TO_UNHOLD_LOCAL` **[string][8]** The amount of time it takes from when the local `unhold` operation starts until it has finished.
*   `TIME_TO_UNHOLD_REMOTE` **[string][8]** The amount of time it takes from when the SDK receives a remote `unhold` notification until it is handled and operation completes.
*   `TIME_TO_COLLECT_ICE_CANDIDATES` **[string][8]** The amount of time it takes from when the local description is set to when all ICE candidates have been collected.
    This metric is affected by the [iceCandidatePoolSize][96] configuration. Collecting candidates ahead of time for the call will result in a shorter value for this metric, potentially resulting in it not being recorded if collection is not needed during call establishment.
*   `TIME_TO_RELAY_CANDIDATES` **[string][8]** The amount of time it takes from when the `ice collection` operation starts until each relay candidate has been recieved.
    This metric is affected by the [iceCandidatePoolSize][96] configuration. Collecting candidates ahead of time for the call will result in a shorter value for this metric, potentially resulting in it not being recorded if collection is not needed during call establishment.
*   `TIME_TO_SEND_CUSTOM_PARAMETERS` **[string][8]** The amount of time it takes from when the `send custom parameters` operation starts until it has finished.
*   `TIME_TO_FORWARD` **[string][8]** The amount of time it takes from when the `forward call` operation starts until it has finished.
*   `TIME_TO_DIRECT_TRANSFER` **[string][8]** The amount of time it takes from when the `direct transfer` operation starts until it has finished.
*   `TIME_TO_CONSULTATIVE_TRANSFER` **[string][8]** The amount of time it takes from when the `consultative transfer` operation starts until it has finished.
*   `TIME_TO_JOIN` **[string][8]** The amount of time it takes from when the `join call` operation starts until it has finished.

#### Examples

```javascript
const report = client.call.getReport(callId)
const callDuration = report.metrics.find(metric => metric.type === client.call.metrics.CALL_DURATION)
log(`Call duration was ${callDuration.data}ms.`)
```

### SIP_URI

The SIP URI ie: sip:[joe@domain.com][97]

Type: [string][8]

### TEL_URI

The TEL URI ie: tel:+18885559876

Type: [string][8]

### CallObject

Information about a Call.

Can be retrieved using the [call.getAll][81] or [call.getById][33] APIs.

Type: [Object][7]

#### Properties

*   `id` **[string][8]** The ID of the call.
*   `from` **[user.UserID][98]** A unique identifier (uri) of the person who made the call.
*   `to` **[user.UserID][98]** A unique identifier (uri) of the person who receives the call.
*   `direction` **[string][8]** The direction in which the call was created. Can be 'outgoing' or 'incoming'.
*   `state` **[string][8]** The current state of the call. See [call.states][93] for possible states.
*   `mediaConnectionState` **[string][8]** The current status of the call's media connection. See [call.mediaConnectionStates][68] for possible states.
*   `localHold` **[boolean][11]** Indicates whether this call is currently being held locally.
*   `remoteHold` **[boolean][11]** Indicates whether this call is currently being held remotely.
*   `localTracks` **[Array][20]<[string][8]>** A list of Track IDs that the call is sending to the remote participant.
*   `remoteTracks` **[Array][20]<[string][8]>** A list of Track IDs that the call is receiving from the remote participant.
*   `mediaOffered` **[call.MediaOffered][99]?** Information about what media was offered by the person who made the call.
*   `remoteParticipant` **[Object][7]** Information about the other call participant.

    *   `remoteParticipant.displayNumber` **[string][8]?** The User ID of the remote participant in the form "username@domain".
    *   `remoteParticipant.displayName` **[string][8]?** The display name of the remote participant.
*   `bandwidth` **[call.BandwidthControls][43]** The bandwidth limitations set for the call.
*   `customParameters` **[Array][20]<[call.CustomParameter][44]>** The locally set Custom Parameters for the call.
*   `startTime` **[number][13]** The start time of the call in milliseconds since the epoch.
*   `endTime` **[number][13]?** The end time of the call in milliseconds since the epoch.
*   `currentOperations` **[Array][20]<[Object][7]>** The list of operations curently on-going for the call.

### MediaConstraint

The MediaConstraint type defines the format for configuring media options.
Either the `exact` or `ideal` property should be provided. If both are present, the
`exact` value will be used.

When the `exact` value is provided, it will be the only value considered for the option.
If it cannot be used, the constraint will be considered an error.

When the `ideal` value is provided, it will be considered as the optimal value for the option.
If it cannot be used, the closest acceptable value will be used instead.

A string value can be provided directly instead of using the MediaConstraint format.
Using a string directly is not recommended, since behaviour may differ depending
on browser and media property. For most properties, a direct string value will be
handled as `ideal` behaviour, but some properties may follow the `exact` behaviour
(eg. `deviceId`).

Type: [Object][7]

#### Properties

*   `exact` **[string][8]?** The required value for the constraint. Other values will not be accepted.
*   `ideal` **[string][8]?** The ideal value for the constraint. Other values will be considered if necessary.

#### Examples

```javascript
// Specify video resolution when making a call.
client.call.make(destination, {
   audio: true,
   video: true,
   videoOptions: {
     // Set height and width constraints to ideally be 1280x720.
     height: { ideal: 720 },
     width: { ideal: 1280 }
   }
})
```

### AudioOptions

The AudioOptions type defines the format for specifying audio-related constraints.

Type: [Object][7]

#### Properties

*   `deviceId` **[call.MediaConstraint][100]** ID of the microphone to receive audio from.

#### Examples

```javascript
// Specify what specific microphone device to use by providing its device ID.
client.call.make(destination, {
   audio: true,
   audioOptions: { deviceId: 'some unique device ID' }
})
```

### VideoOptions

The VideoOptions type defines the format for specifying video-related constraints.

Type: [Object][7]

#### Properties

*   `deviceId` **[call.MediaConstraint][100]** ID of the camera to receive video from.
*   `height` **[call.MediaConstraint][100]?** The height of the video.
*   `width` **[call.MediaConstraint][100]?** The width of the video.
*   `frameRate` **[call.MediaConstraint][100]?** The frame rate of the video.

#### Examples

```javascript
client.call.make(destination, {
   video: true,
   videoOptions: {
     deviceId: 'some unique device ID',
     // Set height and width constraints to exactly be 1280x720.
     height: { exact: 720 },
     width: { exact: 1280 },
     frameRate: { exact: 24 }
   }
})
```

### ScreenOptions

The ScreenOptions type defines the format for specifying screen capturing-related constraints.

Type: [Object][7]

#### Properties

*   `height` **[call.MediaConstraint][100]?** The height of the screen capture.
*   `width` **[call.MediaConstraint][100]?** The width of the screen capture.
*   `frameRate` **[call.MediaConstraint][100]?** The frame rate of the live screen share.

#### Examples

```javascript
client.call.make(destination, {
   screen: true,
   screenOptions: {
     // Set height and width constraints to exactly be 1280x720.
     height: { exact: 720 },
     width: { exact: 1280 },
     frameRate: { exact: 24 }
   }
})
```

### MediaOffered

The MediaOffered type defines what media capabilities are offered by the person making a call.
This is an optional property and therefore may be null if it is not known or if it's associated with caller's side of the call.

Type: [Object][7]

#### Properties

*   `audio` **[boolean][11]** Specifies if any audio capability has been offered by the caller. If set to true, then the caller is capable of supporting at least one audio stream in the current call.
*   `video` **[boolean][11]** Specifies if any video capability has been offered by the caller. If set to true, then the caller is capable of supporting at least one video stream in the current call.

### BandwidthControls

The BandwidthControls type defines the format for configuring media and/or track bandwidth options.
BandwidthControls only affect received remote tracks of the specified type.

Type: [Object][7]

#### Properties

*   `call` **[number][13]?** The desired combined bandwidth bitrate in kilobits per second for all media in the call.
*   `audio` **[number][13]?** The desired bandwidth bitrate in kilobits per second for received remote audio.
*   `video` **[number][13]?** The desired bandwidth bitrate in kilobits per second for received remote video.

#### Examples

```javascript
// Specify received remote video bandwidth limits when making a call.
client.call.make(destination, mediaConstraints,
 {
   bandwidth: {
     video: 5
   }
 }
)
```

### DSCPControls

The DSCPControls type defines the format for configuring network priorities (DSCP marking) for the media traffic.

If DSCPControls are not configured for a call the network priority of the traffic for all media kinds will be the default (i.e., "low").

Type: [Object][7]

#### Properties

*   `audioNetworkPriority` **RTCPriorityType?** The desired network priority for audio traffic (see [RTCPriorityType Enum][101] for the list of possible values).
*   `videoNetworkPriority` **RTCPriorityType?** The desired network priority for video traffic (see [RTCPriorityType Enum][101] for the list of possible values).
*   `screenNetworkPriority` **RTCPriorityType?** The desired network priority for screen share traffic (see [RTCPriorityType Enum][101] for the list of possible values).

### RTCPeerConnectionConfig

Configuration options for an RTCPeerConnection.
It represents an RTCPeerConfiguration dictionary, whose parameters are documented [here][15].

Type: [Object][7]

#### Parameters

*   `iceServers` **[Array][20]\<RTCIceServer>?** The list of ICE servers to be used for calls.
    The full set of properties defined for an RTCIceServer, are mentioned
    [here][102].
*   `sdpSemantics` **[string][8]** The sdpSemantics to use (`'unified-plan'` or `'plan-b'`).
    As 'plan-b' has become a deprecated option, it will therefore be removed in the future. (optional, default `'unified-plan'`)
*   `iceCandidatePoolSize` **[number][13]** An unsigned 16-bit integer value which specifies
    the size of the prefetched ICE candidate pool. With a value greater than 0, the SDK will attempt to collect ICE candidates ahead of time for a call to speed up call establishment time.The default value of 1 is optimized for audio-only calls. A value of 2 can be provided to optimize for audio+video calls. A value of 0 can be provided to disable this feature. (optional, default `1`)
*   `iceTransportPolicy` **[string][8]?** The current ICE transport policy; if the policy isn't specified,
    'all' is assumed by default. Possible values are: 'all', 'public', 'relay'.
*   `bundlePolicy` **[string][8]?** For further description on this and other properties,
    see [RTCPeerConnection's configuration parameters][15].

### IceServer

Type: [Object][7]

#### Properties

*   `urls` **([Array][20]<[string][8]> | [string][8])** Either an array of URLs for reaching out several ICE servers or a single URL for reaching one ICE server. See [RTCIceServers.urls documentation][103] to learn more about the actual url format.
    Starting with Chromium 110, TURN(S) urls must only contain a transport
    parameter in the query section and STUN urls must not specify any query section.
*   `credential` **[string][8]?** The credential needed by the ICE server.
*   `username` **[string][8]?** The credential needed by the ICE server.

### IceCollectionInfo

This object is provided to the [IceCollectionCheckFunction][19], and contains the
necessary information about the call (i.e., call ID, current call operation), and information about the ongoing ICE collection,
such as the list of all ICE candidates collected so far and the ICE gathering state.

Type: [Object][7]

#### Properties

*   `callId` **[string][8]** The ID of the call.
*   `callOperation` **[string][8]** The current operation of the call.
*   `reason` **[string][8]** The reason the check function was called. Three possible values:
    'NewCandidate' - A new ICE candidate was collected. Note: there may be multiple new ICE candidates collected.
    'IceGatheringStateChanged' - The ICE gathering state changed.
    'Scheduled' - A scheduled call (for first invocation, and subsequent invocations based on `wait` value returned by [IceCollectionCheckFunction][19].)
*   `iceCandidates` **[Array][20]\<RTCIceCandidate>** An array of all ICE candidates collected so far.
*   `iceCollectionDuration` **[number][13]** The time elapsed since the start of the ICE collection process.
*   `iceGatheringState` **[string][8]** The current ICE gathering state.
    See [RTCPeerConnection.iceGatheringState][104].
*   `rtcPeerConnectionConfig` **[Object][7]** The current configration for the RTCPeerConnection.
*   `rtcLocalSessionDescription` **[string][8]** The current local session description set on the peer.

### IceCollectionCheckFunction

The form of the ICE collection check function, the arguments that it receives, and the outputs expected.

This function is provided the necessary details of the current WebRTC session and ICE collection
([IceCollectionInfo][17]), which it can use to dictate how to proceed with a call.
The function can be invoked for three different reasons:
a new ICE candidate was collected, the ICE gathering state changed, or a scheduled call based on the `wait` time set after
an initial invocation of the function.

The function must then return an appropriate result object in the format of [IceCollectionCheckResult][18]
which will dictate how the call will proceed. An incorrect return object, or result `type`, will cause the call to end with an error.

\[Default]
The default IceCollectionCheckFunction uses the following algorithm to determine if the call can proceed to negotiation:

1.  If the `iceGatheringState` is "complete" at any stage, then:
    *   Proceed with the negotiation if any ICE candidates are collected.
    *   Or, end the call if there are no ICE candidates collected.
2.  Otherwise, if before the ideal ICE collection timeout:
    *   If every media has a relay ICE candidate for every configured TURN server, proceed with negotiation.
    *   Else, wait until the ideal timeout, or when invoked for another reason.
3.  Otherwise, if before the max ICE collection timeout, but after the ideal ICE collection timeout:
    *   If every media has atleast one relay ICE candidate, proceed with negotiation.
    *   Else, wait until max timeout, or when invoked for another reason.
4.  Otherwise, if we are at, or past, the max ICE collection timeout:
    *   If there are any ICE candidates collected, proceed with negotiation.
    *   Else, end the call with an error.

The ideal and max timeouts can be configured with the `idealIceCollectionTimeout` and `maxIceCollectionTimeout` properties of
the call config.

Type: [Function][16]

#### Parameters

*   `iceCollectionInfo` **[call.IceCollectionInfo][105]** Information about the current status of the ICE candidate collection.
*   `iceTimeouts` **[Object][7]** Configurations provided to the SDK for ICE collection timeout boundaries.

    *   `iceTimeouts.iceCollectionIdealTimeout` **[number][13]** The amount of time to wait for ideal candidates, in
        milliseconds.  See [config.call][106] for more information.
    *   `iceTimeouts.iceCollectionMaxTimeout` **[number][13]** The maximum amount of time to wait for ICE collection,
        in milliseconds. See [config.call][106] for more information.

#### Examples

```javascript
function isRelayCandidate (candidate) {
// NOTE: This would need to be different for Firefox since the `.type` property doesn't exist
// and we would need to parse it ourselves in the `.candidate` property.
  return candidate.type === 'relay'
}

function myIceCollectionCheck ({ iceGatheringState, iceCandidates }, iceTimeouts) {
  if (iceGatheringState === 'complete') {
    if (iceCandidates.some(isRelayCandidate)) {
      return { type: 'StartCall' }
    } else {
      return { type: 'Error', error: new Error('Failed to start call because there is no relay candidates.') }
    }
  } else {
    return { type: 'Wait' }
  }
}
```

Returns **[call.IceCollectionCheckResult][107]** Information on how to proceed with the call and/or ICE collection.

### IceCollectionCheckResult

Type: [Object][7]

#### Properties

*   `type` **[string][8]** Indicates how the system should proceed with the call operation / ICE collection. The possible values are:
    'StartCall' - instruct the system to start the call with the currently gathered ICE candidates and other information.
    'Error' - instruct the system to fail the call with an error. The error to communicate to the user should be specified in the `error` property.
    'Wait' - instruct the system to wait for the specified amount of time before triggering a new ICE collection check. The amount
    of wait time should be specified in the `wait` property.
*   `error` **[string][8]** An error to be sent the user when the `type` of the result is `IceCollectionCheckResultType.Error`
*   `wait` **[number][13]** The amount of time (in milliseconds) to wait before triggering a new ICE collection check. This is only
    valid if the `type` of result is `IceCollectionCheckResultType.Wait`. If a value is not provided, the ICE collection check function
    will only be triggered for new candidates or when the ICE gathering state changes.

### SdpHandlerInfo

Type: [Object][7]

#### Properties

*   `callId` **[string][8]** The id corresponding to the call for which the handler is being run.
*   `type` **RTCSdpType** The session description's type.
*   `step` **[string][8]** The step that will occur after the SDP Handlers are run.
    Will be either 'set' (the SDP will be set locally) or 'send' (the SDP will
    be sent to the remote endpoint).
*   `endpoint` **[string][8]** Which end of the connection created the SDP.

### SdpHandlerFunction

The form of an SDP handler function and the expected arguments that it receives.

Type: [Function][16]

#### Parameters

*   `newSdp` **[Object][7]** The SDP so far (could have been modified by previous handlers).
*   `info` **[call.SdpHandlerInfo][108]** Additional information that might be useful when making SDP modifications.
*   `originalSdp` **[Object][7]** The SDP in its initial state.

Returns **[Object][7]** The resulting modified SDP based on the changes made by this function.

### MediaObject

The state representation of a Media object.
Media is a collection of Track objects.

Type: [Object][7]

#### Properties

*   `id` **[string][8]** The ID of the Media object.
*   `local` **[boolean][11]** Indicator on whether this media is local or remote.
*   `detached` **[boolean][11]** Indicator on whether this media contains detached tracks.
*   `tracks` **[Array][20]<[string][8]>** A list of track IDs representing the Track objects contained in this Media object.

### TrackObject

A Track is a stream of audio or video media from a single source.
Tracks can be retrieved using the Media module's `getTrackById` API and manipulated with other functions of the Media module.

Type: [Object][7]

#### Properties

*   `containers` **[Array][20]<[string][8]>** The list of CSS selectors that were used to render this Track.
*   `disabled` **[boolean][11]** Indicator of whether this Track is disabled or not. If disabled, it cannot be re-enabled.
*   `isLocal` **[boolean][11]** Indicator of whether this Track is a locally created one or is a remote one.
*   `id` **[string][8]** The ID of the Track.
*   `kind` **[string][8]** The kind of Track this is (audio, video).
*   `label` **[string][8]** The label of the device this Track uses.
*   `muted` **[boolean][11]** Indicator on whether this Track is muted or not.
*   `sourceMuted` **[boolean][11]** Indicator on whether this Track is receiving media from its source or not.
    When true, the Track can be considered removed. This indicator is affected by actions outside the
    control of the SDK, such as the remote endpoint of a Call stopping to send media for a remote Track,
    or the browser temporarily disabling the SDK's access to a local Track's source.
*   `state` **[string][8]** The state of this Track. Can be 'live' or 'ended'.
*   `streamId` **[string][8]** The ID of the Media Stream that includes this Track.

### DevicesObject

A collection of media devices and their information.

Type: [Object][7]

#### Properties

*   `camera` **[Array][20]<[call.DeviceInfo][109]>** A list of camera device information.
*   `microphone` **[Array][20]<[call.DeviceInfo][109]>** A list of microphone device information.
*   `speaker` **[Array][20]<[call.DeviceInfo][109]>** A list of speaker device information.

### DeviceInfo

Contains information about a device.

Type: [Object][7]

#### Properties

*   `deviceId` **[string][8]** The ID of the device.
*   `groupId` **[string][8]** The group ID of the device. Devices that share a `groupId` belong to the same physical device.
*   `kind` **[string][8]** The type of the device (audioinput, audiooutput, videoinput).
*   `label` **[string][8]** The name of the device.

### CustomParameter

Custom SIP headers can be used to convey additional information to a SIP endpoint.

Any SIP header can be used as a custom parameter, such as X-Headers or proprietary headers. However, if the defined
header name conflicts with another SIP header name in the SIP message, the existing SIP header will be removed
and the application's custom SIP header will be added to the message.

These parameters must be configured on the WebRTC Gateway prior to making a REST request, otherwise the request will
fail when trying to include the parameters. The WebRTC Gateway does not impose limitations on the length of a
header. See the Gateway documentation for more information.

These parameters can be provided in the [call.make][46] and [call.answer][52] APIs, to be included during call
establishment. They can also be set on the call after it is established using the [call.setCustomParameters][83]
API, then sent using the [call.sendCustomParameters][82] API.

Custom parameters may be received anytime throughout the duration a call. A remote endpoint may send custom headers
when starting a call, answering a call, or during call updates such as hold/unhold and addition/removal of media
in the call. When these custom headers are received, the SDK will emit a
[call:customParameters][110] event which will contain the custom parameters that
were received.

Custom parameters set on a call are stored on its [CallObject][48], which can be retrieved using
[call.getById][33] or [call.getAll][81] APIs. These are the parameters that will be sent to the remote
endpoint of the call. Parameters received from a call are not stored as part of the
[CallObject][48], and are only provided via the
[call:customParameters][110] event.

Type: [Object][7]

#### Properties

*   `name` **[string][8]** The name of the SIP header.
*   `value` **[string][8]** The value of the SIP header.

#### Examples

```javascript
// Specify custom SIP headers to be sent when making a call.
client.call.make(destination, mediaConstraints,
 {
   customParameters: [
     {
       name: 'X-GPS',
       value: '51.759028,-1.213278'
     },
     {
       name: 'X-Caller-ID',
       value: 'Coombs,Ernie'
     },
     {
       name: 'User-to-User',
       value: '48656c6c6f2c20576f726c6421;encoding=hex'
     }
   ]
 }
)

// Receive custom parameters from the remote endpoint of a call.
client.on('call:customParameters', params => {
  const { callId, customParameters } = params
  log(`Received custom parameters from call ${callId}:`, customParameters)
})
```

### call:operation

A call operation has either started, been updated, or finished.

Information about ongoing call operations are stored on the
[CallObject][48]. This event indicates that an operation's
information has changed.

The status of an operation indicates whether the local or remote side of the
call is currently processing it, with values being 'ONGOING' or 'PENDING',
respectively. All operations will begin as 'ONGOING' status with an event
indicating the 'START' transition. Operations that require a response from
the remote side will have an 'UPDATE' transition to the 'PENDING' status once
it starts to wait for the response. Once complete, an event will indicate
a 'FINISH' transition and the operation will be removed from the call state.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID for the call being operated on.
    *   `params.operation` **[string][8]** The type of operation causing this event.
    *   `params.operationId` **[string][8]** The unique ID of the call operation.
    *   `params.transition` **[string][8]** The transition reason for the operation change.
    *   `params.isLocal` **[boolean][11]** Flag indicating whether the operation was local or not.
    *   `params.previous` **[Object][7]?** The operation information before this change.
        If the transition is to "start" the operation, there will be no previous information.

        *   `params.previous.operation` **[string][8]?** The operation that was ongoing.
        *   `params.previous.status` **[string][8]?** The operation status before this change.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:operation', (params) => {
   const { callId, operationId } = params

   // Get the operation from the call's state that this event is about.
   const call = client.call.getById(callId)
   const operation = call.currentOperations.find(op => op.id === operationId)
   log(`${operation.type} operation is now ${operation.status} for call ${callId}.`)
})
```

### call:start

An outgoing call has been started.

Information about the Call can be retrieved using the [call.getById][33]
API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the call.

### call:join

A new joined call has been started.

Information about the Call can be retrieved using the [call.getById][33]
API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the call.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

### call:receive

A new incoming call has been received.

Information about the Call can be retrieved using the [call.getById][33]
API.

NOTE: Upon receiving this notification the call is in "Initiating" state. In order
to answer calls, they must be in either "Ringing" or "Initiated" states. Therefore,
this event should not be used to prompt the user to respond. Instead, the
[call:stateChange][47] event should be used for this purpose.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the call.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:receive', function(params) {
    // We have received a call
    promptUser(client.call.getById(params.callId));
});
```

### call:stateChange

A Call's state has changed.

See [call.states][93] for information about call states.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Media object that was operated on.
    *   `params.previous` **[Object][7]** The call's properties before the operation changed it.

        *   `params.previous.state` **[string][8]** The previous state of the call.
        *   `params.previous.localHold` **[boolean][11]?** The previous local hold state. Present when the state change was a hold/unhold operation.
        *   `params.previous.remoteHold` **[boolean][11]?** The previous remote hold state. Present when the state change was a hold/unhold operation.
    *   `params.transition` **[Object][7]?** Contains more detailed information about the state change.

        *   `params.transition.statusCode` **[number][13]?** The status code associated with the particular state change's reason.
        *   `params.transition.reasonText` **[string][8]?** The reason for the state change.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:stateChange', function (params) {
    const call = client.call.getById(params.callId)
    const prevState = params.previous.state
    log(`Call changed from ${prevState} to ${call.state} state.`)

    // Handle the event depending on the new call state.
    switch (call.state) {
        case client.call.states.CONNECTED:
            // Handle being on call with media.
            break
        case client.call.states.ENDED:
            // Handle call ending.
            break
        ...
    }
})
```

### call:newMedia

New media has been added to the call.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the call.
    *   `params.local` **[boolean][11]** Whether the new media is local or not.
    *   `params.tracks` **[Array][20]** The list of new Tracks.
    *   `params.mediaId` **[string][8]** The ID of the Media object the Tracks belong to.

### call:removedMedia

Media has been removed from the call.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the call.
    *   `params.local` **[boolean][11]** Whether the removed Media was local or not.
    *   `params.tracks` **[Array][20]** The list of removed Tracks.

### call:tracksAdded

Tracks have been added to the Call after an SDK operation. Both sides of the Call
are now able to render these tracks.

Tracks are added to a Call when either the local or remote user adds new media
to the Call, using the [call.addMedia][62] API for example, or when the
Call is unheld with the [call.unhold][58] API.

Remote tracks are similarly added to a Call when new tracks are added by the
remote user or either user unholds the call.

This event can indicate that multiple tracks have been removed by the same
operation. For example, if the remote user added video to the call, this
event would indicate a single, remote video track was added. If the local
user unheld the call, this event would indicate that any tracks previously
on the call have been re-added, both local and remote.

Information about a Track can be retrieved using the [media.getTrackById][111] API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Call the tracks were added to.
    *   `params.trackIds` **[Array][20]<[string][8]>** List of track IDs that have been added to the Call.

#### Examples

```javascript
client.on('call:tracksAdded', function (params) {
   // Get the information for each track.
   const tracks = params.trackIds.map(client.media.getTrackById)
   tracks.forEach(track => {
     const { id, kind, isLocal } = track
     // Handle the track depending whether it is audio vs. video and local vs. remote.
     ...
   })
})
```

### call:tracksRemoved

Tracks have been removed from the Call after an SDK operation. The tracks may still
exist, but the media is not available to both sides of the Call any longer.

Tracks are removed from a Call when either the local or remote user stops the
tracks, by using the [call.removeMedia][63] API for example, or when the
Call is held with the [call.hold][59] API.

This event can indicate that multiple tracks have been removed by the same
operation. For example, if the remote user removed video from the call, this
event would indicate a single, remote video track was removed. If the local
user held the call, this event would indicate that all tracks on the call
have been removed, both local and remote.

Information about a Track can be retrieved using the [media.getTrackById][111] API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Call the tracks were removed from.
    *   `params.trackIds` **[Array][20]<[string][8]>** List of track IDs that have been removed from the Call.

#### Examples

```javascript
client.on('call:tracksRemoved', function (params) {
   // Get the information for each track.
   const tracks = params.trackIds.map(client.media.getTrackById)
   tracks.forEach(track => {
     const { id, kind, isLocal } = track
     // Handle the track depending whether it is audio vs. video and local vs. remote.
     ...
   })
})
```

### call:statsReceived

Stats have been retrieved for a Call or specific Track of a Call.

See the [call.getStats][112] API for more information.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Call to retrieve stats for.
    *   `params.trackId` **[string][8]?** The ID of the Track to retrieve stats for.
    *   `params.result` **[Map][113]?** The RTCStatsReport.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:statsReceived', function (params) {
   if (params.error) {
     // Handle the error from the operation.
     const { code, message } = params.error
     ...
   } else {
     // Iterate over each individual statistic inside the RTCPStatsReport Map.
     // Handle the data on its own or collate with previously gathered stats
     //    for analysis.
     params.result.forEach(stat => {
       ...
     })
   }
})
```

### call:trackReplaced

A local Track has been replaced by the [call.replaceTrack][67] API.

This event is a combination of a track being removed from the Call and a new
track being added to the Call. The previous Track's media is no longer
available, similar to the [call:tracksRemoved][60]
event, and the new Track is available in its place, similar to the
[call:tracksAdded][61] event. The event
includes information about the Track that was replaced to help an application
replace it seamlessly.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the call where a track was replaced.
    *   `params.newTrackId` **[string][8]?** The ID of the new track that replaced the old track.
    *   `params.oldTrack` **[call.TrackObject][114]?** State of the replaced track.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:trackReplaced', function (params) {
  const { callId, oldTrack, newTrackId } = params

  // Unrender the removed track.
  handleTrackGone(oldTrack, callId)

  // Render the added track.
  const track = client.media.getTrackById(newTrackId)
  handleTrackAdded(track, callId)
})
```

### call:customParameters

Custom Parameters have been received for a Call.

These are parameters set by the remote endpoint of the Call. Please refer to
[CustomParameter][80] for more information.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Call in which custom parameters were received.
    *   `params.customParameters` **[Array][20]<[call.CustomParameter][44]>** The custom parameters received.

### call:availableCodecs

The list of available and supported codecs by the browser have been retrieved.

This event is emitted as a result of the [call.getAvailableCodecs][115] API. Please refer to the API for more
information.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.kind` **[string][8]** The kind of media the codecs are for.
    *   `params.codecs` **[Array][20]<[Object][7]>** The list of codecs.

#### Examples

```javascript
client.on('call:availableCodecs', function (codecs) {
   // Iterate over each codec.
   codecs.forEach(codec => {
       // Handle the data by analysing its properties.
       // Some codec instances may have the same name, but different characteristics.
       // (i.e. for a given audio codec, the number of suported channels may differ (e.g. mono versus stereo))
       ...
   })
})
```

### call:mediaConnectionChange

A Call's media connection state has been changed.

This event is emitted as a result of changes to the media connection of the Call.
These state changes occur during call establishment, connection loss/re-establishment, call completion, etc.

To check the media connection state of a call, retrieve the call's information using the  [call.getById][33] API,
and check the `mediaConnectionState` property of the call.
See [call.mediaConnectionStates][68] for the list of possible values and descriptions.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Call whose media connection state was changed.
    *   `params.previous` **[Object][7]** The call's media connection properties before the operation changed it.

        *   `params.previous.state` **[string][8]** The previous state of the media connection.

### call:mediaRestart

A media restart operation for a Call has been attempted.

This event is emitted as a result of the [call.restartMedia][71] API being called.
See the description for [call.restartMedia][71] for information about its
usage.

The [call:mediaConnectionChange][69] event
will also be emitted alongside this event when the media restart operation is
successful.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** The ID of the Call that was acted on.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:mediaRestart', function (params) {
   if (params.error) {
     // The operation failed. May want to determine whether to re-attempt the
     //    operation (if the failure was simply a connectivity issue) or to
     //    consider the call's media irrecoverable.
     ...
   } else {
     // The call should be re-establishing media, with the call's
     //    `mediaConnectionState` being updated.
     const mediaState = client.call.getById(params.callId).mediaConnectionState
     ...
   }
})
```

## callHistory

The 'call.history' namespace is used to retrieve and inspect the authenticated
users call logs.

Functions below are all part of this namespace.

### get

Gets the list of call logs cached locally. The event
`callHistory:changed` is used to indicate the local state of logs
has been updated.

#### Examples

```javascript
client.on('callHistory:change', function() {
    // Get all call logs when they've been updated.
    let callLogs = client.call.history.get();
});
```

Returns **[Array][20]** A list of call log records, ordered by latest first.

### fetch

Fetches the list of call logs and stores them locally. The API
[CallHistory.get][116] can then be used to get
the logs from local state after it has been updated.

#### Parameters

*   `amount` **[number][13]** The number of records to retrieve. (optional, default `50`)
*   `offset` **[number][13]** Starting offset for records to retrieve. (optional, default `0`)

### remove

Deletes the specified call log.

#### Parameters

*   `recordId` **[number][13]** The ID of the call log to be removed.

### clear

Deletes all call logs.

### getCache

Gets the cached call history data and returns stringified data.

The data is provided in a format that can be used directly with the
[call.history.setCache][117] API. This allows an
application to persist the information across SDK instances when the
backend environment does not support the CallHistory feature.

Returns **[string][8]** A stringified list of call log records from the cache, ordered by latest first.

### setCache

Sets the cached call history data, expects stringified data as it will be parsed.

The data can be retrieved from the [call.history.getCache][118] API. This allows an
application to persist the information across SDK instances when the
backend environment does not support the CallHistory feature.

#### Parameters

*   `data` **[string][8]** The stringified call history data to store in the cache.

### callHistory:change

Call history state has been updated. See [CallHistory.get][116] to retrieve new state.

### callHistory:error

An error occurred while performing a call history operation.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.

### callHistoryCache:change

Call history cached state has been updated

## clickToCall

The clickToCall namespace is used to bridge a call between two specified devices

### make

Attempts to establish a call between two specified devices.

#### Parameters

*   `caller` **[string][8]** A string representing the person making the call
*   `callee` **[string][8]** A string representing the person receiving the call

Returns **[string][8]** callId A unique id representing the call or undefined if there is an error.

### get

Gets all local clickToCall calls

Returns **[Array][20]** A list of clickToCall records, ordered by earliest requestTime

### clickToCall:start

ClickToCall has successfully started.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** A unique id representing the call made

### clickToCall:error

ClickToCall had an error.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.callId` **[string][8]** A unique id representing the call made
    *   `params.error` **[api.BasicError][29]** The Basic error object.

## connection

The 'connection' namespace is used to connect and maintain connections between
the SDK and one or more backend servers.

### getSocketState

Get the state of the websocket.

Returns **[connection.WSConnectionObject][119]** Details about the current websocket connection, including state and configuration.

### enableConnectivityChecking

Enables or disables connectivity checking.

This API will change the `connectivity.checkConnectivity` configuration set during SDK initialization. If there
was a connected websocket while it is changed, the change will take affect immediately.

#### Parameters

*   `enable` **[boolean][11]** Whether the websocket should be pinging to check for connectivity issues or not.

### resetConnection

Resets the connected websocket by manually disconnecting then reconnecting.

This API will simulate the SDK receiving a websocket disconnect from the browser,
which will trigger its recovery functionality. This API can be used if the application
is aware of a network issue before the SDK is notified by the browser.

If there is no websocket connected, this API has no effect. If the SDK is not configured
to autoreconnect (see `connectivity.autoReconnect` configuration property), then this
API will not attempt to reconnect the websocket automatically.

The normal websocket and lifecycle events will be emitted during this operation,
notably the [ws:change][120] event.

### WSConnectionObject

Information about a websocket connection.

Can be retrieved using the [connection.getSocketState][121] API.

Type: [Object][7]

#### Properties

*   `connected` **[boolean][11]** The state of the websocket connection.
*   `pinging` **[boolean][11]** True if the client has sent a ping to the server and is still waiting for a pong response.
*   `pingInterval` **[number][13]** How often the client will ping the server to test for websocket connectivity.
*   `reconnectLimit` **[number][13]** How many times the SDK will try to reconnect a disconnected websocket.
*   `reconnectDelay` **[number][13]** How long the SDK will wait before retrying websocket reconnection.
*   `reconnectTimeMultiplier` **[number][13]** Reconnect delay multiplier for subsequent attempts. The reconnect delay time will be multiplied by this after each failed reconnect attempt to increase the delay between attempts. eg. 5000ms then 10000ms then 20000ms delay if value is 2.
*   `reconnectTimeLimit` **[number][13]** Maximum time delay between reconnect attempts (milliseconds). Used in conjunction with `reconnectTimeMultiplier` to prevent overly long delays between reconnection attempts.
*   `autoReconnect` **[boolean][11]** Indicates if the SDK should automatically try reconnecting a disconnected websocket.
*   `webSocketOAuthMode` **[string][8]** The mode used for authenticating with the server.
*   `wsInfo` **[Object][7]** Information required to connect a websocket to the server.

    *   `wsInfo.protocol` **[string][8]?** The protocol to use to connect a websocket.
    *   `wsInfo.server` **[string][8]?** The domain name or IP address of the server to connect to.
    *   `wsInfo.port` **[number][13]?** The port of the server to connect to.
    *   `wsInfo.url` **[string][8]?** The URL path to use to request a websocket connection.
    *   `wsInfo.params` **[string][8]?** Any additional params that might be required by the server to establish the websocket connection.

### ws:change

The WebSocket to the server has changed state.

This event is only emitted when the WebSocket is connected, or has lost connection.

## contacts

The 'contacts' namespace allows users to store personal contacts to their account.

### add

Add a contact to a user's personal address book.
Will trigger the `contacts:new` event.

#### Parameters

*   `contact` **[Object][7]** The contact object.

    *   `contact.primaryContact` **[string][8]** The primary userId for the contact
    *   `contact.contactId` **[string][8]** The contact's unique contact ID
    *   `contact.firstName` **[string][8]?** The contact's first name
    *   `contact.lastName` **[string][8]?** The contact's last name
    *   `contact.photoUrl` **[string][8]?** The URL address identifying location of user's picture
    *   `contact.emailAddress` **[string][8]?** The contact's email address
    *   `contact.homePhone` **[string][8]?** The contact's home phone number
    *   `contact.workPhone` **[string][8]?** The contact's business phone number
    *   `contact.mobilePhone` **[string][8]?** The contact's mobile phone number
    *   `contact.conferenceURL` **[string][8]?** Conference URL and access code for this user's address book entry
    *   `contact.fax` **[string][8]?** The user's fax number
    *   `contact.pager` **[string][8]?** The user's pager number
    *   `contact.groupList` **[string][8]?** The name of the contact list for which to add this contact to ("friends" by default)
    *   `contact.friendStatus` **[boolean][11]?** Indicates whether or not the contact is a friend of the user

### get

Retrieves local information about a contact.

#### Parameters

*   `contactId` **[string][8]** The unique contact ID of the contact.

Returns **[Object][7]** Contact information.

### getAll

Retrieves local information about all contacts.

Returns **[Array][20]** List of contact information.

### refresh

Refreshes the local information about contacts. This will get new contacts from the platform.
Will trigger the `contacts:change` event.

### remove

Remove a contact from a personal address book.
Will trigger the `contacts:change` event.

#### Parameters

*   `id` **[string][8]** The Id of the contact that will be removed.

### update

Update a contact from the user's personal address book.
Will trigger the `contacts:change` event.

#### Parameters

*   `contact` **[Object][7]** The contact object.

    *   `contact.primaryContact` **[string][8]** The primary userId for the contact
    *   `contact.contactId` **[string][8]** The contact's unique contact ID
    *   `contact.firstName` **[string][8]?** The contact's first name
    *   `contact.lastName` **[string][8]?** The contact's last name
    *   `contact.photoUrl` **[string][8]?** The URL address identifying location of user's picture
    *   `contact.emailAddress` **[string][8]?** The contact's email address
    *   `contact.homePhone` **[string][8]?** The contact's home phone number
    *   `contact.workPhone` **[string][8]?** The contact's business phone number
    *   `contact.mobilePhone` **[string][8]?** The contact's mobile phone number
    *   `contact.conferenceURL` **[string][8]?** Conference URL and access code for this user's address book entry
    *   `contact.fax` **[string][8]?** The user's fax number
    *   `contact.pager` **[string][8]?** The user's pager number
    *   `contact.groupList` **[string][8]?** The name of the contact list for which to add this contact to ("friends" by default)
    *   `contact.friendStatus` **[boolean][11]?** Indicates whether or not the contact is a friend of the user

### fetch

Fetch a contact from the user's personal address book.
Will trigger the `contacts:change` event.

#### Parameters

*   `id` **[string][8]** The unique contact ID of the contact.

### contacts:new

A new contact has been added to the address book.

#### Parameters

*   `contact` **[Object][7]** The new contact.

### contacts:error

An error occurred while performing a contact operation.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[Object][7]** The Basic error object.

### contacts:change

The contacts list has changed.

#### Examples

```javascript
client.on('contacts:change', function () {
   // Get the updated list of contacts.
   const contacts = client.contacts.getAll()
   ...
})
```

## conversation

The messaging feature revolves around a 'conversation' namespace. It is responsible to store the conversations
and its messages, and return conversation objects when requested.

See the "Conversation" and "Message" sections of the documentation for more details.

Messaging functions are all part of the 'conversation' namespace. Ex: client.conversation.get('id').

### get

Get a conversation object matching the user ID provided in the 'destination' parameter.
If successful, the event 'conversations:change' will be emitted.

This API will retrieve a conversation already existing in the store.

#### Parameters

*   `destination` **[string][8]** The destination for messages created in this conversation. This will
    be a user's sip address.
*   `options` **[Object][7]?** An optional configuration object to query for more specific results.
    If this object is not passed, the function will query for "im" conversation with that recipient.

    *   `options.type` **[string][8]?** The type of conversation to retrieve. Can be one of "im", "sms" or "other".

Returns **[conversation.Conversation][122]** A Conversation object matching the passed destination, otherwise undefined is returned.

### getAll

Returns all conversations currently tracked by the SDK

Returns **[Array][20]<[conversation.Conversation][122]>** An array of conversation objects.

### Conversation

A Conversation object represents a conversation between two users.
A Conversation can create messages via the conversation's
[createMessage()][123] function.

Type: [Object][7]

#### Properties

*   `destination` **[string][8]** The id of the remote user with which the current user is having a conversation.

#### createMessage

Create and return a message object. You must provide a `text` part as demonstrated in the example.

##### Parameters

*   `part` **[Object][7]** The part to add to the message.

    *   `part.type` **[string][8]** The type of part. Must be "text".
    *   `part.text` **[string][8]** The text of the part. Must be a part of type "text".

##### Examples

```javascript
conversation.createMessage({type: 'text', text: 'This is the message'});
```

Returns **[conversation.Message][124]** The newly created Message object.

#### clearMessages

Clears all messages in this conversation from local state.

#### getMessages

Get the messages associated with this conversation.

Returns **[Array][20]<[Object][7]>** messages An array containing the conversation's messages.

Returns **[Function][16]** messages.markRead Marks the message as read.

Returns **[Function][16]** messages.forward Forward the message to another user.

Returns **[string][8]** messages.messageId The Id of the message.

Returns **[string][8]** messages.sender The user Id of the user who sent the message.

Returns **[number][13]** messages.timestamp The time at which the message was sent.

Returns **[boolean][11]** messages.read Whether the message has been marked as read.

Returns **[boolean][11]** messages.isPending Whether the message has finished being sent to the server.

Returns **[Array][20]** messages.parts The parts of the message.

#### getMessage

Get a specific message from this conversation.

##### Parameters

*   `messageId` **[string][8]** ID of the message to retrieve.

Returns **[Object][7]** A message object.

#### subscribe

Subscribe to this conversations messages array.

##### Parameters

*   `subscriber` **[Function][16]** A subscriber function to be triggered when the messages array of this conversation is updated.

    *   `subscriber.destination` **[string][8]** The conversation participants.
    *   `subscriber.messageId` **[string][8]** The ID of the message that caused the event.

Returns **[Function][16]** The unsubscribe function.

### Message

A Message object is a means by which a sender can deliver information to a recipient.

Creating and sending a message:

A message object can be obtained through the [Conversation.createMessage][123] API on an existing conversation.

Messages have Parts which represent pieces of a message. Currently, only a 'text' part is suported.
Once all the desired parts have been added to the message using the [Message.addPart][125] function,
the message can then be sent using the [Message.send][126] function.

Once the sender sends a message, this message is saved in sender's state as an object.
Similarly, once the recipient gets a message, this message is saved in recipient's state.

Retrieving a delivered message:

Once a message is delivered successfully, it can be
obtained through the [Conversation.getMessages][127] or [Conversation.getMessage][128] API on an existing conversation.

Below are the properties pertaining to the message object, returned by Conversation.getMessage(s) APIs, for either sender or recipient.

Type: [Object][7]

#### Properties

*   `timestamp` **[number][13]** A Unix timestamp in seconds marking the time when the message was created by sender.
*   `parts` **[Array][20]\<conversation.Part>** An array of Part Objects.
*   `sender` **[string][8]** The primary contact address of the sender.
*   `destination` **[Array][20]<[string][8]>** An array of primary contact addresses associated with various destinations to which the message is meant to be delivered. Currently, only one destination is supported.
*   `messageId` **[string][8]** The unique id of the message. The message object (stored in sender's state) has a different id
    than the one associated with the message object stored in recipient's state.
*   `type` **[string][8]** The type of message that was sent. See [conversation.chatTypes][129] for valid types.
    This property applies only to message objects stored in sender's state.

#### send

Sends the message.

### conversations:new

A new conversation has been created and added to the state.

### conversations:change

A change has occurred in the conversation list.

#### Parameters

*   `params` **[Array][20]** An array of objects containing information about the conversations that have changed

    *   `params.destination` **[Array][20]** The destination for messages created in this conversation.
    *   `params.type` **[string][8]** The type of conversation to create. Can be one of "chat", "im", "sms".

### messages:change

A change has occurred in a specific conversations message list.
If a single message was affected/created, `messageId` will be present
as part of the event argument.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.destination` **[string][8]** The destination for messages created in this conversation.
    *   `params.type` **[string][8]** The type of conversation to create. Can be one of "chat", "im", "sms".
    *   `params.messageId` **[string][8]?** The ID of the message affected.
    *   `params.sender` **[string][8]?** The username of the sender of the message which caused the `messages:change` event to be triggered.

### messages:error

An error occurred with messaging.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.

## logger

The SDK has an internal logging system for providing information about its
behaviour. The SDK will generate logs, at different levels for different
types of information, which are routed to a
"[Log Handler][4]" for consumption. An application
can provide their own Log Handler (see
[config.logs][130]) to customize how the logs are
handled, or allow the default Log Handler to print the logs to the
console.

The SDK's default Log Handler is merely a thin wrapper around the browser's
console API (ie. `window.console`). It receives the log generated by the
SDK, called a "[Log Entry][5]", formats a
human-readable message with it, then uses the console to log it at the
appropriate level. This is important to be aware of, since your browser's
console may affect how you see the SDK's default log messages. Since the
default Log Handler uses the console's levels, the browser may filter
which messages are shown depending on which levels it has configured. For
a user that understands console log levels, this can be helpful for
filtering the logs to only the relevant information. But it can equally
be a hindrance by hiding the more detailed log messages (at the 'debug'
level), since browser can have this level hidden by default. For this
reason, we recommend providing a custom Log Handler to the SDK that is
better suited for your application and its users.

### levels

Possible levels for the SDK logger.

The SDK will provide [Log Entries][5] to the
[Log Handler][4] for all logs at or above the set
log level. 'debug' is considered the lowest level and 'silent' the
highest level. For example, if the current level is 'info', then the
[Log Handler][4] will receive
[Log Entries][5] for logs at 'info', 'warn', and
'error', but not for the 'debug' level.

#### Properties

*   `SILENT` **[string][8]** Nothing will be logged.
*   `ERROR` **[string][8]** Unhandled error information will be logged. If
    the SDK encounters an issue it cannot resolve, the error will be included
    in the logs. This likely points to an issue with the SDK itself or an
    issue with how the SDK is being used.
*   `WARN` **[string][8]** Warning messages for the application developer will
    be logged. If the SDK encounters an issue that it can recover and continue,
    a warning about the issue will be included in the logs. These logs point
    to issues that need to be handled by the application. For example, providing
    an invalid configuration to the SDK will cause a warning log that explains
    the issue.
*   `INFO` **[string][8]** General information about the SDK's operations will
    be logged, outlining how the SDK is handling the operations. Reading through
    these logs should provide a high-level view of what the SDK is doing,
    and why it is doing it.
*   `DEBUG` **[string][8]** Detailed information about the SDK's operations,
    meant for debugging issues, will be logged. Specific information and relevant
    operation data are provided for understanding the scenario that the SDK
    was in during the operation.

### LogEntry

A LogEntry object is the data that the SDK compiles when information is
logged. It contains both the logged information and meta-info about when
and who logged it.

A [LogHandler][4] provided to the SDK (see
[config.logs][130]) will need to handle LogEntry
objects.

Type: [Object][7]

#### Properties

*   `timestamp` **[number][13]** When the log was created, based on UNIX epoch.
*   `method` **[string][8]** The log function that was used to create the log.
*   `level` **[string][8]** The level of severity the log.
*   `target` **[Object][7]** The subject that the log is about.

    *   `target.type` **[string][8]** The type of the target. This is also
        used as part of the name of the Logger.
    *   `target.id` **[string][8]?** A unique identifier for the target.
    *   `target.name` **[string][8]** A combination of the target type and ID. If no
        id was provided, this will be the same as the type.
*   `messages` **[Array][20]** The logged information, given to the Logger
    method as parameters.
*   `timer` **[Object][7]?** Timing data, if the log method was a timer method.

#### Examples

```javascript
function defaultLogHandler (logEntry) {
  // Compile the meta info of the log for a prefix.
  const { timestamp, level, target } = logEntry
  let { method } = logEntry
  const logInfo = `${timestamp} - ${target.type} - ${level}`

  // Assume that the first message parameter is a string.
  const [log, ...extra] = logEntry.messages

  // For the timer methods, don't actually use the console methods.
  //    The Logger already did the timing, so simply log out the info.
  if (['time', 'timeLog', 'timeEnd'].includes(method)) {
    method = 'debug'
  }

  console[method](`${logInfo} - ${log}`, ...extra)
}
```

### LogHandler

A LogHandler can be used to customize how the SDK should log information. By
default, the SDK will log information to the console, but a LogHandler can
be configured to change this behaviour.

A LogHandler can be provided to the SDK as part of its configuration (see
[config.logs][130]). The SDK will then provide this
function with the logged information.

Type: [Function][16]

#### Parameters

*   `LogEntry` **[Object][7]** The LogEntry to be logged.

#### Examples

```javascript
// Define a custom function to handle logs.
function logHandler (logEntry) {
  // Compile the meta info of the log for a prefix.
  const { timestamp, level, target } = logEntry
  let { method } = logEntry
  const logInfo = `${timestamp} - ${target.type} - ${level}`

  // Assume that the first message parameter is a string.
  const [log, ...extra] = logEntry.messages

  // For the timer methods, don't actually use the console methods.
  //    The Logger already did the timing, so simply log out the info.
  if (['time', 'timeLog', 'timeEnd'].includes(method)) {
    method = 'debug'
  }

  console[method](`${logInfo} - ${log}`, ...extra)
}

// Provide the LogHandler as part of the SDK configurations.
const configs = { ... }
configs.logs.handler = logHandler
const client = create(configs)
```

## media

The 'media' namespace provides an interface for interacting with Media that the
SDK has access to. Media is used in conjunction with the [Calls][131]
feature to manipulate and render the Tracks sent and received from a Call.

Media and Track objects are not created directly, but are created as part of
Call operations. Media and Tracks will either be marked as "local" or
"remote" depending on whether their source is the local user's machine
or a remote user's machine.

The Media feature also keeps track of media devices that the user's machine
can access. Any media device (eg. USB headset) connected to the machine
can be used as a source for media. Available devices can be found using
the [media.getDevices][132] API.

### getDevices

Retrieves the available media devices for use.

The [devices:change][133] event will be
emitted when the available media devices have changed.

Returns **[Object][7]** The lists of camera, microphone, and speaker devices.

### getById

Retrieves an available Media object with a specific Media ID.

#### Parameters

*   `mediaId` **[string][8]** The ID of the Media to retrieve.

Returns **[call.MediaObject][134]** A Media object.

### getTrackById

Retrieve an available Track object with a specific Track ID.

#### Parameters

*   `trackId` **[string][8]** The ID of the Track to retrieve.

Returns **[call.TrackObject][114]** A Track object.

### createLocalMedia

Create local media Tracks.

#### Parameters

*   `mediaConstraints` **[Object][7]** Collection of constraints for each media type.

    *   `mediaConstraints.audio` **[boolean][11]?** Native media constraints for audio.
    *   `mediaConstraints.video` **[boolean][11]?** Native media constraints for video.
    *   `mediaConstraints.screen` **[boolean][11]?** Native media constraints for display (screen).

#### Examples

```javascript
// Create detached media for your local video
const medias = await client.media.createLocalMedia({ video: true })
```

*   Throws **BasicError** Throws a USER_MEDIA_ERROR error if any any other media type other than audio, video or screen is passed in mediaConstraints.
*   Throws **BasicError** Throws a USER_MEDIA_ERROR error if provided constraints cannot be fulfilled.
*   Throws **BasicError** Throws a USER_MEDIA_ERROR error if it fails to get media for other reasons.

Returns **[Promise][49]<[Array][20]<[media.DetachedMedia][42]>>** Resolves with an array of objects containing both a media type and a media object.

### getLocalMedia

Gets an array of live detached media objects.

#### Examples

```javascript
await client.media.createLocalMedia({ video: true })
// Get all detached tracks
const medias = client.media.getLocalMedia()
```

Returns **[Array][20]<[media.DetachedMedia][42]>** An array of live detached media objects.

### disposeLocalMedia

Dispose local media Tracks.

#### Parameters

*   `localMedia` **([media.DetachedMedia][42] | [string][8])** An object representing the local media to dispose or a string representing a trackId.

<!---->

*   Throws **BasicError** An error indicating that trackId must be defined.
*   Throws **BasicError** An error indicating that the track that is to be disposed is in use by a call.
*   Throws **BasicError** An error indicating that the track that is to be disposed was not created locally.

Returns **[Promise][49]<[undefined][27]>** 

### initializeDevices

Requests permission to access media devices on the end-user's machine.

This API will trigger the browser to ask the end-user for permission to
access their camera and/or microphone. These permissions are
needed for the SDK to read information about the devices (the label,
for example) and for using the devices for a call.

If the browser does not yet have permission, it will prompt the end-user
with a small pop-up window, giving the user a chance to allow/deny the
permissions. The behaviour of this pop-up window differs slightly
based on the browser; it may automatically save the user's decision
(such as in Chrome and Safari) or it may require the user to choose
whether their decision should be saved (such as in Firefox).

This API is not required for proper usage of media and/or calls, but
helps to prepare a user before a call is made or received. It allows
an application to prompt the user for device permissions when it is
convenient for them, rather than during call setup. If the user saves
their decision, they will not be prompted again when the SDK accesses
those devices for a call.

For device information, the [media.getDevices][132] API will retrieve
the list of media devices available for the SDK to use. If this list
is empty, or is missing information, it is likely that the browser
does not have permission to access the device's information. We
recommend using the [media.initializeDevices][135] API in this
scenario if you would like to allow the end-user to select which
device(s) they would like to use when they make a call, rather than
using the system default.

The SDK will emit a [devices:change][133]
event when the operation is successful or a
[devices:error][136] event if an error is
encountered.

#### Parameters

*   `constraints` **[Object][7]?** 

    *   `constraints.audio` **[boolean][11]** Whether to ask for audio device permissions. (optional, default `true`)
    *   `constraints.video` **[boolean][11]** Whether to ask for video device permissions. (optional, default `true`)

#### Examples

```javascript
// The SDK will ask for both audio and video permissions by default.
client.media.initializeDevices()

// The SDK will only ask for audio permissions.
client.media.initializeDevices({ audio: true, video: false })
```

### initializeDevicesAsync

Requests permission to access media devices on the end-user's machine.

This API is equivalent to the [media.initializeDevices][135] API, but
provides feedback via a returned promise instead of emitting events.
This API will not cause any events to be emitted during this operation.

This API will trigger the browser to ask the end-user for permission to
access their camera and/or microphone. These permissions are
needed for the SDK to read information about the devices (the label,
for example) and for using the devices for a call.

If the browser does not yet have permission, it will prompt the end-user
with a small pop-up window, giving the user a chance to allow/deny the
permissions. The behaviour of this pop-up window differs slightly
based on the browser; it may automatically save the user's decision
(such as in Chrome and Safari) or it may require the user to choose
whether their decision should be saved (such as in Firefox).

This API is not required for proper usage of media and/or calls, but
helps to prepare a user before a call is made or received. It allows
an application to prompt the user for device permissions when it is
convenient for them, rather than during call setup. If the user saves
their decision, they will not be prompted again when the SDK accesses
those devices for a call.

For device information, the [media.getDevices][132] API will retrieve
the list of media devices available for the SDK to use. If this list
is empty, or is missing information, it is likely that the browser
does not have permission to access the device's information. We
recommend using the [media.initializeDevicesAsync][137] API in this
scenario if you would like to allow the end-user to select which
device(s) they would like to use when they make a call, rather than
using the system default.

#### Parameters

*   `constraints` **[Object][7]?** 

    *   `constraints.audio` **[boolean][11]** Whether to ask for audio device permissions. (optional, default `true`)
    *   `constraints.video` **[boolean][11]** Whether to ask for video device permissions. (optional, default `true`)

#### Examples

```javascript
try {
   // The SDK will ask for both audio and video permissions by default.
   await client.media.initializeDevicesAsync()
} catch (error) {
   // Error retrieving device permissions.
   const { code, message } = error
   ...
}

try {
   // The SDK will only ask for audio permissions.
   await client.media.initializeDevicesAsync({ audio: true, video: false })
} catch (error) {
   // Error retrieving device permissions.
   const { code, message } = error
   ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### renderTracks

Render Media Tracks in a container.

The container is specified by providing a CSS selector string that
corresponds to the HTMLElement to act as the container.

#### Parameters

*   `trackIds` **[Array][20]<[string][8]>** List of Track IDs to be rendered.
*   `cssSelector` **[string][8]** A CSS selector string that uniquely
    identifies an element. Ensure that special characters are properly
    escaped.
*   `options` **[Object][7]?** Additional options for rendering the tracks.

    *   `options.speakerId` **[string][8]?** The speaker's Device ID to use for audio tracks.

#### Examples

```javascript
// When a Call receives a new track, render it.
client.on('call:tracksAdded', function (params) {
   params.trackIds.forEach(trackId => {
     const track = client.media.getTrackById(trackId)
     const container = track.isLocal ? localContainer : remoteContainer

     // Render the Call's new track when it first becomes available.
     client.media.renderTracks([ trackId ], container)
   }
})
```

### renderTrackAsync

Render Media Track in a container.

This API is similar to the [media.renderTrack][138] API, but
provides feedback via a returned promise instead of emitting events.
This API will not cause any events to be emitted during this operation.

The container is specified by providing a CSS selector string that
corresponds to the HTMLElement to act as the container.

#### Parameters

*   `trackId` **[string][8]** Track ID to be rendered.
*   `cssSelector` **[string][8]** A CSS selector string that uniquely
    identifies an element. Ensure that special characters are properly
    escaped.
*   `options` **[Object][7]?** Additional options for rendering the tracks.

    *   `options.speakerId` **[string][8]?** The speaker's Device ID to use for audio tracks.

#### Examples

```javascript
// When a Call receives a new track, render it.
client.on('call:tracksAdded', function (params) {
   params.trackIds.forEach(trackId => {
     const track = client.media.getTrackById(trackId)
     const container = track.isLocal ? localContainer : remoteContainer

     try {
       // Render the Call's new track when it first becomes available.
       await client.media.renderTrackAsync(trackId, container)
     } catch (error) {
       // Failed to render the track.
       const { code, message } = error
       ...
     }
   }
})
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### muteTracks

Mutes the specified Tracks.

This API prevents the media of the specified Tracks from being rendered. Audio
Tracks will become silent and video Tracks will be a black frame.
This does not stop media from being received by those Tracks. The media simply
cannot be used by the application while the Track is muted.

If a local Track being sent in a Call is muted, the Track will be
noticeably muted for the remote user. If a remote Track received in a
call is muted, the result will only be noticeable locally.

This mute operation acts on those specified Tracks directly.
It does not act on the active Call as a whole.

The SDK will emit a [media:muted][139] event
when a Track has been muted.

#### Parameters

*   `trackIds` **[Array][20]<[string][8]>** List of Track IDs.

### muteTrackAsync

Mutes the specified Track.

This API is similar to the [media.muteTracks][72] API, but
provides feedback via a returned promise instead of emitting events.
This API will not cause any events to be emitted during this operation.
It will also only take a single track ID as an argument.

This API prevents the media of the specified Track from being rendered. Audio
Tracks will become silent and video Tracks will be a black frame.
This does not stop media from being received by those Tracks. The media simply
cannot be used by the application while the Track is muted.

If a local Track being sent in a Call is muted, the Track will be
noticeably muted for the remote user. If a remote Track received in a
call is muted, the result will only be noticeable locally.

This mute operation acts on the specified Track directly. It does not act on an
active Call as a whole.

#### Parameters

*   `trackId` **[string][8]** The ID of the track to mute.

#### Examples

```javascript
try {
   await client.media.muteTrackAsync(trackId)
} catch (error) {
   // Failed to mute the track.
   const { code, message } = error
   ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves with the list of muted track IDs.

### unmuteTracks

Unmutes the specified Tracks.

Media will resume its normal rendering for the Tracks.
Like the 'muteTracks' API, this unmute operation acts on those specified Tracks directly.
Therefore it does not act on active Call as a whole.

The SDK will emit a [media:unmuted][140] event
when a Track has been unmuted.

#### Parameters

*   `trackIds` **[Array][20]<[string][8]>** List of Track IDs.

### unmuteTrackAsync

Unmutes the specified Track.

This API is similar to the [media.unmuteTracks][141] API, but
provides feedback via a returned promise instead of emitting events.
This API will not cause any events to be emitted during this operation.
It will also only take a single track ID as an argument.

Media will resume its normal rendering for the Track.
Like the 'muteTrack' API, this unmute operation acts on the specified Track directly.
Therefore it does not act on active Call as a whole.

#### Parameters

*   `trackId` **[string][8]** Track ID to unmute.

#### Examples

```javascript
try {
   const unmutedId = await client.media.unmuteTrackAsync(trackId)
} catch (error) {
   // Failed to unmute the track.
   const { code, message } = error
   ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation succeeds.

### removeTracks

Remove Media Tracks from a container.

The container is specified by providing a CSS selector string that
corresponds to the HTMLElement to act as the container.

#### Parameters

*   `trackIds` **[Array][20]<[string][8]>** List of Track IDs to stop being rendered.
*   `cssSelector` **[string][8]** A CSS selector string that uniquely
    identifies an element. Ensure that special characters are properly
    escaped.

### removeTrackAsync

Remove Media Track from a container.

This API is similar to the [media.removeTracks][73] API, but provides feedback
via a returned promise instead of emitting events. This API will not cause any events
to be emitted during this operation. It will also only take a single track ID as
an argument.

The container is specified by providing a CSS selector string that
corresponds to the HTMLElement to act as the container.

#### Parameters

*   `trackId` **[string][8]** Track ID to stop being rendered.
*   `cssSelector` **[string][8]** A CSS selector string that uniquely
    identifies an element. Ensure that special characters are properly
    escaped.

#### Examples

```javascript
try {
  // Stop the track from being rendered.
  await client.media.removeTrackAsync(trackId, selector)
} catch (error) {
  // Failed to remove the track.
  const { code, message } = error
  ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### DetachedMedia

Detached Media is a special type of [call.MediaObject][142] that is created outside the scope of a call. A DetachedMedia
object is a [call.MediaObject][142] that is wrapped with the contained [call.TrackObject][143]'s media type for convenience.

The APIs for managing detached media are available in the [media][144] namespace. They are
[media.createLocalMedia][145], [media.getLocalMedia][146], and [media.disposeLocalMedia][147]. Unlike media that is created
as part of a call, the application is responsible for the lifecycle for a detached media object.

Accessing local media before a call is made can be used to implement a "media preview" feature, allowing an end-user to
check their media devices before joining a call.

Detached Media can also be used as part of a call, rather than new media being created as part of the call operations. This can be
done as an optimization, to avoid the overhead of creating new media objects during the call setup process. The same Detached
Media objects can be used for multiple calls, as well.

Type: [Object][7]

#### Properties

*   `media` **[call.MediaObject][134]** The media object.
*   `type` **[string][8]** The type of the media object ('audio', 'video', or 'screen').

#### Examples

```javascript
// Create new detached media objects.
const medias = await client.media.createLocalMedia({ audio: true, video: true })
// medias === [ { type: 'audio', media: <call.MediaObject> }, { type: 'video', media: <call.MediaObject> } ]
// where medias[x].type === client.media.getTrackById(medias[x].media.tracks[0].id).type)

// Render the local video as a preview.
client.media.renderTracks([ medias[1].media.tracks[0].id ], '#localVideoPreview')

// Use the Detached Media in a call, instead of creating new media for it.
const call = client.call.make('destination', { audio: false, video: false, medias: medias })
```

### devices:change

The media devices available for use have changed.

Information about the available media devices can be retrieved using the
[media.getDevices][132] API.

#### Examples

```javascript
// Listen for changes to available media devices.
client.on('devices:change', function () {
   // Retrieve the latest media device lists.
   const devices = client.media.getDevices()
})
```

### devices:error

An error occurred while trying to access media devices.

The most common causes of this error are when the browser does not have
permission from the end-user to access the devices, or when the browser
cannot find a media device that fulfills the
[MediaConstraint(s)][148] that was provided.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[Error][149]** The Basic error object.

### media:muted

The specified Tracks have been muted.

A Track can be muted using the [media.muteTracks][72] API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.tracks` **[Array][20]<[string][8]>** The list of Tracks that were muted.

### media:unmuted

The specified Tracks have been unmuted.

A Track can be unmuted using the [media.unmuteTracks][141]
API.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.tracks` **[Array][20]<[string][8]>** The list of Tracks that were unmuted.

### media:sourceMuted

The specified Track has had its media source muted.

The Track is still active, but is not receiving media any longer. An audio
track will be silent and a video track will be a black frame. It is
possible for the track to start receiving media again (see the
[media:sourceUnmuted][150] event).

This event is generated outside the control of the SDK. This will predominantly
happen for a remote track during network issues, where media will lose frames
and be "choppy". This may also happen for a local track if the browser or
end-user stops allowing the SDK to access the media device, for example.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.trackId` **[string][8]** The track that is affected as a result of media source being muted.

### media:sourceUnmuted

The specified Track has started receiving media from its source once again.

The Track returns to the state before it was muted (see the
[media:sourceMuted][151] event), and will
be able to display video or play audio once again.

This event is generated outside the control of the SDK, when the cause of the
media source being muted had been undone.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.trackId` **[string][8]** The track that is affected as a result of media source being unmuted.

### media:trackRendered

The specified Track has been rendered into an element.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.trackIds` **[Array][20]<[string][8]>** The list of track id's that were rendered.
    *   `params.selector` **[string][8]** The css selector used to identify the element the track is rendered into.
    *   `params.error` **[api.BasicError][29]?** An error object, if the operation was not successful.

### media:trackEnded

A local Track has ended unexpectedly. The Track may still be part of a Call but
has become disconnected from its media source and is not recoverable.

This event is emitted when an action other than an SDK operation stops the
track. The most comon scenarios are when a device being used for a Call
disconnects, any local tracks (such as audio from a bluetooth headset's
microphone or video from a USB camera) from that device will be ended.
Another scenario is for screensharing, where some browsers provide the
ability to stop screensharing directly rather than through an SDK operation.

When a local track ends this way, it will still be part of the Call but will
not have any media. The track can be removed from the call with the
[call.removeMedia][63] API so the remote side of the Call knows the track
has stopped, or the track can be replaced with a new track using the
[call.replaceTrack][67] API to prevent any interruption.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.trackId` **[Object][7]** The Track that has ended.
    *   `params.callId` **[Object][7]** The ID of the Call the Track is used in.

## notification

The 'notification' namespace allows user to register/deregister for/from push notifications as well as
enabling/disabling the processing of websocket notifications.

### process

Provides an external notification to the system for processing.

#### Parameters

*   `notification` **[Object][7]** The notification object from which to extract relevant data.
*   `channel` **[string][8]** The channel that the notification came from.
    If no channel provided, then by default it will be a PUSH notification. (optional, default `'PUSH'`)

Returns **[undefined][27]** 

### processAsync

Provides an external notification to the system for processing.

This API is equivalent to the [notification.process][152] API, but provides feedback via a returned promise.
This API's promise will resolve after the notification has been processed, rather than synchronously like
the [notification.process][152] API.

If the provided notification has a duplicate ID as a notification already processed, then the promise will
reject with an error.

#### Parameters

*   `notification` **[Object][7]** The notification object from which to extract relevant data.
*   `channel` **[string][8]** The channel that the notification came from.
    If no channel provided, then by default it will be a PUSH notification. (optional, default `'PUSH'`)

#### Examples

```javascript
try {
   await client.notification.processAsync(notification)
   // Notification has been processed.
} catch (error) {
   // Notification was a duplicate; not processed.
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### notifications:change

Push notifications registration state has changed.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.channel` **[string][8]** The channel for the notification.

### notifications:error

An error occurred with push notifications.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.
    *   `params.channel` **[string][8]** The channel for the notification.

## presence

The 'presence' namespace provides an interface for an application to set the
User's presence information and to track other Users' presence
information.

Presence information is persisted by the server. When the SDK is initialized,
there will be no information available. Presence information will become
available either by using [presence.fetch][153] or by subscribing for
updates about other Users, using [presence.subscribe][154].

Available presence information can be retrieved using [presence.get][155] or
[presence.getAll][156].

### statuses

Possible status values.

Type: [Object][7]

#### Properties

*   `OPEN` **[string][8]** 
*   `CLOSED` **[string][8]** 

#### Examples

```javascript
const { statuses, activities } = client.presence
// Use the values when updating presence.
client.presence.update(statuses.OPEN, activities.AVAILABLE)
```

### activities

Possible activity values.

Type: [Object][7]

#### Properties

*   `AVAILABLE` **[string][8]** 
*   `IDLE` **[string][8]** 
*   `AWAY` **[string][8]** 
*   `LUNCH` **[string][8]** 
*   `BUSY` **[string][8]** 
*   `VACATION` **[string][8]** 
*   `ON_THE_PHONE` **[string][8]** 
*   `UNKNOWN` **[string][8]** 

### update

Updates the presence information for the current user.

See [presence.statuses][157] and [presence.activities][158] for valid
values.

The SDK will emit a
[presence:selfChange][159] event
when the operation completes. The updated presence information is
available and can be retrieved with [presence.getSelf][160].

Other users subscribed for this user's presence will receive a
[presence:change][161] event.

#### Parameters

*   `status` **[string][8]** The status of the presence state.
*   `activity` **[string][8]** The activity to be shown as presence state
*   `note` **[string][8]?** An additional note to be provided when the activity is `presence.activities.ACTIVITIES_OTHER`.

### fetch

Fetches presence information for the given users. This will refresh the
available information with any new information from the server.

Available presence information an be retrieved using the
[presence.get][155] or [presence.getAll][156] APIs.

#### Parameters

*   `user` **([Array][20]<[string][8]> | [string][8])** A User ID or an array of User IDs.

### subscribe

Subscribe to another User's presence updates.

When the User updates their presence information, the SDK will emit a
[presence:change][161] event.

#### Parameters

*   `users` **([Array][20]<[string][8]> | [string][8])** A User ID or an array of User IDs.

### unsubscribe

Unsubscribe from another User's presence updates.

#### Parameters

*   `users` **([Array][20]<[string][8]> | [string][8])** A User ID or an array of User IDs.

### get

Retrieves the presence information for specified users, if available.

#### Parameters

*   `user` **([Array][20]<[string][8]> | [string][8])** A User ID or an array of User IDs.

Returns **([Array][20]<[Object][7]> | [Object][7])** List of user presence information.

### getAll

Retrieves the presence information for all available users.

Returns **[Array][20]<[Object][7]>** List of user presence information.

### getSelf

Retrieves the presence information for the current user.

This information is set using the [presence.update][162] API.

Returns **[Object][7]** Presence information for the current user.

### PresenceStatus

The PresenceStatus type defines the user's current status in terms of the user's availability to
communicate/respond to other users in the network.
An instance of this type can be obtained by invoking the [presence.get][155] function.

Reporting when a user is on the phone is enabled (by default), which means that presence update notifications
will be sent whenever a user is in a call, as well as when the call has ended.
This is a user preference enabled or disabled on server side, and it can only be changed on the server side.

The status is set to [open][157] as soon as a user subscribes for the presence service.

Type: [Object][7]

#### Properties

*   `userId` **[string][8]** The unique identifier for the user associated with this presence status.
*   `status` **[string][8]** The current status the user has set for themselves. For supported values see [presence.statuses][157].
*   `activity` **[string][8]** The current activity of the user.
    For supported values see [presence.activities][158].
*   `note` **[string][8]** Additional message accompanying the status & activity.
*   `loading` **[boolean][11]** Whether the presence information has been loaded or is in the process of loading.

### presence:change

A presence update about a subscribed user has been received.

This event is generated as a result of [presence.fetch][153] or [presence.update][162] operations.

For the latter operation, the current user receives a presence update of another user that the current user is subscribed to.

The changed information can be retrieved using the [presence.get][155]
API.

#### Parameters

*   `params` **[Object][7]** A presence object containing data.

    *   `params.userId` **[string][8]** The ID of the user.
    *   `params.status` **[string][8]** The presence status of the user.
    *   `params.activity` **[string][8]** The activity of the user.
    *   `params.note` **[string][8]** A custom note provided by the user.

### presence:selfChange

The current user's presence information has changed.

The changed information can be retrieved using the [presence.getSelf][160]
API.

### presence:subscribe

An update (as a result of subscribing to a specific user's presence) has been received.

#### Parameters

*   `params` **[Object][7]** A subscription object containing data.

    *   `params.userIds` **[Array][20]<[string][8]>** The ID(s) of the user(s) whose presence needs to be watched.

### presence:unsubscribe

An update (as a result of unsubscribing to a specific user's presence) has been received.

#### Parameters

*   `params` **[Object][7]** A subscription object containing data.

    *   `params.userIds` **[Array][20]<[string][8]>** The ID(s) of the user(s) whose presence no longer requires to be watched.

### presence:error

An error occurred with presence.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.

## proxy

The 'proxy' namespace allows for a secondary mode for making calls: proxy mode.
When proxy mode is enabled, the SDK will redirect webRTC / media operations from the current machine to a remote machine using a channel.

This is an advanced feature that enables support for Calls in particular scenarios that would otherwise not support them.

### Channel

The Channel object that the Proxy module needs to be provided.

Type: [Object][7]

#### Examples

```javascript
// The channel the application uses for communicating with a remote endpoint.
const appChannel = ...

// The channel the application will provide to the Proxy module for use.
const channel = {
   send: function (data) {
     // Any encoding / wrapping needed for a Proxy message being sent
     //    over the channel.
     appChannel.sendMessage(data)
   },
   // The Proxy module will set this function.
   receive: undefined
}
appChannel.on('message', data => {
   // Any decoding / unwrapping needed for the received message.
   channel.receive(data)
})

client.proxy.setChannel(channel)
```

#### send

Channel function that the Proxy module will use to send messages to the remote side.

##### Parameters

*   `data` **[Object][7]** Message to be sent over the channel.

#### receive

API that the Proxy module will assign a listener function for accepting received messages.
This function should receive all messages sent from the remote side of the channel.

##### Parameters

*   `data` **[Object][7]** The message received from the Channel.

### getProxyMode

Retrieves the current mode for Proxy behaviour.

When set to `true`, WebRTC operations will be proxied over a channel. When
set to `false`, WebRTC operation will occur as normal on the local machine.
See the [proxy.setProxyMode][163] API for more information.

Returns **[boolean][11]** Whether proxy mode is currently enabled.

### getInfo

Retrieves information about the proxy.

#### Examples

```javascript
const proxy = client.proxy.getInfo()

log(`Proxy Browser in use: ${proxy.browser}, mode: ${proxy.proxyMode}, channel: ${proxy.hasChannel}, initialized: ${proxy.remoteInitialized}.`)
```

Returns **[Object][7]** proxy Object containing information about the proxy.

Returns **[boolean][11]** proxy.proxyMode Current operating mode.

Returns **[boolean][11]** proxy.hasChannel Proxy has a channel associated with it.

Returns **[boolean][11]** proxy.remoteInitialized Proxy initialization state.

Returns **[Object][7]** proxy.browser Details for the browser the proxy is using.

### getProxyDetails

Retrieve information about the proxy's browser being used.
Browser information being defined indicates that the browser supports
basic webRTC scenarios.

#### Examples

```javascript
const details = client.proxy.getProxyDetails()

log(`Proxy Browser in use: ${details.browser}, version ${details.version}.`)
```

Returns **[Object][7]** Object containing `browser` and `version` information.

### setChannel

Sets the channel to be used while proxy mode is enabled.

Providing a channel is a required step for being able to use the Proxy
functionality. This should be the first step, before initializing the
remote endpoint and setting proxy mode.

On completion, this API will trigger a [proxy:change][164]
event on success. The [proxy.getInfo][165] API can be used to verify
that a channel has been set. If an error is encountered, this API will
trigger a [proxy:error][166] event. A channel
cannot be set if there is an on-going call.

#### Parameters

*   `channel` **[proxy.Channel][167]** See the `Channel` module for information.

#### Examples

```javascript
client.on('proxy:change', () => {
   const { hasChannel } = client.proxy.getInfo()
   log(`A channel ${hasChannel ? 'has': 'has not'} been set.`)
})
client.on('proxy:error', params => {
   const { code, message } = params.error
   log(`Encountered error ${code}: ${message}.`)
})

const appChannel = ...
client.proxy.setChannel(appChannel)
```

### setChannelAsync

Sets the channel to be used while proxy mode is enabled.

This API is equivalent to the [proxy.setChannel][168] API, but provides feedback via a returned promise instead
of an event. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect proxy state changes.

Providing a channel is a required step for being able to use the Proxy functionality. This should be the first
step, before initializing the remote endpoint and setting proxy mode.

The Proxy state will be changed on operation success, which will be accompanied by a
[proxy:change][164] event. The [proxy.getInfo][165] API can be used to retrieve
the state.

#### Parameters

*   `channel` **[proxy.Channel][167]** See the `Channel` module for information.

#### Examples

```javascript
const appChannel = ...
try {
  await client.proxy.setChannelAsync(appChannel)
  // Proxy channel has been set.
  // client.proxy.getInfo().hasChannel === true
} catch (error) {
  // Encountered error while setting channel.
  const { code, message } = error
  ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A Promise that resolves when the operation is successful.

### setProxyMode

Sets whether Call functionality should be proxied to the Remote SDK or not.
When set to `true`, WebRTC operations will be proxied over a channel. When
set to `false`, WebRTC operation will occur as normal on the local machine.

Setting proxy mode is a required step for being able to use the Proxy
functionality. It is recommended that this is the last step, after setting
a channel and initializing the remote endpoint. Proxy mode cannot be changed if there
is an on-going call.

On completion, this API will trigger a [proxy:change][164]
event on success. The [proxy.getProxyMode][169] or [proxy.getInfo][165]
APIs can be used to verify that proxy mode has been changed. If an error
is encountered, this API will trigger a [proxy:error][166]
event.

#### Parameters

*   `value` **[boolean][11]** Whether proxy mode should be enabled.

#### Examples

```javascript
// On success, the `proxy.setProxyMode` API will trigger a `proxy:change` event.
client.on('proxy:change', params => {
   const isProxied = client.proxy.getProxyMode()
   log(`Proxy mode set to ${isProxied}.`)
})
// On error, the `proxy.setProxyMode` API will trigger a `proxy:error` event.
client.on('proxy:error', params => {
   const { code, message } = params.error
   log(`Failed to set proxy mode due to ${code}: ${message}.`)
})

// Get the current proxy state to ensure we can set proxy mode to `true`.
const { proxyMode, hasChannel, remoteInitialized } = client.proxy.getInfo()
if (
   hasChannel === true && // A channel was previously provided.
   remoteInitialized === true && // The Remote SDK is ready.
   proxyMode === false && // Proxy mode is not already `true`.
) {
   client.proxy.setProxyMode(true)
}
```

### setProxyModeAsync

Sets whether Call functionality should be proxied to the Remote SDK or not. When set to `true`, WebRTC
operations will be proxied over a channel. When set to `false`, WebRTC operation will occur as normal
on the local machine.

This API is equivalent to the [proxy.setProxyMode][163] API, but provides feedback via a returned promise
instead of an event. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect proxy state changes.

Setting proxy mode is a required step for being able to use the Proxy functionality. It is recommended that
this is the last step, after setting a channel and initializing the remote endpoint. Proxy mode cannot be
changed if there is an on-going call.

The Proxy state will be changed on operation success, which will be accompanied by a
[proxy:change][164] event. The [proxy.getInfo][165] API can be used to retrieve
the state.

#### Parameters

*   `value` **[boolean][11]** Whether proxy mode should be enabled.

#### Examples

```javascript
// Get the current proxy state to ensure we can set proxy mode to `true`.
const { proxyMode, hasChannel, remoteInitialized } = client.proxy.getInfo()
if (
   hasChannel === true &&        // A channel was previously provided.
   remoteInitialized === true && // The Remote SDK is ready.
   proxyMode === false &&        // Proxy mode is not already `true`.
) {
   try {
     await client.proxy.setProxyMode(true)
     // Calls are now set to be proxied.
     // client.proxy.getInfo().proxyMode === true
   } catch (error) {
     // Operation failed; handle error.
     const { code, message } = error
     ...
   }
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A Promise that resolves when the operation is successful.

### initializeRemote

Sends an initialization message over the channel with webRTC configurations.

Initializing the Remote SDK is a required step before being able to use the
Proxy functionality. This step requires a channel having been set previously
(see the [API][168]). It is recommended to perform this
step before setting the proxy mode (see the [proxy.setProxyMode][163] API).

On completion, this API will trigger a [proxy:change][164]
event on success. The [proxy.getInfo][165] API can be used to verify
that the remote endpoint is initialized. If an error is encountered, this
API will trigger a [proxy:error][166] event.

This API will perform a version-check between this SDK and the Remote SDK.
Their versions must be the same, otherwise initialization will fail.

#### Parameters

*   `config` **[Object][7]** 

#### Examples

```javascript
// Get the current proxy state to ensure we can initialize the Remote SDK.
const { hasChannel, remoteInitialized } = client.proxy.getInfo()
if (
   hasChannel === true && // A channel was previously provided.
   remoteInitialized === false // The Remote SDK was not previously initializted.
) {
   client.proxy.initializeRemote()
}
```

### initializeRemoteAsync

Sends an initialization message over the channel with webRTC configurations.

This API is equivalent to the [proxy.initializeRemote][170] API, but provides feedback via a returned promise instead
of emitting events. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect proxy state changes.

Initializing the Remote SDK is a required step before being able to use the
Proxy functionality. This step requires a channel having been set previously
(see the [API][168]). It is recommended to perform this
step before setting the proxy mode (see the [proxy.setProxyMode][163] API).

This API will perform a version-check between this SDK and the Remote SDK. Their versions must be the same,
otherwise initialization will fail.

The Proxy state will be changed on operation success, which will be accompanied by a
[proxy:change][164] event. The [proxy.getInfo][165] API can be used to retrieve
the state.

#### Parameters

*   `config` **[Object][7]** 

#### Examples

```javascript
// Get the current proxy state to ensure we can initialize the Remote SDK.
const { hasChannel, remoteInitialized } = client.proxy.getInfo()
if (
   hasChannel === true &&      // A channel was previously provided.
   remoteInitialized === false // The Remote SDK was not previously initializted.
) {
   try {
     await client.proxy.initializeRemoteAsync()
     // Remote SDK has been setup.
     // client.proxy.getInfo().remoteInitialized === true
   } catch (params) {
     // Operation failed; handle error.
     const { code, message } = error
     ...
   }
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A Promise that resolves when the operation is successful.

### proxy:change

A Proxy API has completed and changed the proxy state.

The [proxy.getInfo][165] API can be used to retrieve the current proxy state.

### proxy:error

A Proxy API has resulted in an error.

The [proxy.getInfo][165] API can be used to retrieve the current proxy state.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **BasicError** An error with `code` and `message` information.

## request

The 'request' namespace (within the 'api' type) is used to make network requests to the server.

### fetch

Send a request to the underlying REST service with the appropriate configuration and authentication.
This is a wrapper on top of the browser's [fetch API][171]
and behaves very similarly but using SDK configuration for the base URL and authentication as well
as SDK logging.

#### Parameters

*   `resource` **[string][8]** The full path of the resource to fetch from the underlying service. This should include any REST version
    or user information. This path will be appended to the base URL according to SDK configuration.
*   `init` **RequestInit** An object containing any custom settings that you want to apply to the request. See [fetch API][171]
    for a full description and defaults.

#### Examples

```javascript
// Send a REST request to the server
// Create a request options object following [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/fetch)
const requestOptions = {
  method: 'POST',
  body: JSON.stringify({
    test: 123
  })
}

// Note that you will need to subscribe for the `custom` service in order to
// receive notifications from the `externalnotification` service.
const response = await client.request.fetch('/rest/version/1/user/xyz@test.com/externalnotification', requestOptions)
```

Returns **[Promise][49]<[Response][172]>** A promise for a [Response][173] object.

## sdpHandlers

A set of [SdpHandlerFunction][92]s for manipulating SDP information.
These handlers are used to customize low-level call behaviour for very specific
environments and/or scenarios.

Note that SDP handlers are exposed on the entry point of the SDK. They can be added during
initialization of the SDK using the [config.call.sdpHandlers][106] configuration
parameter. They can also be set after the SDK's creation by using the
[call.setSdpHandlers][174] function.

### Examples

```javascript
import { create, sdpHandlers } from '@rbbn/webrtc-js-sdk';
const codecRemover = sdpHandlers.createCodecRemover(['VP8', 'VP9'])
const client = create({
  call: {
    sdpHandlers: [ codecRemover, <Your-SDP-Handler-Function>, ...]
  }
})
```

```javascript
// Through the Call API post-instantiation
client.call.setSdpHandlers([ codecRemover, <Your-SDP-Handler-Function>, ...])
```

### CodecSelector

An object that represents a selector to match codecs of an RTP map in SDP.

Type: [Object][7]

#### Properties

*   `name` **[string][8]** The name of the codec.
*   `fmtpParams` **[Array][20]<[string][8]>** An array of strings to match against the "a=fmtp" format parameters for the corresponding codec.
    All of the elements in the array must be contained in the "a=fmtp" attribute in order to be a match.

### createCodecRemover

This function creates an SDP handler that will remove codecs matching the selectors specified for SDP offers and answers.

In some scenarios it's necessary to remove certain codecs being offered by the SDK to remote parties. For example, some legacy call services limit the SDP
length (usually to 4KB) and will reject calls that have SDP size above this amount.

While creating an SDP handler would allow a user to perform this type of manipulation, it is a non-trivial task that requires in-depth knowledge of WebRTC SDP.

To facilitate this common task, the createCodecRemover function creates a codec removal handler that can be used for this purpose. Applications can use this codec
removal handler in combination with the [call.getAvailableCodecs][115] function in order to build logic to determine the best codecs to use
for their application.

#### Parameters

*   `codecs` **([Array][20]\<CodecSelector> | [Array][20]<[string][8]>)** A list of codec selectors to remove from the SDP. If passing a list of strings, they will be converted into
    codec selectors that correspond to those names without any extra FMTP parameters.

#### Examples

```javascript
import { create, sdpHandlers } from '@rbbn/webrtc-js-sdk';

const codecRemover = sdpHandlers.createCodecRemover([
  // Remove all VP8 and VP9 codecs.
  'VP8',
  'VP9',

  // Remove all H264 codecs with the specified FMTP parameters.
  {
    name: 'H264',
    fmtpParams: ['packetization-mode=0']
  }
])

const client = create({
  call: {
    sdpHandlers: [codecRemover]
  }
})
```

Returns **[call.SdpHandlerFunction][21]** The resulting SDP handler that will remove the codec.

## services

The 'services' namespace allows an application to manage how they wish the SDK to
receive communications from the platform. An application can subscribe to
services in order to receive updates about that service for the current
user. A feature generally requires a subscription for its service to be
fully functional.

The services an application can subscribe to are based on the features
included in the SDK. The list of available services can be retrieved
using the [services.getSubscriptions][175] API. These values can be used
with the [services.subscribe][176] API.

The channel used for subscriptions is the method for receiving the service
updates. The recommended channel is `websocket`, where the SDK is able to
handle receiving the updates internally. Alternate channel methods, if a
websocket cannot be used, will be available in the future.

### subscribe

Subscribes to platform notifications for an SDK service.

The SDK will emit a [subscription:change][177] event for each change
in subscription state. This includes when this API is initially called, to indicate a pending subscription,
then again after the operation succeeds. Upon getting such event, existing subscriptions can be retrieved
using the [services.getSubscriptions][175] API.

The SDK will emit a [subscription:error][178] event if the operation
fails.

If the [services.unsubscribe][179] API is called while a subscription is in progress, this operation will
be cancelled and the SDK will emit a [subscription:error][178] event
with an error indicating the cancellation.

The `clientCorrelator` option should be provided to support a user subscribing from multiple clients
at the same time. This value is used by the platform to correlate subscriptions to specific clients.
If a second subscription is made with the same value (including no value), the platform will override
the first subscription. The client with the first subscription will receive a
[subscription:change][177] event with an explicit reason in this
scenario.

The SDK currently only supports the `websocket` channel as a subscription `type` option.

#### Parameters

*   `services` **[Array][20]<([string][8] | [services.ServiceDescriptor][180])>** A list of service configurations.
*   `options` **[Object][7]?** The options object for non-credential options.

    *   `options.type` **[string][8]** The method of how to receive service updates. (optional, default `'websocket'`)
    *   `options.clientCorrelator` **[string][8]?** Unique ID for the client. This is used by the platform to identify
        an instance of the application used by the specific device.

#### Examples

```javascript
// Subscribe for call and messaging services.
client.services.subscribe(['call', 'IM'], { clientCorrelator: 'abc123' })
```

Returns **[undefined][27]** 

### subscribeAsync

Creates a subscription on the WebRTC Gateway to receive notifications for specified services.

This API is equivalent to the [services.subscribe][176] API, but provides feedback via a returned promise instead
of emitting events. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect subscription changes.

As a prerequisite, user credentials must be available for REST authorization with the WebRTC Gateway. The credentials
should be provided with the [auth.setCredentials][181] API.

Returns a promise that resolves when the subscription is successful. When resolved, subscriptions can be retrieved
using the [services.getSubscriptions][175] API. If the subscription fails, the promise will reject with a
[BasicError][182] describing the failure.

If the [services.unsubscribe][179] API is called while a subscription is in progress, this operation will
be cancelled and will reject with an error indicating the cancellation.

The `clientCorrelator` option should be provided to support a user subscribing from multiple clients
at the same time. This value is used by the platform to correlate subscriptions to specific clients.
If a second subscription is made with the same value (including no value), the platform will override
the first subscription. The client with the first subscription will receive a
[subscription:change][177] event with an explicit reason in this
scenario.

The subscription will be refreshed automatically based on the [config.subscription][183] configuration. When this
resubscribe happens, a [subscription:resub][184] event will be emitted. If the
subscription cannot be refreshed before it expires, a [subscription:change][177]
event will be emitted with an explicit `reason` parameter.

#### Parameters

*   `services` **[Array][20]<([string][8] | [services.ServiceDescriptor][180])>** A list of service configurations.
*   `options` **[Object][7]?** The options object for non-credential options.

    *   `options.type` **[string][8]** The method of how to receive service updates. (optional, default `'websocket'`)
    *   `options.clientCorrelator` **[string][8]?** Unique ID for the client. This is used by the platform to identify
        an instance of the application used by the specific device.

#### Examples

```javascript
// Subscribe for call and messaging services.
try {
    await client.services.subscribeAsync(['call', 'IM'], { clientCorrelator: 'abc123' })
} catch (error) {
    // Subscription failed; handle error.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the subscription is successful.

### unsubscribe

Cancels existing subscriptions for platform notifications.

When calling this API, SDK emits a [subscription:change][177] event, each
time there is a change in subscriptions.

Upon getting such event, existing subscriptions can be retrieved using the
[services.getSubscriptions][175] API. The `subscribed` values are the
services that can be unsubscribed from.

#### Parameters

*   `services` **[Array][20]<[string][8]>** A list of subscribed service names.
*   `type` **[string][8]** The method of how the service updates
    are being received. (optional, default `'websocket'`)

#### Examples

```javascript
// Unsubscribe from chat and SMS services.
const services = [ 'chat', 'smsinbound' ]

client.services.unsubscribe(services)
```

### unsubscribeAsync

Cancels the existing subscription on the WebRTC Gateway for receiving notifications.

This API is equivalent to the [services.unsubscribe][179] API, but provides feedback via a returned promise instead
of emitting events. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect subscription changes.

As a prerequisite, a subscription must exist with some or all of the specified `services`. The [services.getSubscriptions][175] API
can be used to retrieve the existing subscription, if any. If a subset of the existing services are specified, then the
subscription will be updated to remove only those services. If all of the existing services are specified, then the subscription
will be removed entirely.

Returns a promise that resolves when the operation is successful. If the operation fails, the promise will reject with a
[BasicError][182] describing the failure.

#### Parameters

*   `services` **[Array][20]<[string][8]>** A list of subscribed service names.
*   `type` **[string][8]** The method of how the service updates are being received. (optional, default `'websocket'`)

#### Examples

```javascript
// Unsubscribe from call and messaging services.
try {
  await client.services.unsubscribeAsync(['call', 'IM'])
  // Operation was successful.
} catch (error) {
  // Operation failed.
  const { code, message } = error
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the unsubscription is complete.

### getSubscriptions

Retrieves information about currently subscribed services and available services.
The data returned by this API is a snapshot of the SDK's current local subscription state.
The data does indicate whether there was an ongoing subscription at the time this API was called.
If a subscription is in fact in progress, the user should not take decisions based on this snapshot, as the
subscription is not yet complete.

To be notified when any subscription(s) did change/complete, listen for
[subscription:change][177] events.

The `available` values are the SDK's services that an application can
subscribe to receive notifications about. A feature generally
requires a subscription to its service in order to be fully functional.

The `subscribed` values are the SDK's services that the application has
an active subscription for. Services are subscribed to using the
[services.subscribe][176] API.

#### Examples

```javascript
// Get the lists of services.
const services = client.services.getSubscriptions()

// Ensure that there were no pending subscriptions at the time
// we called getSubscriptions API.
if (!services.isPending) {
  // Figure out which available services don't have a subscription.
  const notSubscribed = services.available.filter(service => {
    return !services.subscribed.includes(service)
  })

  // Subscribe for all not-yet-subscribed services.
  client.services.subscribe(notSubscribed)
}
```

Returns **[Object][7]** Lists of subscribed and available services.

### changeReasons

Constants used to describe reasons for subscription change.

These values are used in the [subscription:change][177] event
for the `reason` parameter to indicate why the subscription has changed.

#### Properties

*   `GONE` **[string][8]** When the server terminated the subscription.
*   `LOST_CONNECTION` **[string][8]** When network connectivity was lost.
*   `WS_OVERRIDDEN` **[string][8]** When the webSocket was overridden by the server.
*   `PENDING` **[string][8]** When the subscription is in progress.
*   `SUBSCRIBED` **[string][8]** When the user is subscribed to services.
*   `UNSUBSCRIBED` **[string][8]** When the user is unsubscribed from services.

### ServiceDescriptor

The ServiceDescriptor type defines the format for specifying how to subscribe for a certain service.
This is the service configuration object that needs to be passed (as part of an array of configuration objects)
when calling the [services.subscribe][176] function.
Only some plugins (`call`, `messaging` and `presence`) support such configuration object that needs to be passed
to the subscribe function.

Type: [Object][7]

#### Properties

*   `service` **[string][8]** The name of the available service user wants to subscribe to.
    The available service names are `chat`, `presence`, `call` and `smsinbound`.
*   `params` **[Object][7]?** An object containing any additional parameters required for subscribing to that service.
    This is an optional property as not all service subscriptions require it.

#### Examples

```javascript
// Subscribe to chat, presence & call services on a WebSocket channel.
client.services.subscribe([
   {service: 'chat'},
   {service: 'presence'},
   {service: 'call'},
], 'websocket')
```

### subscription:change

Subscription information has changed.

The updated subscription information can be retrieved using the
[services.getSubscriptions][175] API.

The `reason` parameter indicates why the subscription has changed.
The value for this parameter will be one of the [services.changeReasons][185] constants.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.reason` **[string][8]?** The reason for the change.

### subscription:error

An error occurred during a subscription operation.

The subscription information can be retrieved using the
[services.getSubscriptions][175] API.

Below are some common errors related to service subscriptions.

*   `authentication:1`  - "Authorization failed with server. Please check credentials. Status code: 4\`" - Invalid credentials.
*   `authentication:3`  - "No subscription found for "X", can't unsubscribe" - The requested service is not currently subscribed.
*   `authentication:3`  - "No subscription found, can't unsubscribe." - There are no active subscriptions.
*   `authentication:4`  - "Failed to subscribe user. Status Code 19" - Too many active sessions with the requested user.
*   `authentication:4`  - "Failed to subscribe user. Status Code 37" - Invalid service string.
*   `authentication:4`  - "Failed to subscribe user. Status Code 38" - Invalid characters in client correlator.
*   `authentication:4`  - "Failed to subscribe user. Status Code 39" - Session does not exist anymore.
*   `authentication:12` - "No services found in configuration." - No services found in SDK configuration.

The following errors indicate an issue with the user account or temporary backend issue. They may require help from support or a delay before being retried.

*   `authentication:4`  - "Failed to subscribe user. Status Code 9"
*   `authentication:4`  - "Failed to subscribe user. Status Code 17"
*   `authentication:4`  - "Failed to subscribe user. Status Code 26"
*   `authentication:4`  - "Failed to subscribe user. Status Code 27"
*   `authentication:4`  - "Failed to subscribe user. Status Code 54"
*   `authentication:4`  - "Failed to subscribe user. Status Code 62"
*   `authentication:4`  - "Failed to subscribe user. Status Code 63"
*   `authentication:13` - "Failed to subscribe user. Status Code 53"

For a more detailed look into subscription errors and handling recommendations,
please refer to the "Handling Subscription Errors" tutorial.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[Object][7]** A Basic error object, representing the error that occurred.

### subscription:resub

An attempt to extend the current user's subscription was made.

In a failure scenario, the current user is still connected, and further
resubscription attempts will be made, but may become disconnected if the
session expires.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.attemptNum` **[number][13]** The attempt number of this resubscription.
    *   `params.isFailure` **[boolean][11]** Whether the resubscription failed or not.
    *   `params.error` **[api.BasicError][29]?** The Basic error object.

## sip

The SIP Events feature allows an application to communicate with a SIP network integrated
with their WebRTC Gateway instance. The SIP network may generate custom events intended
for an application, which can be handled with the SDK's `sip` namespace.

Usage of SIP Events is dependent on your WebRTC Gateway instance. The types of SIP Events can
be different based on configurations and components, often being part of a custom
solution. As such, the SIP Events feature is presented in a generic manner to be
flexible for any possible events.

An example of a common SIP event is "SIP presence". When a user is connected to a SIP phone,
the network may generate "phone presence" events when the user starts and ends a call
(eg. 'On Call', 'Available'). Applications can subscribe to receive these events for
specific users.

A SIP event may either be solicited or unsolicited. Solicited events, such as the "presence"
example above, requires the application to subscribe for the event. See the
[sip.subscribe API][186] for more information about solicited events.
Unsolicited events have no prerequisites for being received.

### getDetails

Retrieve information about a SIP event subscription.

The SDK will track which users are included as part of the subscription and
previous notifications received. Each subscription will include a unique ID.

#### Parameters

*   `eventType` **[string][8]?** The name of a SIP event. If not provided, will retrieve
    information for all SIP subscriptions.

#### Examples

```javascript
// Retrieve information about a single SIP subscription.
const { subscribedUsers, notifications } = client.sip.getDetails('event:presence')

// Retrieve information about all current SIP subscriptions.
const subscriptions = client.sip.getDetails()
const { subscribedUsers, notifications } = subscriptions['event:presence']
```

Returns **[Object][7]** SIP subscription information. If `eventType` was not provided, will
return an object namespaced by event types.

### subscribe

Creates a subscription for a SIP event.

A subscription is required to receive SIP notifications for solicited events. Before
creating a SIP subscription, the service for the event type must have been
provisioned as part of the user subscription using the [services.subscribe][176]
API.

Only one SIP subscription per event type can exist at a time. A subscription can
watch for events from multiple users at once. Users can be added to or removed
from a subscription using the [sip.update][187] API at any time.

The SDK will emit a [sip:subscriptionChange][188]
event when the operations completes. The [sip.getDetails][189] API can be used
to retrieve the current information about a subscription.

The SDK will emit a [sip:eventsChange][190] event when
a SIP event is received.

#### Parameters

*   `eventType` **[string][8]** The name of the SIP event.
*   `subscribeUserList` **[Array][20]<[string][8]>** The list of users to receive events about.
*   `clientCorrelator` **[string][8]** Unique identifier for a client device.
*   `customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.

#### Examples

```javascript
// Provision the service for the specific SIP event during user subscription.
//   This is required before a SIP subscription for the event can be created.
const services = ['call', 'event:presence', ...]
client.services.subscribe(services)

// Subscribe to receive SIP presence events from two users.
client.sip.subscribe('event:presence', ['userOne@example.com', 'userTwo@example.com'], 'clientId123')

// Subscribe for SIP events with a custom parameter.
const customParameters = [{
   name: 'X-nt-GUID',
   value: 'GUID123abc'
}]
client.sip.subscribe('event:presence', subscribeUserList, 'clientId123', customParameters)
```

### subscribeAsync

Creates a subscription for a SIP event.

This API is equivalent to the [sip.subscribe][186] API, but provides feedback via a returned promise instead
of an event. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect SIP subscription changes.

A subscription is required to receive SIP notifications for solicited events. Before
creating a SIP subscription, the service for the event type must have been
provisioned as part of the user subscription using the [services.subscribe][176]
API.

Only one SIP subscription per event type can exist at a time. A subscription can
watch for events from multiple users at once. Users can be added to or removed
from a subscription using the [sip.update][187] API at any time.

The SIP subscriptions state will be changed on operation success, which will be accompanied by a
[sip:subscriptionChange][188] event. The [sip.getDetails][189] API can be
used to retrieve the state.

The SDK will emit a [sip:eventsChange][190] event when a SIP event is received.

#### Parameters

*   `eventType` **[string][8]** The name of the SIP event.
*   `subscribeUserList` **[Array][20]<[string][8]>** The list of users to receive events about.
*   `clientCorrelator` **[string][8]** Unique identifier for a client device.
*   `customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.

#### Examples

```javascript
// Provision the service for the specific SIP event during user subscription.
//   This is required before a SIP subscription for the event can be created.
await client.services.subscribeAsync(['call', 'event:presence', ...])

// Subscribe to receive SIP presence events from two users.
try {
    await client.sip.subscribeAsync('event:presence', ['userOne@example.com', 'userTwo@example.com'], 'clientId123')
} catch (error) {
    // Operation failed; handle error.
    const { code, message } = error
    ...
}

// Subscribe for SIP events with a custom parameter.
try {
    const customParameters = [{
      name: 'X-nt-GUID',
      value: 'GUID123abc'
    }]
    await client.sip.subscribeAsync('event:presence', subscribeUserList, 'clientId123', customParameters)
} catch (error) {
    // Operation failed; handle error.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### unsubscribe

Deletes an existing SIP event subscription.

The SDK will emit a [sip:subscriptionChange][188]
event when the operations completes.

Subscription details will no longer be available using the [sip.getDetails][189]
API after it has been unsubscribed from.

#### Parameters

*   `eventType` **[string][8]** The name of the SIP event.

#### Examples

```javascript
// Delete a SIP subscription.
client.sip.unsubscribe('event:presence')
```

### unsubscribeAsync

Deletes an existing SIP event subscription.

This API is equivalent to the [sip.unsubscribe][191] API, but provides feedback via a returned promise instead
of an event. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect SIP subscription changes.

The SIP subscriptions state will be changed on operation success, which will be accompanied by a
[sip:subscriptionChange][188] event. The subscription details will no longer
be available using the [sip.getDetails][189] API after it has been unsubscribed from.

#### Parameters

*   `eventType` **[string][8]** The name of the SIP event.

#### Examples

```javascript
try {
    await client.sip.unsubscribeAsync('event:presence')
    // SIP subscription deleted.
    // client.sip.getDetails('event:presence') === undefined
} catch (error) {
    // Operation failed; handle error.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### update

Updates an existing SIP event subscription.

Allows for adding or removing users from the subscription, and for changing the
custom parameters of the subscription.

The SDK will emit a [sip:subscriptionChange][188]
event when the operations completes. The [sip.getDetails][189] API can be used
to retrieve the current information about a subscription.

#### Parameters

*   `eventType` **[string][8]** The name of the SIP event.
*   `userLists` **[Object][7]** 

    *   `userLists.subscribeUserList` **[Array][20]<[string][8]>** List of users to add to the subscription.
    *   `userLists.unsubscribeUserList` **[Array][20]<[string][8]>** List of users to remove from the subscription. If all users are removed, the event subscription will be deleted.
*   `customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.

#### Examples

```javascript
// Add a user to an existing subscription.
const userLists = {
   subscribedUserList: ['userThree@example.com']
}
client.sip.update('event:presence', userLists)

// Simultaneously add and remove users from the subscription.
const userLists = {
   subscribedUserList: ['userThree@example.com'],
   unsubscribeUserList: ['userOne@example.com']
}
client.sip.update('event:presence', userLists)
```

### updateAsync

Updates an existing SIP event subscription.

This API is equivalent to the [sip.update][187] API, but provides feedback via a returned promise instead
of emitting events. This API will not emit events specifically about the operation's completion, but may
emit an event to reflect SIP subscription changes.

As a prerequisite, a SIP subscription must exist for the `eventType` service. The [sip.subscribe][186] API
can be used to create a SIP subscription, and the [sip.getDetails][189] API can be used to
retrieve information about existing subscriptions.

The SIP subscriptions state will be changed on operation success, which will be accompanied by a
[sip:subscriptionChange][188] event. The [sip.getDetails][189] API can be
used to retrieve the state.

#### Parameters

*   `eventType` **[string][8]** The name of the SIP event.
*   `userLists` **[Object][7]** 

    *   `userLists.subscribeUserList` **[Array][20]<[string][8]>** List of users to add to the subscription.
    *   `userLists.unsubscribeUserList` **[Array][20]<[string][8]>** List of users to remove from the subscription. If all users are removed, the event subscription will be deleted.
*   `customParameters` **[Array][20]<[call.CustomParameter][44]>?** Custom SIP header parameters for the SIP backend.

#### Examples

```javascript
// Add a user to an existing subscription.
const userLists = {
   subscribedUserList: ['userThree@example.com']
}
try {
    await client.sip.updateAsync('event:presence', userLists)
} catch (error) {
    // Operation failed; handle error.
    const { code, message } = error
    ...
}

// Simultaneously add and remove users from the subscription.
const userLists = {
   subscribedUserList: ['userThree@example.com'],
   unsubscribeUserList: ['userOne@example.com']
}

try {
    await client.sip.updateAsync('event:presence', userLists)
} catch (error) {
    // Operation failed; handle error.
    const { code, message } = error
    ...
}
```

*   Throws **BasicError** Rejects with a BasicError if the operation fails.

Returns **[Promise][49]<[undefined][27]>** A promise that resolves when the operation is successful.

### sip:subscriptionChange

A change has occurred to a SIP subscription.

This event can be emitted when a new SIP subscription is created ([sip.subscribe][186]
API), an existing subscription is updated ([sip.update][187] API), or has been
deleted ([sip.unsubscribe][191] API). The `change` parameter on the event indicates
which scenario caused the event.

When users are added or removed from a subscription through a new subscription or an update,
the `subscribedUsers` and `unsubscribedUsers` parameters will indicate the users added
and removed, respectively.

The [sip.getDetails][189] API can be used to retrieve the current information about
a subscription.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.eventType` **[string][8]** The name of the SIP event.
    *   `params.change` **[string][8]** The change operation that triggered the event.
    *   `params.subscribedUsers` **[Array][20]<[string][8]>?** List of users added to the subscription
        as part of the change.
    *   `params.unsubscribedUsers` **[Array][20]<[string][8]>?** List of users removed from the
        subscription as part of the change.

### sip:error

An error has occurred during a SIP event operation.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.
    *   `params.eventType` **[string][8]** The name of the SIP event.

#### Examples

```javascript
// Listen for the event being emitted.
client.on('sip:error', (params) => {
   // Handle the error based on the information.
   const { code, message } = params.error
   ...
})
```

### sip:eventsChange

A SIP event notification has been received.

The `event` parameter is the full notification received from the network. The format
of the notification is dependant on its event type. The SDK does not do any
pre-processing of this data.

#### Parameters

*   `params` **[Object][7]** Information about the notification.

    *   `params.eventType` **[string][8]** The name of the SIP event.
    *   `params.eventId` **[string][8]** A unique ID for the event notification.
    *   `params.event` **[Object][7]** The full event object.
    *   `params.links` **[Object][7]** 

        *   `params.links.callId` **[string][8]?** The ID of the call this SIP event links to.

#### Examples

```javascript
// Listen for the event being emitted.
client.on('sip:eventsChange', (params) => {
   // Gather the SIP info specific to the event.
   const sipInfo = params.event.genericNotificationParams

   // Handle the data based on the event type.
   if (params.eventType === 'event:presence') {
       const { data, from } = sipInfo
       ...
   }
})
```

## user

The 'user' namespace allows access to user information for users within the same domain.

### fetch

Fetches information about a User.

The SDK will emit a [users:change][192]
event after the operation completes. The User's information will then
be available.

Information about an available User can be retrieved using the
[user.get][193] API.

#### Parameters

*   `userId` **[string][8]** The User ID of the user.

### get

Retrieves information about a User, if available.

See the [user.fetch][194] and [user.search][195] APIs for details about
making Users' information available.

#### Parameters

*   `userId` **[user.UserID][98]** The User ID of the user.

Returns **[user.User][196]** The User object for the specified user.

### getAll

Retrieves information about all available Users.

See the [user.fetch][194] and [user.search][195] APIs for details about
making Users' information available.

Returns **[Array][20]<[user.User][196]>** An array of all the User objects.

### search

Searches the domain's directory for Users.

Directory searching only supports one filter. If multiple filters are provided, only one of the filters will be used for the search.
A search with no filters provided will return all users.

The SDK will emit a [directory:change][197]
event after the operation completes. The search results will be
provided as part of the event, and will also be available using the
[user.get][193] and [user.getAll][198] APIs.

#### Parameters

*   `filters` **[Object][7]** The filter options for the search.

    *   `filters.userId` **[user.UserID][98]?** Matches the User ID of the user.
    *   `filters.name` **[string][8]?** Matches the firstName or lastName.
    *   `filters.firstName` **[string][8]?** Matches the firstName.
    *   `filters.lastName` **[string][8]?** Matches the lastName.
    *   `filters.userName` **[string][8]?** Matches the userName.
    *   `filters.phoneNumber` **[string][8]?** Matches the phoneNumber.

### User

The User data object.

Type: [Object][7]

#### Properties

*   `userId` **[user.UserID][98]** The User ID of the user.
*   `emailAddress` **[string][8]** The email address of the user.
*   `firstName` **[string][8]** The first name of the user.
*   `lastName` **[string][8]** The last name of the user.
*   `photoURL` **[string][8]** The URL to get the photo of the user.
*   `buddy` **[string][8]** Whether the user is a "buddy". Values can be "true" or "false".

### UserID

The ID of a User (e.g. [joe@domain.com][97])

Type: [string][8]

### directory:change

The directory has changed.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.results` **[Array][20]<[user.User][196]>** The Users' information returned by the
        operation.

### directory:error

An error occurred while performing a directory operation.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[Object][7]** The Basic error object.

### users:change

A change has occurred in the users list

#### Parameters

*   `params` **[Object][7]** 

    *   `params.results` **[Array][20]<[user.User][196]>** The Users' information returned by the
        operation.

### users:error

An error occurred while retrieving the user information

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[Object][7]** params.error The Basic error object.

## voicemail

The 'voicemail' namespace is used to retrieve and view
voicemail indicators.

Voicemail functions are all part of this namespace.

### fetch

Attempts to retrieve voicemail information from the server.

A [voicemail:change][199] event is
emitted upon completion.

### get

Returns voicemail data from the store.

### voicemail:change

A voicemail event has been received.

#### Parameters

*   `params` **[Object][7]** An object containing voicemail info.

    *   `params.lastUpdated` **[number][13]** Timestamp of the last time voicemail data was checked.
    *   `params.newMessagesWaiting` **[boolean][11]** Whether there are new messages.
    *   `params.totalVoice` **[number][13]** The total number of voicemail messages.
    *   `params.unheardVoice` **[number][13]** Number of unheard voicemail messages.
    *   `params.voice` **[Object][7]** Object containing individual counts of new, old, urgent voicemails.
    *   `params.fax` **[Object][7]** Object containing individual counts of new, old, urgent faxes.
    *   `params.multimedia` **[Object][7]** Object containing individual counts of new, old, urgent multimedia messages.

### voicemail:error

An error has occurred while attempting to retrieve voicemail data.

#### Parameters

*   `params` **[Object][7]** 

    *   `params.error` **[api.BasicError][29]** The Basic error object.

[1]: #config

[2]: #api

[3]: #create

[4]: #loggerloghandler

[5]: #loggerlogentry

[6]: #logger

[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[9]: #loggerlevels

[10]: #loggerloghandler

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[12]: https://en.wikipedia.org/wiki/Keepalive

[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[14]: #callrtcpeerconnectionconfig

[15]: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#parameters

[16]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[17]: #callicecollectioninfo

[18]: #callicecollectioncheckresult

[19]: #callicecollectioncheckfunction

[20]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[21]: #callsdphandlerfunction

[22]: #apigetconfig

[23]: #config

[24]: #apieventauthchange

[25]: #apieventautherror

[26]: api.getUserInfo

[27]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined

[28]: setCredentials

[29]: #apibasicerror

[30]: #apisetcredentials

[31]: #callsip_uri

[32]: #calltel_uri

[33]: #callgetbyid

[34]: #calleventcalloperation

[35]: #calleventcallstart

[36]: #calleventcallreceive

[37]: #callsip_uri

[38]: #calltel_uri

[39]: #callaudiooptions

[40]: #callvideooptions

[41]: #callscreenoptions

[42]: #mediadetachedmedia

[43]: #callbandwidthcontrols

[44]: #callcustomparameter

[45]: #calldscpcontrols

[46]: #callmake

[47]: #calleventcallstatechange

[48]: #callcallobject

[49]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise

[50]: #callcallobject

[51]: call.event:call:newTrack

[52]: #callanswer

[53]: #callreject

[54]: #callignore

[55]: #callforward

[56]: call.event:call:trackEnded

[57]: #callend

[58]: #callunhold

[59]: #callhold

[60]: #calleventcalltracksremoved

[61]: #calleventcalltracksadded

[62]: #calladdmedia

[63]: #callremovemedia

[64]: #callstartvideo

[65]: #callstopvideo

[66]: #calleventcalltrackreplaced

[67]: #callreplacetrack

[68]: #callmediaconnectionstates

[69]: #calleventcallmediaconnectionchange

[70]: #calleventcallmediarestart

[71]: #callrestartmedia

[72]: #mediamutetracks

[73]: #mediaremovetracks

[74]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement/Audio

[75]: #mediaeventmediatrackended

[76]: #calldirecttransfer

[77]: #callconsultativetransfer

[78]: #calljoin

[79]: #callsendringingfeedback

[80]: #callcustomparameter

[81]: #callgetall

[82]: #callsendcustomparameters

[83]: #callsetcustomparameters

[84]: #callsenddtmf

[85]: https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport

[86]: https://developer.mozilla.org/en-US/docs/Web/API/RTCStats

[87]: https://developer.mozilla.org/docs/Web/API/RTCStatsReport

[88]: #calleventcallavailablecodecs

[89]: https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-getcapabilities

[90]: #callreportevents

[91]: #callmetrics

[92]: #callsdphandlerfunction

[93]: #callstates

[94]: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState

[95]: #callgetreport

[96]: #callrtcpeerconnectionconfig

[97]: mailto:joe@domain.com

[98]: #useruserid

[99]: #callmediaoffered

[100]: #callmediaconstraint

[101]: https://www.w3.org/TR/webrtc-priority/#rtc-priority-type

[102]: https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer#properties

[103]: https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer/urls

[104]: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceGatheringState

[105]: #callicecollectioninfo

[106]: #configconfigcall

[107]: #callicecollectioncheckresult

[108]: #callsdphandlerinfo

[109]: #calldeviceinfo

[110]: #calleventcallcustomparameters

[111]: #mediagettrackbyid

[112]: #callgetstats

[113]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map

[114]: #calltrackobject

[115]: #callgetavailablecodecs

[116]: #callhistoryget

[117]: callHistory.setCache

[118]: callHistory.getCache

[119]: #connectionwsconnectionobject

[120]: #connectioneventwschange

[121]: #connectiongetsocketstate

[122]: #conversationconversation

[123]: #conversationconversationcreatemessage

[124]: #conversationmessage

[125]: conversation.Message.addPart

[126]: #conversationmessagesend

[127]: #conversationconversationgetmessages

[128]: #conversationconversationgetmessage

[129]: conversation.chatTypes

[130]: #configconfiglogs

[131]: #call

[132]: #mediagetdevices

[133]: #mediaeventdeviceschange

[134]: #callmediaobject

[135]: #mediainitializedevices

[136]: #mediaeventdeviceserror

[137]: #mediainitializedevicesasync

[138]: media.renderTrack

[139]: #mediaeventmediamuted

[140]: #mediaeventmediaunmuted

[141]: #mediaunmutetracks

[142]: #callmediaobject

[143]: #calltrackobject

[144]: #media

[145]: #mediacreatelocalmedia

[146]: #mediagetlocalmedia

[147]: #mediadisposelocalmedia

[148]: #callmediaconstraint

[149]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error

[150]: #mediaeventmediasourceunmuted

[151]: #mediaeventmediasourcemuted

[152]: #notificationprocess

[153]: #presencefetch

[154]: #presencesubscribe

[155]: #presenceget

[156]: #presencegetall

[157]: #presencestatuses

[158]: #presenceactivities

[159]: #presenceeventpresenceselfchange

[160]: #presencegetself

[161]: #presenceeventpresencechange

[162]: #presenceupdate

[163]: #proxysetproxymode

[164]: #proxyeventproxychange

[165]: #proxygetinfo

[166]: #proxyeventproxyerror

[167]: #proxychannel

[168]: #proxysetchannel

[169]: #proxygetproxymode

[170]: #proxyinitializeremote

[171]: https://developer.mozilla.org/en-US/docs/Web/API/fetch

[172]: https://developer.mozilla.org/docs/Web/Guide/HTML/HTML5

[173]: https://developer.mozilla.org/en-US/docs/Web/API/Response

[174]: #callsetsdphandlers

[175]: #servicesgetsubscriptions

[176]: #servicessubscribe

[177]: #serviceseventsubscriptionchange

[178]: #serviceseventsubscriptionerror

[179]: #servicesunsubscribe

[180]: #servicesservicedescriptor

[181]: auth.setCredentials

[182]: BasicError

[183]: config.subscription

[184]: #serviceseventsubscriptionresub

[185]: #serviceschangereasons

[186]: #sipsubscribe

[187]: #sipupdate

[188]: #sipeventsipsubscriptionchange

[189]: #sipgetdetails

[190]: #sipeventsipeventschange

[191]: #sipunsubscribe

[192]: #usereventuserschange

[193]: #userget

[194]: #userfetch

[195]: #usersearch

[196]: #useruser

[197]: #usereventdirectorychange

[198]: #usergetall

[199]: #voicemaileventvoicemailchange
