# Web Campaigns (Reference: https://docs.iqra.bot/build/campaigns/web) **Web Campaigns** allow you to embed Voice AI directly into your websites, mobile applications, or custom hardware. Unlike Telephony campaigns (which rely on old phone networks), Web Campaigns use **WebRTC** or **WebSockets**. This results in: * **Higher Audio Quality:** HD Voice (44.1kHz) instead of phone quality (8kHz). * **Lower Latency:** Direct internet connection without carrier routing. * **Zero Telephony Costs:** No per-minute fees to Twilio/Telnyx. Creating a Campaign [#creating-a-campaign] Navigate to **Business Dashboard** -> **Routing & Campaigns** -> **Web Campaigns**. Agent & Script [#agent--script] Select the [**Agent**](/build/agent) and the [**Opening Script**](/build/script). Configuration [#configuration] * **Max Duration:** Limit the session length to control compute costs. * **Silence Detection:** Configure how the agent handles user silence (usually more lenient in web sessions than phone calls). Dynamic Variables [#dynamic-variables] Define what data you expect the frontend to pass to the agent. * **Example:** If your website has a logged-in user, you can pass their `name` and `account_id` as metadata when the session starts. * **Usage:** The Agent can then greet them personally: *"Welcome back, \{\{ name }}."* Client Integration [#client-integration] Once saved, the campaign generates a **Web Campaign ID** (e.g., `camp_web_123...`). Use this ID with our client libraries. Check the **[Web Widget SDK](/developers/sdks/web-widget)** and **[.NET Middleware](/developers/sdks/middleware)** guides for implementation details. *** Post-Analysis [#post-analysis] Configure how the system analyzes the conversation after the session closes. 1. Navigate to the **Post Analysis** tab. 2. Select a **Template** defined in the [Post Analysis Module](/build/operations/analysis). 3. **Context Variables:** The LLM will receive the following data: | Variable | Type | Description | | :------------------------------ | :------- | :------------------------------------------- | | `web_session_id` | String | Unique ID for the web session. | | `web_session_created_at` | Datetime | When the connection was established. | | `web_session_status` | String | Status (e.g., `completed`). | | `web_session_web_campaign_id` | String | The Campaign ID. | | `web_session_client_identifier` | String | The unique user ID passed from the frontend. | | `web_session_dynamic_variables` | Object | JSON of variables passed from frontend. | | `web_session_metadata` | Object | JSON of metadata passed from frontend. | | `conversation_id` | String | Unique UUID for the conversation logic. | | `conversation_start_time` | Datetime | Start of audio stream. | | `conversation_end_time` | Datetime | End of audio stream. | | `conversation_end_type` | String | `agent_hangup`, `user_hangup`, `timeout`. | | `conversation_turns` | Object | Raw JSON array of speaker turns. | | `conversation_turns_simplified` | String | Human-readable transcript. | *** Actions (Webhooks) [#actions-webhooks] Sync digital conversation events to your backend. 1. Create a [Custom Tool](/build/tools/custom-tools) first. 2. Select that tool in the Action dropdown. 3. Map the **Available Variables** (below) to the Tool's Input Schema. 1. On Conversation Initiation Failure [#1-on-conversation-initiation-failure] Triggered if the connection is rejected (e.g., Invalid Token, Geo-blocked, or Concurrency Limit reached). | Variable | Type | Description | | :------------------------------ | :------- | :----------------------------------------- | | `web_session_id` | String | Unique ID for the attempted session. | | `web_session_created_at` | Datetime | Time of attempt. | | `web_session_status` | String | `failed`. | | `web_session_web_campaign_id` | String | The Campaign ID. | | `web_session_client_identifier` | String | The unique user ID passed. | | `web_session_dynamic_variables` | Object | JSON variables. | | `web_session_metadata` | Object | JSON metadata. | | `web_session_initiation_error` | String | Error details (e.g., `concurrency_limit`). | 2. On Conversation Initiated [#2-on-conversation-initiated] Triggered when the WebSocket/WebRTC connection is established and audio is ready. | Variable | Type | Description | | :------------------------------ | :------- | :-------------------------------------- | | `web_session_id` | String | Unique ID for the active session. | | `web_session_created_at` | Datetime | Connection time. | | `web_session_status` | String | `active`. | | `web_session_web_campaign_id` | String | The Campaign ID. | | `web_session_client_identifier` | String | The unique user ID passed. | | `web_session_dynamic_variables` | Object | JSON variables. | | `web_session_metadata` | Object | JSON metadata. | | `conversation_id` | String | Unique UUID for the conversation logic. | | `conversation_start_time` | Datetime | Start of audio stream. | 3. On Conversation Ended [#3-on-conversation-ended] Triggered when the user closes the tab or clicks "End Call". | Variable | Type | Description | | :------------------------------ | :------- | :-------------------------------------- | | `web_session_id` | String | Unique ID for the session. | | `web_session_created_at` | Datetime | Connection time. | | `web_session_status` | String | `completed`. | | `web_session_web_campaign_id` | String | The Campaign ID. | | `web_session_client_identifier` | String | The unique user ID passed. | | `web_session_dynamic_variables` | Object | JSON variables. | | `web_session_metadata` | Object | JSON metadata. | | `conversation_id` | String | Unique UUID for the conversation logic. | | `conversation_start_time` | Datetime | Start of audio stream. | | `conversation_end_type` | String | Reason for termination. | | `conversation_end_time` | Datetime | End of audio stream. | | `conversation_turns` | Object | Raw JSON array of speaker turns. | | `conversation_turns_simplified` | String | Human-readable transcript. |