> ## Documentation Index
> Fetch the complete documentation index at: https://docs.navtalk.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# webrtc.signaling.offer

> WebRTC offer signaling event

Triggered when a WebRTC offer is received through the unified WebSocket connection. WebRTC signaling is sent through the same WebSocket connection as other events, eliminating the need for a separate WebRTC signaling connection.

## Event Properties

<ResponseField name="type" type="string">
  Event type. Always `"webrtc.signaling.offer"` for this event.
</ResponseField>

<ResponseField name="data" type="object">
  Event data object containing WebRTC offer information.
</ResponseField>

<ResponseField name="data.sdp" type="object">
  The SDP (Session Description Protocol) offer object. This is an RTCSessionDescription object that needs to be set as the remote description.

  **Example**:

  ```json theme={null}
  {
    "type": "offer",
    "sdp": "v=0\r\no=- 123456789 123456789 IN IP4 0.0.0.0\r\n..."
  }
  ```
</ResponseField>

<ResponseExample>
  ```json Example theme={null}
  {
    "type": "webrtc.signaling.offer",
    "data": {
      "sdp": {
        "type": "offer",
        "sdp": "v=0\r\no=- 123456789 123456789 IN IP4 0.0.0.0\r\n..."
      }
    }
  }
  ```
</ResponseExample>

## Receiving Offer

When you receive a WebRTC offer (typically sent by the server), handle it like this:

```javascript theme={null}
const NavTalkMessageType = Object.freeze({
    WEB_RTC_OFFER: "webrtc.signaling.offer",
    WEB_RTC_ANSWER: "webrtc.signaling.answer",
    WEB_RTC_ICE_CANDIDATE: "webrtc.signaling.iceCandidate",
    // ... other event types
});

// Function to send answer (after receiving offer)
function sendAnswerMessage(sdp) {
    const message = {
        type: NavTalkMessageType.WEB_RTC_ANSWER,
        data: { sdp: sdp }
    };
    socket.send(JSON.stringify(message));
}

// Function to send ICE candidate
function sendIceMessage(candidate) {
    const message = {
        type: NavTalkMessageType.WEB_RTC_ICE_CANDIDATE,
        data: { candidate: candidate }
    };
    socket.send(JSON.stringify(message));
}

async function handleReceivedMessage(data) {
    const nav_data = data.data;
    
    switch (data.type) {
        case NavTalkMessageType.WEB_RTC_OFFER:
            // Create peer connection
            const offer = new RTCSessionDescription(nav_data.sdp);
            peerConnection = new RTCPeerConnection(configuration);
            
            // Set remote description and create answer
            await peerConnection.setRemoteDescription(offer);
            const answer = await peerConnection.createAnswer();
            await peerConnection.setLocalDescription(answer);
            
            // Send answer through unified WebSocket
            sendAnswerMessage(peerConnection.localDescription);
            
            // Set up ICE candidate handler
            peerConnection.onicecandidate = (event) => {
                if (event.candidate) {
                    sendIceMessage(event.candidate);
                }
            };
            break;
    }
}
```

**Key Points:**

* The `sdp` parameter in `data.sdp` is an `RTCSessionDescription` object with:
  * `type`: `"offer"`
  * `sdp`: The SDP string containing the offer description
* After receiving an offer, you should:
  1. Create an RTCPeerConnection
  2. Set the offer as remote description
  3. Create and send an answer
  4. Set up ICE candidate handler to send candidates

<Note>
  - **When received**: The server typically sends the offer when establishing a WebRTC connection
  - **What to do**: After receiving an offer, create an answer and send it back, then send ICE candidates as they're generated
  - All WebRTC signaling (offer, answer, ICE candidates) is sent through the unified WebSocket connection using the encapsulated event types. There is no need for a separate WebRTC signaling WebSocket connection.
</Note>
