Skip to main content

Prerequisites

Before you begin, make sure you have:
  • An active Ringg AI account
  • Your API key (X-API-KEY)
  • An assistant configured for web calls
  • Access to modify your website’s HTML

Execution

Step 1: Configure Your Assistant for Web Calls
  • Open your assistant in the Ringg AI dashboard
  • Navigate to the assistant settings
  • Configure the WebCall Settings section
  • Add your website domain to the Whitelist Domains list
Step 2: Get the Embed Code
  • Open your assistant in the Ringg AI dashboard
  • Click the Embed button in the top right corner
  • Copy the provided code snippet
The embed code will look similar to this:
<script>
	 function loadAgentsCdn(e, t) {
		 let n = document.createElement("link");
		 n.rel = "stylesheet", n.type = "text/css", n.href = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${e}/dist/style.css`;
		 var a = document.createElement("script");
		 a.type = "text/javascript", a.readyState ? a.onreadystatechange = function() {
			 "loaded" !== a.readyState && "complete" !== a.readyState || (a.onreadystatechange = null, t())
		 } : a.onload = function() {
			 t()
		 }, a.src = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${e}/dist/dv-agent.es.js`, document.getElementsByTagName("head")[0].appendChild(n), document.getElementsByTagName("head")[0].appendChild(a)
	 }
</script>
<script>
	 loadAgentsCdn("latest", function() {
		 loadAgent({
			 agentId: "your-agent-id",
			 xApiKey: "your-api-key",
			 variables: {},
			 buttons: {},
		 });
	 });
</script>
Step 3: Customize the Embed Code Modify the configuration object to customize the appearance and behavior of the Web Call assistant:
loadAgent({
  agentId: "your-agent-id",
  xApiKey: "your-api-key",

  variables: {
    custom_variable_1: "value1",
    custom_variable_2: "value2",
  },

  buttons: {
    modalTrigger: {
      styles: {
        backgroundColor: "#4CAF50",
        color: "white",
        borderRadius: "50%",
      },
      icon: {
        url: "https://example.com/custom-icon.svg",
        size: 24,
      },
    },
    mic: {
      styles: {
        backgroundColor: "#f44336",
        borderRadius: "50%",
      },
    },
    call: {
      textBeforeCall: "Start Call",
      textDuringCall: "End Call",
      styles: {
        backgroundColor: "#2196F3",
        color: "white",
        borderRadius: "4px",
      },
    },
  },

  widgetPosition?: {
    triggerPlacement?: "fixed" | "absolute",
    /**
     * Widget positioning mode.
     * "fixed" - floats over the page, fixed to viewport (default)
     * "absolute" - embeds inside a container with id="ringg_ai_container"
     * Supported from v1.0.19+
     */

    triggerAlignment?: "bottom-right" | "bottom-left" | "top-right" | "top-left" | "center",
    /**
     * Position of the trigger button.
     * Supported from v1.0.19+
     * @default "bottom-right"
     */

    hideTriggerOnExpand?: boolean,
    /**
     * Hide the trigger button when widget is open.
     * Supported from v1.0.19+
     * @default true
     */

    widgetAlignment?: "bottom-right" | "bottom-center" | "bottom-left",
    /**
     * Position of the expanded widget.
     * Supported from v1.0.19+
     * @default "bottom-right"
     */
  },

  defaultTab?: "audio" | "text",
  /**
   * The tab shown by default when the component loads.
   * Supported from v1.0.8+
   * @default "audio"
   */

  hideTabSelector?: boolean,
  /**
   * Whether to hide the tab selector UI.
   * Supported from v1.0.8+
   * @default false
   */

  innerWindowProps?: {
    /**
     * Inner window dimensions when a call is connected.
     * Accepts a number (px) or any valid CSS size string.
     * Supported from v1.0.8+
     */
    width?: number | string,
    height?: number | string,
    borderRadius?: number | string,
  },

  title?: string,
  /** Custom title displayed in the header. */

  description?: string,
  /** Custom description displayed below the title. */

  logoUrl?: string,
  /**
   * Custom logo URL displayed in the header.
   * Supported from v1.0.10+
   */

  logoStyles?: Partial<React.CSSProperties>,
  /**
   * Custom CSS styles for the logo container.
   * Supported from v1.0.10+
   */

  legalDisclaimer?: {
    text: string,
    links?: Record<string, string>
  },
  /**
   * Custom legal disclaimer with clickable links.
   * Supported from v1.0.10+
   */

  feedbackScreen?: {
    title?: string,               // Default: "How was your call/chat?"
    description?: string,         // Default: "Your feedback helps us improve!"
    starsCount?: number,          // Default: 5
    placeholder?: string,         // Default: "We'd love to hear more..."
    submitBtnCTA?: string,        // Default: "Submit Feedback"
    submitBtnStyles?: Partial<React.CSSProperties>,
    starsStyles?: {
      filledColor?: string,       // Default: #FBBF24 (yellow)
      emptyColor?: string         // Default: #D1D5DB (gray)
    }
  },
  /**
   * Optional feedback UI props
   * Supported from v1.0.11+
   */
});

Step 4: Add the Code to Your Website Paste the embed code into your website’s HTML, preferably just before the closing </body> tag. Step 5: Configure CDN Permissions If your website uses Content Security Policy (CSP), add the following CDN links to your security policies:
style-src: https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@latest/dist/style.css
script-src: https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@latest/dist/dv-agent.es.js
Step 6: Test the Integration
  • Visit your website
  • Look for the Web Call button (typically in the bottom right corner)
  • Click the button to start a call
  • Speak to test the voice interaction

Widget Positioning

Control where the widget appears on your page. Supported from v1.0.19+.

Fixed Mode (Default)

The widget floats over your page, fixed to the browser viewport. No additional setup required.

Absolute Mode

Embed the widget inside a specific container on your page. Step 1: Add a container with the required ID
<div id="ringg_ai_container" style="position: relative; width: 100%; height: 500px;">
</div>
Step 2: Enable absolute positioning
loadAgent({
  agentId: "your-agent-id",
  xApiKey: "your-api-key",
  widgetPosition: {
    triggerPlacement: "absolute",
    triggerAlignment: "center"
  }
});

OptionTypeDefaultDescription
triggerPlacementstring"fixed""fixed" for viewport, "absolute" for container
triggerAlignmentstring"bottom-right"Trigger button position
hideTriggerOnExpandbooleantrueHide trigger when widget is open
widgetAlignmentstring"bottom-right"Expanded widget position

Trigger Button Customization

Customize the floating action button that opens the widget. Supported from v1.0.19+.

Button Styles

buttons: {
  modalTrigger: {
    styles: {
      backgroundColor: "#4F46E5",
      width: 64,
      height: 64
    }
  }
}

Custom Icon

buttons: {
  modalTrigger: {
    icon: {
      url: "https://example.com/my-icon.svg",
      size: 24
    }
  }
}

OptionTypeDefaultDescription
stylesCSSPropertiesButton CSS styles (width, height, backgroundColor, etc.)
icon.urlstringRingg phone iconCustom icon URL
icon.sizenumber20Icon size in pixels

Widget Events

Subscribe to widget events and perform your custom actions based on them. Supported from v1.0.17.

EventPayload
ringg:widget_statusstatus: "maximised" | "minimised"
mode: "audio" | "text"
ringg:conversation_statusstatus: "started" | "ended"
mode: "audio" | "text"
callId: string
ringg:feedback_statusstatus: "submitted" | "skipped"
callId: string
rating?: number

Usage

window.addEventListener("ringg:widget_status", (e) => {
  console.log(e.detail); // { status: "maximised", mode: "audio" }
});

window.addEventListener("ringg:conversation_status", (e) => {
  console.log(e.detail); // { status: "started", mode: "audio", callId: "abc123" }
});

window.addEventListener("ringg:feedback_status", (e) => {
  console.log(e.detail); // { status: "submitted", callId: "abc123", rating: 5 }
});

Chat Agent (Text Mode)

The Ringg widget supports a text-based chat mode alongside voice calls. In chat mode, the AI assistant handles conversations through typed messages instead of audio, while still supporting interactive widgets like callback scheduling, form collection, and all configured tools.

Setting Up a Chat Agent

Best Practice: Create a dedicated assistant for chat by cloning your voice assistant in the Ringg AI dashboard. This lets you tailor the prompt specifically for text-based interactions — chat conversations are typically longer, more detailed, and benefit from a different conversational style than voice calls.
To set up a chat agent:
  1. Open the Ringg AI dashboard and navigate to your assistants.
  2. Clone your existing voice assistant (or create a new one).
  3. Update the cloned assistant’s prompt to be optimized for chat — e.g., include structured responses, markdown formatting, and instructions for when to present widgets like the callback scheduler.
  4. Configure any chat-specific tools or widgets (calendar for callback scheduling, forms for data collection).
  5. Use the cloned assistant’s agentId in the embed code with defaultTab: "text".

Enabling Chat Mode

Set defaultTab to "text" when loading the agent to open the widget in chat mode by default:
loadAgent({
  agentId: "your-chat-agent-id",
  xApiKey: "your-api-key",
  defaultTab: "text",
});

Chat-Only Mode

To create a chat-only widget with no voice tab, hide the tab selector:
loadAgent({
  agentId: "your-chat-agent-id",
  xApiKey: "your-api-key",
  defaultTab: "text",
  hideTabSelector: true,
});

Dual Mode (Voice + Chat)

You can also offer both voice and chat in the same widget. Users can switch between tabs freely:
loadAgent({
  agentId: "your-agent-id",
  xApiKey: "your-api-key",
  defaultTab: "audio",
  hideTabSelector: false,
});

How Chat Mode Works

The chat agent uses the same underlying assistant configuration as voice mode with these key differences:
  • Input/Output: Text messages instead of audio streams. Audio input and output are disabled; transcription-based text communication is enabled.
  • Context Compression: Long chat conversations are automatically compressed to manage token limits, keeping the conversation flowing without hitting model context limits.
  • RAG Summarization: Knowledge base query results are summarized in chat mode to reduce token usage and provide concise answers.
  • Interactive Widgets: Chat mode is especially powerful with widgets — the assistant can present callback scheduling calendars, data collection forms, and other interactive components directly in the chat window.
  • Same Tools: All configured tools (API integrations, knowledge base queries, widgets, etc.) work identically in chat mode.

OptionTypeDefaultDescription
defaultTab"audio" | "text""audio"Tab shown when the widget loads. Use "text" for chat mode. Supported from v1.0.8+
hideTabSelectorbooleanfalseHides the audio/text tab switcher for a single-mode experience. Supported from v1.0.8+

Chat Widgets

Chat widgets are interactive UI components that the AI assistant can present to users during a conversation. They render directly inside the chat interface, enabling structured interactions like scheduling a callback, collecting form data, or booking appointments — all without leaving the chat.
Chat widgets work best in text mode. While they can also be triggered during voice calls, the visual interaction is most natural in the chat interface. Consider setting up a dedicated chat agent with widgets for the best user experience.

Widget Types

The assistant supports two built-in widget types:
  1. Calendar Widget — Ideal for callback scheduling, appointment booking, and demo scheduling. Presents available date and time slots for the user to select.
  2. Form Widget — Perfect for collecting structured data like contact details, lead information, support tickets, or survey responses.

How Widgets Work

The widget interaction follows a seamless round-trip flow:
  1. During a conversation, the assistant determines it’s the right moment to present a widget (e.g., the user asks to schedule a callback) and calls the send_widgets tool.
  2. The widget renders directly inside the chat interface.
  3. The user interacts with the widget (selects a time slot, fills out a form).
  4. The user’s response is sent back to the assistant automatically.
  5. The assistant processes the response, optionally triggers an API call (e.g., to create a booking in your CRM), and continues the conversation with a confirmation.

Calendar Widget (Callback Scheduling)

The calendar widget is the go-to solution for callback scheduling and appointment booking. It displays available time slots over a configurable number of days, and past slots are automatically excluded so users only see valid options. Common use cases:
  • Schedule a callback from a human agent
  • Book a product demo or consultation
  • Set up a follow-up appointment
Configuration fields:

FieldTypeRequiredDescription
tool_typestringYesMust be "calender_widget_tool"
tool_idstringYesUnique identifier for this widget instance
slot_duration_daysintegerYesNumber of days to show slots for (e.g., 7)
slot_interval_minutesintegerYesMinutes between each slot (e.g., 30)
start_time_24_hour_formatstringYesSlot start time in HH:MM format (e.g., "09:00")
end_time_24_hour_formatstringYesSlot end time in HH:MM format (e.g., "17:00")
timezonestringYesIANA timezone (e.g., "Asia/Kolkata")
api_configobjectNoOptional API to call when the user selects a slot
Example: Callback scheduling configuration (passed in assistant metadata):
{
  "tool_type": "calender_widget_tool",
  "tool_id": "callback_scheduler",
  "slot_duration_days": 7,
  "slot_interval_minutes": 30,
  "start_time_24_hour_format": "09:00",
  "end_time_24_hour_format": "17:00",
  "timezone": "Asia/Kolkata",
  "api_config": {
    "url": "https://your-api.com/schedule-callback",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer your-token",
      "Content-Type": "application/json"
    },
    "body": {}
  }
}
What happens when a user schedules a callback:
  1. The assistant presents the calendar widget with available slots.
  2. The user picks a date and time.
  3. The selected datetime and timezone are sent back to the assistant.
  4. If api_config is provided, the booking data is automatically forwarded to your API (e.g., to create a callback entry in your CRM or scheduling system).
  5. The assistant confirms the booking to the user in a human-readable format (e.g., “Your callback has been scheduled for Monday, March 2nd at 10:30 AM IST”).

Form Widget (Data Collection)

The form widget renders a dynamic form with multiple field types directly inside the chat. It is ideal for collecting structured information that would be tedious to gather through back-and-forth messages. Common use cases:
  • Collect contact details or lead information
  • Gather shipping/billing addresses
  • Capture support ticket details
  • Run quick surveys or preference questionnaires
Configuration fields:

FieldTypeRequiredDescription
tool_typestringYesMust be "form_widget_tool"
tool_idstringYesUnique identifier for this widget instance
titlestringYesTitle displayed at the top of the form
submit_button_labelstringYesText on the submit button (e.g., "Submit")
form_fieldsarrayYesArray of field definitions (see below)
api_configobjectNoOptional API to call when the form is submitted
Form field definition:

FieldTypeRequiredDescription
keystringYesUnique field identifier
typestringYesField type (e.g., "text", "email", "select", "number")
descriptionstringYesLabel/placeholder text for the field
requiredbooleanYesWhether the field is mandatory
optionsarrayNoOptions list for select/dropdown fields
Example configuration:
{
  "tool_type": "form_widget_tool",
  "tool_id": "contact_form",
  "title": "Contact Information",
  "submit_button_label": "Submit Details",
  "form_fields": [
    {
      "key": "full_name",
      "type": "text",
      "description": "Full Name",
      "required": true,
      "options": []
    },
    {
      "key": "email",
      "type": "email",
      "description": "Email Address",
      "required": true,
      "options": []
    },
    {
      "key": "preferred_plan",
      "type": "select",
      "description": "Preferred Plan",
      "required": false,
      "options": ["Basic", "Pro", "Enterprise"]
    }
  ],
  "api_config": {
    "url": "https://your-api.com/contacts",
    "method": "POST",
    "headers": {
      "Content-Type": "application/json"
    },
    "body": {}
  }
}
When the user submits the form, the collected data is sent back to the assistant. If an api_config is provided, the data is also forwarded to your API endpoint.

Complete Example: Chat Agent with Callback Scheduling

Here is a full example of embedding a chat-only assistant with callback scheduling enabled:
<script>
  function loadAgentsCdn(e, t) {
    let n = document.createElement("link");
    n.rel = "stylesheet", n.type = "text/css", n.href = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${e}/dist/style.css`;
    var a = document.createElement("script");
    a.type = "text/javascript", a.onload = function() { t() },
    a.src = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${e}/dist/dv-agent.es.js`,
    document.getElementsByTagName("head")[0].appendChild(n),
    document.getElementsByTagName("head")[0].appendChild(a)
  }
</script>

<script>
  loadAgentsCdn("latest", function() {
    loadAgent({
      agentId: "your-chat-agent-id",
      xApiKey: "your-api-key",

      // Chat-only mode
      defaultTab: "text",
      hideTabSelector: true,

      // Branding
      title: "Support Chat",
      description: "Hi! I can help you schedule a callback or answer your questions.",
      logoUrl: "https://example.com/your-logo.svg",

      // Widget appearance
      buttons: {
        modalTrigger: {
          styles: {
            backgroundColor: "#4F46E5",
          },
          icon: {
            url: "https://example.com/chat-icon.svg",
            size: 24,
          },
        },
      },

      // Feedback after conversation
      feedbackScreen: {
        title: "How was your chat?",
        description: "Your feedback helps us improve!",
        submitBtnCTA: "Submit",
      },
    });
  });
</script>
The calendar and form widgets are configured in the assistant’s metadata through the Ringg AI dashboard — no additional frontend code is needed. See the prompt examples below for how to instruct the assistant to use them.

Prompt Examples for Chat Agents

Your assistant’s prompt (configured in the Ringg AI dashboard) controls when and how it uses widgets. Below are ready-to-use prompt examples for common chat scenarios.

Chat Agent with Callback Scheduling

You are a friendly support assistant for [Company Name]. You help users with
their questions and can schedule callbacks with our team.

Guidelines:
- Greet the user warmly and ask how you can help.
- Answer questions using the knowledge base when available.
- If the user wants to speak to a human agent, schedule a call, or book a demo,
  present the calendar widget so they can pick a convenient time slot.
- After the user selects a time slot, confirm the booking with the date, time,
  and timezone in a clear, human-readable format.
- Keep responses concise and conversational — this is a chat, not an email.

Chat Agent with Form Collection

You are a lead qualification assistant for [Company Name]. Your goal is to
understand the user's needs and collect their contact information.

Guidelines:
- Start by understanding what the user is looking for.
- Once you have enough context about their needs, present the contact form
  widget to collect their details (name, email, phone, preferred plan).
- After the form is submitted, thank the user and let them know a team member
  will follow up shortly.
- Do not ask for information that the form will collect — let the form handle it.

Chat Agent with Both Calendar and Form

You are a customer support assistant for [Company Name]. You can help users
with questions, collect information, and schedule callbacks.

Guidelines:
- Greet the user and ask how you can help.
- For general questions, answer directly using available knowledge.
- If the user needs to speak with a human agent or wants a demo:
  → Present the calendar widget to schedule a callback.
- If the user wants to submit a request, provide feedback, or share details:
  → Present the form widget to collect their information.
- Always confirm the action after a widget interaction (e.g., "Your callback
  is booked for Tuesday at 2:00 PM" or "Thanks! We've received your details").
- Keep responses short and friendly.

Tips for Writing Chat Prompts

  • Be explicit about when to use widgets — tell the assistant exactly which situations should trigger the calendar or form widget.
  • Don’t duplicate widget fields in conversation — if the form collects the user’s email, don’t ask for it in chat first.
  • Confirm after widget interactions — instruct the assistant to acknowledge bookings and form submissions clearly.
  • Keep it conversational — chat prompts should produce shorter, more casual responses than voice prompts.