## Prerequisites

- A modern web browser with WebRTC support. For more information, refer to [Supported Browsers](https://docs.cognigy.com/click-to-call/sdk/supported-browsers).
- [Node.js](https://nodejs.org/) version 18 or later.
- A web application where you can install npm packages.
  - The web application must be served over HTTPS or from `localhost`. WebSocket and UDP traffic must be allowed for SIP signaling and media transport.
- A Cognigy.AI Flow with a configured Voice Gateway Endpoint.

## Install the SDK

1. Install the SDK in your web application project using npm:
   
   ```
   npm install @cognigy/click-to-call-sdk
   ```
2. Verify the installation:
   
   ```
   npm list @cognigy/click-to-call-sdk
   ```

## Configure the Client

Import the SDK, verify browser support, and create a client instance:

```javascript
import { createWebRTCClient, checkWebRTCSupport } from '@cognigy/click-to-call-sdk';

const support = checkWebRTCSupport();
if (!support.supported) {
  console.error('WebRTC not supported. Missing features:', support.missing);
  throw new Error('Browser does not support WebRTC');
}

const client = await createWebRTCClient({
  endpointUrl: 'https://your-cognigy-environment.com/endpoint-token',
  userId: 'user-123',
});
```

The `endpointUrl` parameter must point to a valid [Cognigy Voice Gateway Endpoint](https://docs.cognigy.com/ai/agents/deploy/endpoint-reference/voice-gateway):

1. In the **Configuration** section of the Voice Gateway Endpoint, copy the URL from the **Endpoint URL** field.
2. Replace `wss://` with `https://` and remove `/voiceGateway` from the path. For example, if your Endpoint URL is:
 
   ```
   wss://endpoint-trial.cognigy.ai/d17711ad79bc73f9da03865066201d744386d78cf11651a3377ae35085902268/voiceGateway
   ```
3. Then your `endpointUrl` will be:
   
   ```
   https://endpoint-trial.cognigy.ai/d17711ad79bc73f9da03865066201d744386d78cf11651a3377ae35085902268
   ```

The SDK fetches SIP credentials and server details from this URL automatically.

### (Optional) Configure Custom STUN/TURN Servers

For advanced use cases, such as specifying custom STUN or TURN servers, provide a `pcConfig` object when creating the client. Use `pcConfig` only if your application requires custom NAT traversal or TURN servers. Otherwise, the SDK uses default servers automatically.

```javascript
const client = await createWebRTCClient({
  endpointUrl: 'https://your-cognigy-environment.com/endpoint-token',
  userId: 'user-123',
  pcConfig: {
    iceServers: [
      { urls: 'stun:stun.l.google.com:19302' },
      { urls: 'turn:your-turn-server.com:3478', username: 'user', credential: 'password' }
    ]
  }
});
```

## Register Event Listeners

Set up event listeners before making any calls:

```javascript
// Connection events
client.on('connecting', () => console.log('Connecting to SIP server...'));
client.on('registered', () => console.log('SIP client registered'));
client.on('disconnected', () => console.log('Disconnected from SIP server'));

// Call events
client.on('answered', (session) => console.log('Call answered. Session ID:', session.id));
client.on('ended', (session, endInfo) => console.log('Call ended. Cause:', endInfo.cause));
client.on('failed', (session, endInfo) => console.error('Call failed. Cause:', endInfo.cause));

// Error handling
client.on('error', (error) => console.error('WebRTC SDK error:', error.message));
```

Audio playback is automatic. You don’t need to add an `<audio>` element to your HTML. For advanced use cases, such as custom audio processing or visualization, refer to [Custom Audio](https://docs.cognigy.com/click-to-call/sdk/custom-audio).

## Start and End a Call

With the client configured and events registered, start a voice call:

```javascript
// Connect and start the call in one step
await client.connectAndCall();
```

To end the call and clean up:

```javascript
await client.endCall();
await client.disconnect();
```

Instead of calling `endCall()` and `disconnect()` separately, you can call [`client.destroy()`](https://docs.cognigy.com/click-to-call/sdk/api-reference/destroy) to end the call, disconnect, and release all resources in one step.

## Run and Verify

1. Combine the code from the previous sections into a single function and bind it to a button click in your web application. A call must be initiated by a user gesture, for example, a button click, because browsers block audio autoplay without user interaction. Refer to the [Complete Example](https://docs.cognigy.com/click-to-call/sdk/getting-started#complete-example).
2. Start your application and open it in a [supported browser](https://docs.cognigy.com/click-to-call/sdk/supported-browsers).
3. Open the browser developer console.
4. Click the button that triggers the call. You should see the following messages in the console:
   - `Connecting to SIP server...` — the SDK is establishing a connection.
   - `SIP client registered` — registration succeeded.
   - `Call answered. Session ID: ...` — the call is active and audio should be playing.

If you don’t hear audio or the call fails to connect, refer to [Troubleshooting](https://docs.cognigy.com/click-to-call/sdk/troubleshooting#call-issues).

## Complete Example

```javascript
import { createWebRTCClient, checkWebRTCSupport } from '@cognigy/click-to-call-sdk';

async function main() {
  const support = checkWebRTCSupport();
  if (!support.supported) {
    console.error('WebRTC not supported:', support.missing);
    return;
  }

const client = await createWebRTCClient({
    endpointUrl: 'https://your-cognigy-environment.com/endpoint-token',
    userId: 'user-123',
  });

// Connection events
  client.on('connecting', () => console.log('Connecting to SIP server...'));
  client.on('registered', () => console.log('SIP client registered'));
  client.on('disconnected', () => console.log('Disconnected from SIP server'));

// Call events
  client.on('answered', (session) => console.log('Call answered:', session.id));
  client.on('ended', (session, endInfo) => console.log('Call ended:', endInfo.cause));
  client.on('failed', (session, endInfo) => console.error('Call failed:', endInfo.cause));
  client.on('error', (error) => console.error('Error:', error.message));

await client.connectAndCall();

// Clean up when the page unloads.
  // destroy() disconnects the SIP client, ends any active call, and releases all resources.
  window.addEventListener('beforeunload', () => {
    void client.destroy().catch(() => {
    });
  });
}

main();
```

## Next Steps

- [API Reference](https://docs.cognigy.com/click-to-call/sdk/api-reference/overview)
- [Event Reference](https://docs.cognigy.com/click-to-call/sdk/event-reference/overview)
- [Security](https://docs.cognigy.com/click-to-call/sdk/security)
- [Troubleshooting](https://docs.cognigy.com/click-to-call/sdk/troubleshooting)
