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

> ## Agent Instructions
> To search or read these docs, connect the Ringg docs MCP server at https://docs.ringg.ai/mcp (no key needed; tools search_ringg_ai and query_docs_filesystem_ringg_ai) instead of browsing pages one by one. Setup for each client: https://docs.ringg.ai/resources/mcp-server/docs-mcp-server/mcp-for-ai-assistants.md
> The dashboard labels agents "Assistants"; these docs say "agent". Both mean the same object, identified by agent_id.
> API base URL: https://prod-api.ringg.ai/ca/api/v0. Send the workspace API key in the X-API-KEY header, from server-side code only.
> Placing a call dials a real phone number and spends credits. Confirm the number with the user before calling.
> To act on a Ringg workspace (place calls, edit agents, read transcripts), use the separate Ringg workspace MCP server at https://mcp.ringg.ai/mcp: https://docs.ringg.ai/resources/mcp-server/workspace-mcp-server/overview.md

# Lesson: Voice and language

> Confirm the EMI reminder agent's languages, compare voices by provider and tag, preview them in English and Hindi, set the speaking speed, and save.

export const Quiz = ({question, answers, correctFeedback, incorrectFeedback}) => {
  const [selected, setSelected] = React.useState(null);
  const [checked, setChecked] = React.useState(false);
  const quizId = React.useId();
  const isCorrect = checked && answers[selected]?.correct;
  const reset = () => {
    setSelected(null);
    setChecked(false);
  };
  const optionStyle = (answer, i) => {
    const base = {
      display: "flex",
      alignItems: "flex-start",
      gap: "0.6rem",
      padding: "0.6rem 0.8rem",
      marginTop: "0.5rem",
      borderRadius: "0.6rem",
      border: "1px solid rgba(128, 128, 128, 0.35)",
      cursor: checked ? "default" : "pointer",
      lineHeight: 1.45
    };
    if (checked && answer.correct) {
      return {
        ...base,
        borderColor: "rgba(22, 163, 74, 0.8)",
        background: "rgba(22, 163, 74, 0.12)"
      };
    }
    if (checked && selected === i && !answer.correct) {
      return {
        ...base,
        borderColor: "rgba(220, 38, 38, 0.8)",
        background: "rgba(220, 38, 38, 0.1)"
      };
    }
    if (!checked && selected === i) {
      return {
        ...base,
        borderColor: "currentColor",
        background: "rgba(128, 128, 128, 0.12)"
      };
    }
    return base;
  };
  const buttonStyle = disabled => ({
    marginTop: "0.9rem",
    padding: "0.45rem 0.9rem",
    borderRadius: "0.5rem",
    border: "1px solid rgba(128, 128, 128, 0.5)",
    background: "rgba(128, 128, 128, 0.1)",
    color: "inherit",
    font: "inherit",
    fontSize: "0.9em",
    cursor: disabled ? "not-allowed" : "pointer",
    opacity: disabled ? 0.5 : 1
  });
  return <div style={{
    marginTop: "1.5rem",
    padding: "1rem 1.1rem",
    borderRadius: "0.8rem",
    border: "1px solid rgba(128, 128, 128, 0.35)"
  }}>
      <Badge color="green">Quiz</Badge>
      <p id={quizId + "-question"} style={{
    fontWeight: 600,
    margin: "0.6rem 0 0.2rem"
  }}>
        {question}
      </p>
      <div role="radiogroup" aria-labelledby={quizId + "-question"} aria-disabled={checked}>
        {answers.map((answer, i) => <label key={i} style={optionStyle(answer, i)}>
            <input type="radio" name={"quiz-" + quizId} checked={selected === i} onChange={() => !checked && setSelected(i)} disabled={checked} style={{
    marginTop: "0.3rem",
    flexShrink: 0
  }} />
            <span>{answer.text}</span>
          </label>)}
      </div>
      {checked && <div role="status" aria-live="polite" aria-atomic="true" style={{
    marginTop: "0.9rem",
    padding: "0.7rem 0.9rem",
    borderRadius: "0.6rem",
    lineHeight: 1.5,
    background: isCorrect ? "rgba(22, 163, 74, 0.12)" : "rgba(220, 38, 38, 0.1)"
  }}>
          <strong style={{
    marginRight: "0.4rem"
  }}>{isCorrect ? "✓" : "✗"}</strong>
          {isCorrect ? correctFeedback : incorrectFeedback}
        </div>}
      {!checked ? <button type="button" onClick={() => selected !== null && setChecked(true)} disabled={selected === null} style={buttonStyle(selected === null)}>
          Check answer
        </button> : <button type="button" onClick={reset} style={buttonStyle(false)}>
          Try again
        </button>}
    </div>;
};

export const RelatedTopics = ({items}) => <div className="not-prose mt-12">
    <div className="text-sm font-medium text-gray-500 dark:text-zinc-400 mb-3">Related topics</div>
    <div className="flex flex-col gap-2.5">
      {items.map(([title, href]) => <a key={href} href={href} className="flex items-center gap-2.5 text-sm text-gray-700 hover:text-gray-950 dark:text-zinc-300 dark:hover:text-white">
          <Icon icon="file-text" size={16} color="currentColor" />
          {title}
        </a>)}
    </div>
  </div>;

**Part 2: Building your first agent · Lesson 3 of 4 · 10 minutes**

## Objective

Compare voices properly, hear Ananya in both of her languages, pick a speaking speed, and confirm Hindi stays her secondary language.

## The scenario

Acme's callers speak English or Hindi, and Ananya reads out an amount and a date on every call. Lesson 1 picked a voice in a hurry; this is where the choice gets made.

## Hands-on

<Frame caption="Changing language, voice and speed in the dashboard">
  <video alt="Changing language, voice and speed in the dashboard" aria-label="Changing language, voice and speed in the dashboard" controls muted playsInline className="w-full rounded-xl" style={{ aspectRatio: "16 / 10" }} preload="metadata" controlsList="nodownload noremoteplayback" poster="/media/agents-voice/poster.webp">
    <source src="https://mintcdn.com/ringgai-0da73d20/zhzhS2waLZvF8qXk/media/agents-voice/video.webm?fit=max&auto=format&n=zhzhS2waLZvF8qXk&q=85&s=a750c1bb68f10cd2817b17fca9fe2912" type="video/webm; codecs=&#x22;av01.0.09M.08&#x22;" data-path="media/agents-voice/video.webm" />
  </video>
</Frame>

<Steps>
  <Step title="Open the Voice section">
    In the agent editor, click **Voice**. It has three parts, **Language**, **Voice** and **Voice speed**, and one **Save** button at the bottom for all of them.
  </Step>

  <Step title="Confirm the languages">
    **Primary Language** should read English (India) and **Secondary Language** Hindi, as set when you created the agent. Do not change the primary language now: changing it clears the secondary language and the selected voice, and you would have to pick both again.

    Leave **Add more languages** alone. Additional languages are for callers who speak languages the agent does not, and saving them switches the speech-to-text provider; Acme's callers speak English or Hindi, which are already covered.
  </Step>

  <Step title="Narrow the grid">
    The **Voice** part lists voices that speak the primary or secondary language. The tabs along the top are **All** and one tab per voice provider in the list; the tag chips under them narrow it further, and combine, so a voice must have every selected tag. Click **Clear** to reset. Click **See more** if the voice you want is not in the first rows.
  </Step>

  <Step title="Compare three voices in both languages">
    Clicking a voice selects it and plays its preview. Because Ananya has a secondary language, the **Preview language** icon next to the tabs switches the preview between English and Hindi: listen to each candidate in both before deciding. A voice that cannot speak the primary language opens a **Change agent language?** dialog; click **Cancel** and pick another.
  </Step>

  <Step title="Set the speed">
    **Voice speed** has six steps from **0.7x** to **1.2x**, with **1.0x** the default. The play button beside it previews the selected voice at that speed. Ananya reads out an amount and a date, so compare **0.9x** and **1.0x** and keep the one where "four thousand five hundred rupees" is easiest to follow.
  </Step>

  <Step title="Save">
    Click **Save**.
  </Step>
</Steps>

## Checkpoint

<Check>
  "Voice settings saved" appears, **Save** is disabled again, and the voice you chose is first in the grid.
</Check>

## Exercise

Give the speech recogniser the words it is most likely to mishear on Acme's calls. Under **Advanced Settings → Keyword Boosting**, type `Acme Lending, EMI, NACH` and click **Add**. Expected result: "Vocabulary updated successfully" appears and each word shows as a chip below the field; there is no separate **Save** for this list.

## What you learned

* Language, voice and speed are one section with one **Save**; changing the primary language clears the secondary language and the voice.
* With a secondary language, the **Preview language** icon lets you hear a voice in both languages before you commit.
* Speed runs from 0.7x to 1.2x, default 1.0x, and the play button previews the selected voice at the chosen speed.

<Quiz
  question="Acme decides Ananya should speak Marathi as her primary language instead of English (India). What happens when you change Primary Language?"
  answers={[
{ text: "Only the voice grid refreshes; everything else stays", correct: false },
{ text: "The secondary language and the selected voice are cleared, so you pick both again", correct: true },
{ text: "The speed resets to 1.0x and the voice stays", correct: false },
{ text: "Nothing changes until you place a test call", correct: false },
]}
  correctFeedback="Right. Changing the primary language clears the secondary language and the selected voice, because the voice grid lists only voices that speak the agent's languages. Speed is untouched. That is why the lesson keeps the primary language as it was."
  incorrectFeedback="Not quite. The primary language decides which voices are offered, so changing it clears the secondary language and the selected voice; you choose both again and save. Speed is not affected."
/>

<RelatedTopics items={[["Voice and language", "/documentation/build-agents/customize-agent-behaviour/voice-and-language"], ["Write prompts for voice", "/documentation/build-agents/customize-agent-behaviour/agent-prompt#write-prompts-for-voice"]]} />


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.