<!-- 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 'kandy'
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.authentication

Configuration options for the CallMe Authentication feature.

#### Parameters

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

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

        *   `authentication.subscription.protocol` **[string][8]** Protocol to be used for subscription requests. (optional, default `'https'`)
        *   `authentication.subscription.server` **[string][8]** Server to be used for subscription requests.
        *   `authentication.subscription.port` **[Number][12]** Port to be used for subscription requests. (optional, default `443`)
        *   `authentication.subscription.service` **[Array][13]?** Services to subscribe to for notifications.
    *   `authentication.websocket` **[Object][7]** 

        *   `authentication.websocket.protocol` **[string][8]** Protocol to be used for websocket notifications. (optional, default `'wss'`)
        *   `authentication.websocket.server` **[string][8]** Server to be used for websocket notifications.
        *   `authentication.websocket.port` **[Number][12]** 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][12]** 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][12]** 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 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][13]<[call.SdpHandlerFunction][20]>?** List of SDP handler functions to modify SDP. Advanced usage.
    *   `call.removeH264Codecs` **[boolean][11]** Whether to remove "H264" codec lines from incoming and outgoing SDP messages. (optional, default `true`)
    *   `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.mediaBrokerOnly` **[boolean][11]** Whether all Calls will be anchored on the MediaBroker instead of being peer-to-peer. Set to true if the backend is configured for broker only mode. (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][12]** Time interval, in milliseconds between call audits. (optional, default `25000`)
    *   `call.mediaConnectionRetryDelay` **[number][12]** 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`)

### 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

#### Parameters

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

    *   `connectivity.pingInterval` **[Number][12]** Time in between websocket ping attempts (milliseconds). (optional, default `30000`)
    *   `connectivity.reconnectLimit` **[Number][12]** 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][12]** Base time between websocket reconnect attempts (milliseconds). (optional, default `5000`)
    *   `connectivity.reconnectTimeMultiplier` **[Number][12]** 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][12]** 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.maxMissedPings` **[Number][12]** Maximum pings sent (without receiving a response) before reporting an error. (optional, default `3`)
    *   `connectivity.checkConnectivity` **[Boolean][11]** Flag to determine whether the SDK should check connectivity. (optional, default `true`)
    *   `connectivity.webSocketOAuthMode` **[string][8]** query will send the bearer access token to authenticate the websocket and none will not send it. (optional, default `query`)

### config.notifications

Configuration options for the notification feature.

#### Parameters

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

    *   `notifications.idCacheLength` **[number][12]** 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.

## 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 'kandy'
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 updating the [call.removeH264Codecs][21] configuration will not immediately change the SDP handlers used for a call. If you want to add or remove the
h264 codec remover sdp handler you should follow this procedure:

1.  Update the config for removeH264Codecs using the [updateConfig][22] API.
2.  Update the sdp handler list using the [setSdpHandlers][23] API and provide any client defined SDP handler functions.

    NOTE: You can get the currently defined SDP handler functions with the [getConfig][24] API.

Please note that the object provided to the `updateConfig` API may be different
than the object retrieved from the [getConfig][24] 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][25] section.

#### Parameters

*   `newConfigValues` **[Object][7]** Key-value pairs that will be placed into the store. See [config][25] 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.
})
```

*   Throws **[Error][26]** Invalid event type

### 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.

<!---->

*   Throws **[Error][26]** Invalid event type

### 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.

<!---->

*   Throws **[Error][26]** Listener not a function

### unsubscribe

Removes a global event listener from SDK instance.

#### Parameters

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

<!---->

*   Throws **[Error][26]** Listener not a function

### 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.

### 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][27]** 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.

### makeAnonymous

Starts an outgoing call as an anonymous user.

#### Parameters

*   `callee` **[string][8]** Full user ID of the call recipient.
*   `credentials` **[Object][7]** Information needed to validate a token anonymous call.

    *   `credentials.realm` **[Object][7]** The realm used to encrypt the tokens.
    *   `credentials.accountToken` **[Object][7]?** The encrypted account token of the account making the call.
    *   `credentials.fromToken` **[Object][7]?** The encrypted SIP address of the account/caller.
    *   `credentials.toToken` **[Object][7]?** The encrypted SIP address of the callee.
*   `callOptions` **[Object][7]** Call options.

    *   `callOptions.from` **[string][8]** The URI of the user making the call.
    *   `callOptions.audio` **[Boolean][11]** Whether the call should have audio on start. Currently, audio-less calls are not supported. (optional, default `true`)
    *   `callOptions.audioOptions` **[Object][7]?** Options for configuring the call's audio.

        *   `callOptions.audioOptions.deviceId` **[call.MediaConstraint][28]?** ID of the microphone to receive audio from.
    *   `callOptions.bandwidth` **[call.BandwidthControls][29]?** Options for configuring media's bandwidth.
    *   `callOptions.video` **[Boolean][11]** Whether the call should have video on start. (optional, default `false`)
    *   `callOptions.videoOptions` **[Object][7]?** Options for configuring the call's video.

        *   `callOptions.videoOptions.deviceId` **[call.MediaConstraint][28]?** ID of the camera to receive video from.
        *   `callOptions.videoOptions.height` **[call.MediaConstraint][28]?** The height of the video.
        *   `callOptions.videoOptions.width` **[call.MediaConstraint][28]?** The width of the video.
        *   `callOptions.videoOptions.frameRate` **[call.MediaConstraint][28]?** The frame rate of the video.
    *   `callOptions.screen` **[Boolean][11]** Whether the call should have screenshare on start. (optional, default `false`)
    *   `callOptions.screenOptions` **[Object][7]?** Options for configuring the call's screenShare.

        *   `callOptions.screenOptions.height` **[call.MediaConstraint][28]?** The height of the screenShare.
        *   `callOptions.screenOptions.width` **[call.MediaConstraint][28]?** The width of the screenShare.
        *   `callOptions.screenOptions.frameRate` **[call.MediaConstraint][28]?** The frame rate of the screenShare.
    *   `callOptions.displayName` **[string][8]?** Custom display name to be provided to the destination. Only used with token-less anonymous calls. Not supported in all environments and may use default display name.
    *   `callOptions.customParameters` **[Array][13]<[call.CustomParameter][30]>?** Custom SIP header parameters for the SIP backend.

#### Examples

```javascript
// Make a basic anonymous call.
let callee = 'user1@example.com';
let callOptions = { ... };

let callId = client.call.makeAnonymous(callee, {}, callOptions);
```

```javascript
// Make a time-limited token anonymous call.
let callee = 'user1@example.com';
let account = 'user2@example.com';
let callOptions = { ...
    customParameters: [
      {
        "name": "X-GPS",
        "value": "42.686032,23.344565"
      }
    ],
    ...
  };

// Generate / Retrieve the encrypted tokens.
const key = 'abc123...';
const credentials = {
     accountToken: createToken(account, key),
     fromToken: createToken('sip:' + account, key),
     toToken: createToken('sip:' + callee, key),
     realm: 'realmAbc123...'
};

let callId = client.call.makeAnonymous(callee, credentials, callOptions);
```

Returns **[string][8]** Id of the outgoing call.

### CallObject

Information about a Call.

Can be retrieved using the [call.getAll][31] or [call.getById][32] APIs.

Type: [Object][7]

#### Properties

*   `id` **[string][8]** The ID of the call.
*   `from` **user.UserID** A unique identifier (uri) of the person who made the call.
*   `to` **user.UserID** 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][33] for possible states.
*   `mediaConnectionState` **[string][8]** The current status of the call's media connection. See [call.mediaConnectionStates][34] 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][13]<[string][8]>** A list of Track IDs that the call is sending to the remote participant.
*   `remoteTracks` **[Array][13]<[string][8]>** A list of Track IDs that the call is receiving from the remote participant.
*   `mediaOffered` **[call.MediaOffered][35]?** 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][29]** The bandwidth limitations set for the call.
*   `customParameters` **[Array][13]<[call.CustomParameter][30]>** The locally set Custom Parameters for the call.
*   `startTime` **[number][12]** The start time of the call in milliseconds since the epoch.
*   `endTime` **[number][12]?** The end time of the call in milliseconds since the epoch.

### 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 }
   }
})
```

### 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][12]?** The desired combined bandwidth bitrate in kilobits per second for all media in the call.
*   `audio` **[number][12]?** The desired bandwidth bitrate in kilobits per second for received remote audio.
*   `video` **[number][12]?** 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][36] for the list of possible values).
*   `videoNetworkPriority` **RTCPriorityType?** The desired network priority for video traffic (see [RTCPriorityType Enum][36] for the list of possible values).
*   `screenNetworkPriority` **RTCPriorityType?** The desired network priority for screen share traffic (see [RTCPriorityType Enum][36] 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][13]\<RTCIceServer>?** The list of ICE servers to be used for calls.
    The full set of properties defined for an RTCIceServer, are mentioned
    [here][37].
*   `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][12]?** An unsigned 16-bit integer value which specifies
    the size of the prefetched ICE candidate pool. The default value is 0 (meaning no candidate prefetching will occur).
*   `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][13]<[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][38] 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][13]\<RTCIceCandidate>** An array of all ICE candidates collected so far.
*   `iceCollectionDuration` **[number][12]** The time elapsed since the start of the ICE collection process.
*   `iceGatheringState` **[string][8]** The current ICE gathering state.
    See [RTCPeerConnection.iceGatheringState][39].
*   `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][40]** 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][12]** The amount of time to wait for ideal candidates, in
        milliseconds.  See [config.call][21] for more information.
    *   `iceTimeouts.iceCollectionMaxTimeout` **[number][12]** The maximum amount of time to wait for ICE collection,
        in milliseconds. See [config.call][21] 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][41]** 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][12]** 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][42]** 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.
*   `tracks` **[Array][13]<[call.TrackObject][43]>** A list of Track objects that are 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][13]<[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][13]<[call.DeviceInfo][44]>** A list of camera device information.
*   `microphone` **[Array][13]<[call.DeviceInfo][44]>** A list of microphone device information.
*   `speaker` **[Array][13]<[call.DeviceInfo][44]>** 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.

These parameters must be configured on the server prior to making a request, otherwise the request will fail when trying to include the parameters.

These parameters can be specified with the [call.make][45] and [call.answer][46] APIs.
They can also be set after a Call is established using the [call.setCustomParameters][47] API, and sent using the [call.sendCustomParameters][48] API.

Custom headers 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][49] event
which will contain the custom parameters that were received.

A Call's custom parameters are stored on the Call's [CallObject][50],
which can be retrieved using the [call.getById][32] or
[call.getAll][31] 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 and are only provided via the [call:customParameters][49] event.

Type: [Object][7]

#### Properties

*   `name` **[string][8]** The name of the custom parameter
*   `value` **[string][8]** The value of the custom parameter

#### Examples

```javascript
// Specify custom parameters when making a call.
client.call.make(destination, mediaConstraints,
 {
   customParameters: [
     {
       name: 'X-GPS',
       value: '42.686032,23.344565'
     }
   ]
 }
)
```

### 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][51] API.

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

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

#### Parameters

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

### 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][52] event.

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

#### Parameters

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

### setCustomParameters

Set the [Custom Parameters][54] of a Call, to be provided to the remote endpoint.

The specified parameters will be saved as part of the call's information 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.

A Call's custom parameters are a property of the Call's [CallObject][50],
which can be retrieved using the [call.getById][32] or
[call.getAll][31] APIs.

The custom parameters set on a call can be sent directly with the [call.sendCustomParameters][48] API.

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

#### Parameters

*   `callId` **[string][8]** The ID of the call.
*   `customParameters` **[Array][13]<[call.CustomParameter][30]>** The custom parameters to set.

### sendCustomParameters

Send the custom parameters on an ongoing call to the server. The server may either consume the headers or relay them
to another endpoint, depending on how the server is configured.

A Call's custom parameters are a property of the Call's [CallObject][50],
which can be retrieved using the [call.getById][32] or
[call.getAll][31] APIs.

To change or remove the custom parameters on a call, use the [call.setCustomParameters][47] API.

#### Parameters

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

### 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][13]<[call.CallObject][55]>** 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][55]** A call object.

### end

Ends an ongoing call.

The SDK will stop any/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][52] event.

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

#### Parameters

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

### 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][52] event.

The SDK will emit a [call:newTrack][57] 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.audioOptions` **[Object][7]?** Options for configuring the call's audio.

        *   `media.audioOptions.deviceId` **[call.MediaConstraint][28]?** ID of the microphone to receive audio from.
    *   `media.videoOptions` **[Object][7]?** Options for configuring the call's video.

        *   `media.videoOptions.deviceId` **[call.MediaConstraint][28]?** ID of the camera to receive video from.
        *   `media.videoOptions.height` **[call.MediaConstraint][28]?** The height of the video.
        *   `media.videoOptions.width` **[call.MediaConstraint][28]?** The width of the video.
        *   `media.videoOptions.frameRate` **[call.MediaConstraint][28]?** The frame rate of the video.
    *   `media.screenOptions` **[Object][7]?** Options for configuring the call's screenShare.

        *   `media.screenOptions.height` **[call.MediaConstraint][28]?** The height of the screenShare.
        *   `media.screenOptions.width` **[call.MediaConstraint][28]?** The width of the screenShare.
        *   `media.screenOptions.frameRate` **[call.MediaConstraint][28]?** The frame rate of the screenShare.
*   `options` **[Object][7]?**  (optional, default `{}`)

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

### removeMedia

Remove tracks from an ongoing call.

The progress of the operation will be tracked via the
[call:operation][52] 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][13]** A list of track IDs to remove.
*   `options` **[Object][7]?**  (optional, default `{}`)

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

### 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][59] API can be used.

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

The SDK will emit a [call:newTrack][57] 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` **[Object][7]?** Options for configuring the call's video.

    *   `videoOptions.deviceId` **[call.MediaConstraint][28]?** ID of the camera to receive video from.
    *   `videoOptions.height` **[call.MediaConstraint][28]?** The height of the video.
    *   `videoOptions.width` **[call.MediaConstraint][28]?** The width of the video.
    *   `videoOptions.frameRate` **[call.MediaConstraint][28]?** The frame rate of the video.
*   `options` **[Object][7]?** 

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

### 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][60] API can be used.

The progress of the operation will be tracked via the
[call:operation][52] 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]** ID of the call being acted on.

### startScreenshare

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

The latest SDK release (v4.X+) has not yet implemented this API in the
same way that it was available in previous releases (v3.X). In place
of this API, the SDK has a more general API that can be used for this
same behaviour.

The [call.addMedia][59] API can be used to perform the same behaviour
as `startScreenshare`. {@link call.addMedia} is a general-purpose API
for adding media to a call, which covers the same functionality as
`startScreenshare`. Selecting only screen options when using
[call.addMedia][59] will perform the same behaviour as using
`startScreenshare`.

#### Examples

```javascript
// Select media options for adding only screenshare.
const media = {
   audio: false,
   video: false,
   screen: true,
   screenOptions: { ... }
}

// Add the selected media to the call.
client.call.addMedia(callId, media)
```

### stopScreenshare

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

The latest SDK release (v4.X+) has not yet implemented this API in the
same way that it was available in previous releases (v3.X). In place
of this API, the SDK has a more general API that can be used for this
same behaviour.

The [call.removeMedia][60] API can be used to perform the same
behaviour as `stopScreenshare`. {@link call.removeMedia} is a
general-purpose API for removing media from a call, which covers the
same functionality as `stopScreenshare`. Specifying only the screen
track when using [call.removeMedia][60] will perform the same
behaviour as using `stopScreenshare`.

There is a caveat that if a Call has multiple video tracks (for example,
both a video and a screen track), the SDK itself cannot yet
differentiate one from the other. The application will need to know
which track was the screen track in this scenario.

#### Examples

```javascript
const call = client.call.getById(callId)
// Get the ID of any/all video tracks on the call.
const videoTracks = call.localTracks.filter(trackId => {
   const track = call.media.getTrackById(trackId)
   // Both video and screen tracks have kind of 'video'.
   return track.kind === 'video'
})

// Pick out the screen track.
const screenTrack = videoTracks[0]

// Remove screen from the call.
client.call.removeMedia(callId, [ screenTrack ])
```

### 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][52] 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][12]** The amount of time, in milliseconds, that each DTMF tone should last. (optional, default `100`)
*   `intertoneGap` **[number][12]** The length of time, in milliseconds, to wait between tones. (optional, default `70`)

### getStats

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

The data retrieved is a [RTCStatsReport][61]
object, which contains many individual
[RTCStats][62].
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
Track of the Call.

This API will return a promise which, when resolved, will contain the report of the particular call.
The progress of the operation will be tracked via the
[call:operation][52] event.

The SDK will emit a
[call:statsReceived][63] event, after
the operation completes, that has the report.

#### Parameters

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

#### Examples

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

// Get a snapshot of the Call's stats.
//   This may be done on a regular interval to collect data over time.
client.call.getStats(callId)
```

### 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][52] event.

The SDK will emit a
[call:trackReplaced][64] 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` **[Object][7]?** Options for configuring the audio track.

        *   `media.audioOptions.deviceId` **[call.MediaConstraint][28]?** ID of the microphone to receive audio from.
    *   `media.video` **[boolean][11]** Whether to create a video track. (optional, default `false`)
    *   `media.videoOptions` **[Object][7]?** Options for configuring the video track.

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

#### 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
})
```

### 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][65] event
upon retrieving that list of codecs.

This API is a wrapper for the static method [RTCRtpSender.getCapabilities()][66].
Firefox browser does not currently support this method. Therefore, this API will not work on Firefox.

#### Parameters

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

### setSdpHandlers

Set [SDP Handler Functions][67] 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][13]<[call.SdpHandlerFunction][20]>** The list of SDP handler functions to modify SDP.

### 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][50],
which can be retrieved using the [call.getById][32] or
[call.getAll][31] APIs.

The SDK emits a [call:stateChange][53]
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][33] 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][68] API will attempt to reconnect the media. See
the [call.restartMedia][68] API description for more information.

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

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

The SDK emits a [call:mediaConnectionChange][70]
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][68] 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
  }
}
```

### 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][34]
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][34] should have
transitioned to `checking` (via a
{@link call.event:call:mediaConnectionChange call:mediaConnectionChange}
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][34].

Behaviour during the operation may differ slightly based on the browser.
Notably, Firefox will always transition to the `checking`
[mediaConnectionState][34] 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][70]
event emitted. For this reason, Chrome-based applications may need a
short delay after receiving the [call:mediaRestart][71]
event before checking the Call's updated
[mediaConnectionState][34] to ensure the
application is acting on the "latest" state.

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

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

#### Parameters

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

### setDefaultDevices

The `setDefaultDevices` API from previous SDK releases (3.X) has been
deprecated in the latest releases (4.X+). The SDK no longer keeps
track of "default devices" on behalf of the application.

The devices used for a call can be selected as part of the APIs for
starting the call. Microphone and/or camera can be chosen in the
[call.make][45] and [call.answer][46] APIs, and speaker can be
chosen when the audio track is rendered with the
[media.renderTracks][72] API.

### changeInputDevices

Changes the camera and/or microphone used for a Call's media input.

The latest SDK release (v4.X+) has not yet implemented this API in the
same way that it was available in previous releases (v3.X). In place
of this API, the SDK has a more general API that can be used for this
same behaviour.

The same behaviour as the `changeInputDevices` API can be implemented
using the general-purpose [call.replaceTrack][73] API. This API can
be used to replace an existing media track with a new track of the
same type, allowing an application to change certain aspects of the
media, such as input device.

#### Examples

```javascript
const call = client.call.getById(callId)
// Get the ID of the Call's video track.
const videoTrack = call.localTracks.find(trackId => {
   const track = client.media.getTrackById(trackId)
   return track.kind === 'video'
})

// Select the new video options.
const media = {
   video: true,
   videoOptions: {
       deviceId: 'cameraId'
   }
}

// Change the call's camera by replacing the video track.
client.call.replaceTrack(callId, videoTrack, media)
```

### changeSpeaker

Changes the speaker used for a Call's audio output. Supported on
browser's that support HTMLMediaElement.setSinkId().

The latest SDK release (v4.X+) has not yet implemented this API in the
same way that it was available in previous releases (v3.X). In place
of this API, the SDK has a more general API that can be used for this
same behaviour.

The same behaviour as the `changeSpeaker` API can be implemented by
re-rendering the Call's audio track.  A speaker can be selected when
rendering an audio track, so changing a speaker can be simulated
by unrendering the track with [media.removeTracks][74], then
re-rendering it with a new speaker with [media.renderTracks][72].

#### Examples

```javascript
const call = client.call.getById(callId)
// Get the ID of the Call's audio track.
const audioTrack = call.localTracks.find(trackId => {
   const track = client.media.getTrackById(trackId)
   return track.kind === 'audio'
})

// Where the audio track was previously rendered.
const audioContainer = ...

// Unrender the audio track we want to change speaker for.
client.media.removeTrack([ audioTrack ], audioContainer)
// Re-render the audio track with a new speaker.
client.media.renderTrack([ audioTrack ], audioContainer, {
   speakerId: 'speakerId'
})
```

### call:operation

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

Information about ongoing call operations are stored with the call
information (see the [call.getById][32] API). This event indicates that
an operation's information has been changed.

Local call operations will be tracked from start to finish. An operation may
be updated as it progresses, based on the status of the operation. The
operation status may be ongoing or pending, depending if the operation is
waiting on activity on the local or remote end of the call, respectively.

Except in the case of slow-start operations, remote operations will only be
tracked as a "finish", to indicate that it occurred.

#### Parameters

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

    *   `params.operation` **[string][8]** The call operation causing this event.
    *   `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][27]?** An error object, if the operation was not successful.

### call:start

An outgoing call has been started.

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

#### Parameters

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

    *   `params.callId` **[string][8]** The ID of the call.
    *   `params.error` **[api.BasicError][27]?** 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][32]
API.

#### Parameters

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

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

#### Examples

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

### call:stateChange

A Call's state has changed.

See [call.states][33] 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]?** 

        *   `params.transition.statusCode` **[number][12]?** 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][27]?** 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][13]** 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][13]** 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][59] API for example, or when the
Call is unheld with the [call.unhold][51] 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][75] API.

#### Parameters

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

    *   `params.callId` **[string][8]** The ID of the Call the tracks were added to.
    *   `params.trackIds` **[Array][13]<[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][60] API for example, or when the
Call is held with the [call.hold][76] 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][75] API.

#### Parameters

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

    *   `params.callId` **[string][8]** The ID of the Call the tracks were removed from.
    *   `params.trackIds` **[Array][13]<[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][77] 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][78]** The RTCStatsReport.
    *   `params.error` **[api.BasicError][27]?** An error object, if the operation was not successful.

#### Examples

```javascript
client.on('call:statsReceived', function (params) {
   // Iterate over each individual statistic inside the RTCPStatsReport Map.
   params.result.forEach(stat => {
     ...
   })
})
```

### call:trackReplaced

A local Track has been replaced by the [call.replaceTrack][73] 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][79]
event, and the new Track is available in its place, similar to the
[call:tracksAdded][80] 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][43]?** State of the replaced track.
    *   `params.error` **[api.BasicError][27]?** 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: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][81] 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][13]<[Object][7]>** The list of codecs.

### 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][32] API,
and check the `mediaConnectionState` property of the call.
See {@link call.mediaConnectionStates} 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][68] API being called.
See the description for [call.restartMedia][68] for information about its
usage.

The [call:mediaConnectionChange][70] 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][27]?** 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
     ...
   }
})
```

## connection

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

### WSConnectionObject

Information about a websocket connection.

Can be retrieved using the [connection.getSocketState][82] 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.
*   `method` **[Object][7]** Information about how the websocket is being used.

    *   `method.type` **[string][8]?** How the websocket is staying connected.
    *   `method.responsibleParty` **[string][8]?** Who is responsible for keeping the connection alive.
*   `platform` **[string][8]** The SDK platform being used.
*   `pingInterval` **[number][12]** How often the client will ping the server to test for websocket connectivity.
*   `reconnectLimit` **[number][12]** How many times the SDK will try to reconnect a disconnected websocket.
*   `reconnectDelay` **[number][12]** How long the SDK will wait before retrying websocket reconnection.
*   `reconnectTimeMultiplier` **[number][12]** 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][12]** 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.
*   `maxMissedPings` **[number][12]** How many missed pings before the SDK stops trying to reconnect 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][12]?** 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.
*   `lastContact` **[number][12]** The date and time that the last known contact with the server was.

### getSocketState

Get the state of the websocket.

#### Parameters

*   `platform` **[string][8]** Backend platform for which to request the websocket's state. (optional, default `'link'`)

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

### enableConnectivityChecking

Enables or disables connectivity checking.

#### Parameters

*   `enable` **[boolean][11]** Enable connectivity checking.

### resetConnection

Triggers a reset in the connection to the WebSocket being used for notifications.
This can be used in scenarios where a network issue (undetectable by the SDK)
is detected by an application.

If there is no WebSocket currently connected, this function has no effect.
Calling this function will trigger all the normal WebSocket and connectivity lifecycle
events as well as trigger re-connection processing that follows the configuration of the SDK.
Calling this function always has the potential of causing some events being lost by the
SDK and preventing proper operation.

### ws:change

The websocket to the server has changed state.

#### Parameters

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

    *   `params.platform` **[string][8]** The platform

## 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][84]) 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][84]) will need to handle LogEntry
objects.

Type: [Object][7]

#### Properties

*   `timestamp` **[number][12]** 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][13]** 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][84]). 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][85]
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][86] API.

### getDevices

Retrieves the available media devices for use.

The [devices:change][87] 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][88]** 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][43]** A Track object.

### 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][86] 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][89] 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][87]
event when the operation is successful or a
[devices:error][90] 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 })
```

### 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][13]<[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:newTrack', function (params) {
   const track = client.media.getTrackById(params.trackId)
   const container = params.local ? localContainer : remoteContainer

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

### 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][13]<[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.

### 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][91] event
when a Track has been muted.

#### Parameters

*   `trackIds` **[Array][13]<[string][8]>** List of 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][92] event
when a Track has been unmuted.

#### Parameters

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

### devices:change

The media devices available for use have changed.

Information about the available media devices can be retrieved using the
[media.getDevices][86] 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)][93] that was provided.

#### Parameters

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

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

### media:muted

The specified Tracks have been muted.

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

#### Parameters

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

    *   `params.tracks` **[Array][13]<[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][95]
API.

#### Parameters

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

    *   `params.tracks` **[Array][13]<[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][96] event).

This event is generated outside the control of the SDK. This will predominantely
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][97] 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][13]<[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][27]?** 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][60] 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][73] 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]** 
*   `channel` **[string][8]?** The channel that the notification came from.

### registerApplePush

Registers with Apple push notification service. Once registration is successful, the application will be able to receive
standard and/or voip push notifications. It can then send these notifications to the SDK with [api.notifications.process][98]
in order for the SDK to process them.

#### Parameters

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

    *   `params.services` **[Array][13]<[string][8]>** Array of services for which we wish to receive notifications.
    *   `params.voipDeviceToken` **[string][8]** The voip device token used for voip push on iOS.
        This token is required if registering for call service notifications on iOS.
    *   `params.standardDeviceToken` **[string][8]** The standardDevice token used for standard push on iOS .
        This token is required when registering for non-call service notifications.
    *   `params.bundleId` **[string][8]** The bundleId to identify the application receiving the push notification.
    *   `params.clientCorrelator` **[string][8]** Unique identifier for a client device.
    *   `params.realm` **[string][8]** The realm used by the push registration service to identify and
        establish a connection with the service gateway.
    *   `params.isProduction` **[boolean][11]** If true, push notification will be sent to production.
        If false, push notification will be sent to sandbox.

Returns **[Promise][99]** When successful,  the information of the registration.
Promise will reject with error object otherwise.

### registerAndroidPush

Registers with Google push notification service. Once registration is successful, the application will be able to receive
standard and/or voip push notifications. It can then send these notifications to the SDK with [api.notifications.process][98]
in order for the SDK to process them.

#### Parameters

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

    *   `params.services` **[Array][13]<[string][8]>** Array of services to register for.
    *   `params.deviceToken` **[string][8]** The device token used for standard push on Android. This token is required
        when registering for all related services notifications.
    *   `params.bundleId` **[string][8]** The bundleId to identify the application receiving the push notification.
    *   `params.clientCorrelator` **[string][8]** Unique identifier for a client device.
    *   `params.realm` **[string][8]** The realm used by the push registration service to identify
        and establish a connection with the service gateway.

Returns **[Promise][99]** When successful,  the information of the registration.
Promise will reject with error object otherwise.

### unregisterApplePush

Unregister Apple push notifications.

#### Parameters

*   `registrationInfo` **[string][8]** The data returned from the push registration

Returns **[Promise][99]** When successful, the promise will resolve with undefined.
Promise will reject with error object otherwise.

### unregisterAndroidPush

Unregister Android push notifications.

#### Parameters

*   `registrationInfo` **[string][8]** The data returned from the push registration

Returns **[Promise][99]** When successful, the promise will resolve with undefined.
Promise will reject with error object otherwise.

### enableWebsocket

Enables, or disables, the processing of websocket notifications.

#### Parameters

*   `enable` **[boolean][11]** Whether the websocket channel should be enabled.

### 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][27]** The Basic error object.
    *   `params.channel` **[string][8]** The channel for the notification.

## 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][100]
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][100]
    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][99]<[Response][101]>** A promise for a [Response][102] object.

## sdpHandlers

A set of [SdpHandlerFunction][67]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][21] configuration
parameter. They can also be set after the SDK's creation by using the
[call.setSdpHandlers][23] function.

### Examples

```javascript
import { create, sdpHandlers } from 'kandy';
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][13]<[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][81] function in order to build logic to determine the best codecs to use
for their application.

#### Parameters

*   `codecs` **([Array][13]\<CodecSelector> | [Array][13]<[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 'kandy';

const codecRemover = sdpHandlers.createCodecRemover([
  // Remove all VP8 and VP9 codecs.
  'VP8',
  'VP9',

  // Remove all H264 codecs with the specified FMTP parameters.
  {
    name: 'H264',
    fmtpParams: ['profile-level-id=4d0032', 'packetization-mode=1']
  }
])

const client = create({
  call: {
    sdpHandlers: [codecRemover]
  }
})
```

Returns **[call.SdpHandlerFunction][20]** The resulting SDP handler that will remove the codec.

[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://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[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]: #callsdphandlerfunction

[21]: #configconfigcall

[22]: #apiupdateconfig

[23]: #callsetsdphandlers

[24]: #apigetconfig

[25]: #config

[26]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error

[27]: #apibasicerror

[28]: #callmediaconstraint

[29]: #callbandwidthcontrols

[30]: #callcustomparameter

[31]: #callgetall

[32]: #callgetbyid

[33]: #callstates

[34]: #callmediaconnectionstates

[35]: #callmediaoffered

[36]: https://www.w3.org/TR/webrtc-priority/#rtc-priority-type

[37]: https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer#properties

[38]: https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer/urls

[39]: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceGatheringState

[40]: #callicecollectioninfo

[41]: #callicecollectioncheckresult

[42]: #callsdphandlerinfo

[43]: #calltrackobject

[44]: #calldeviceinfo

[45]: call.make

[46]: call.answer

[47]: #callsetcustomparameters

[48]: #callsendcustomparameters

[49]: call.event:call:customParameters

[50]: #callcallobject

[51]: #callunhold

[52]: #calleventcalloperation

[53]: #calleventcallstatechange

[54]: #callcustomparameter

[55]: #callcallobject

[56]: call.event:call:trackEnded

[57]: call.event:call:newTrack

[58]: #calldscpcontrols

[59]: #calladdmedia

[60]: #callremovemedia

[61]: https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport

[62]: https://developer.mozilla.org/en-US/docs/Web/API/RTCStats

[63]: #calleventcallstatsreceived

[64]: #calleventcalltrackreplaced

[65]: #calleventcallavailablecodecs

[66]: https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-getcapabilities

[67]: #callsdphandlerfunction

[68]: #callrestartmedia

[69]: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState

[70]: #calleventcallmediaconnectionchange

[71]: #calleventcallmediarestart

[72]: #mediarendertracks

[73]: #callreplacetrack

[74]: #mediaremovetracks

[75]: #mediagettrackbyid

[76]: #callhold

[77]: #callgetstats

[78]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map

[79]: #calleventcalltracksremoved

[80]: #calleventcalltracksadded

[81]: #callgetavailablecodecs

[82]: #connectiongetsocketstate

[83]: #connectionwsconnectionobject

[84]: #configconfiglogs

[85]: #call

[86]: #mediagetdevices

[87]: #mediaeventdeviceschange

[88]: #callmediaobject

[89]: #mediainitializedevices

[90]: #mediaeventdeviceserror

[91]: #mediaeventmediamuted

[92]: #mediaeventmediaunmuted

[93]: #callmediaconstraint

[94]: #mediamutetracks

[95]: #mediaunmutetracks

[96]: #mediaeventmediasourceunmuted

[97]: #mediaeventmediasourcemuted

[98]: api.notifications.process

[99]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise

[100]: https://developer.mozilla.org/en-US/docs/Web/API/fetch

[101]: https://developer.mozilla.org/docs/Web/Guide/HTML/HTML5

[102]: https://developer.mozilla.org/en-US/docs/Web/API/Response
