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

# Implement a Sales Playbook Using LLM Gateway

This guide will show you how to use AssemblyAI's LLM Gateway to implement a sales playbook with a call from a sales representative to a client.

This guide aims to show different ways of using structured prompts with a hypothetical sales use case to produce personalized, precise responses. Using LLM Gateway, a user can immediately evaluate large numbers of sales calls and ensure that prospecting steps are followed, including quotes in the response, which can inform future sales by identifying trends and quantitative performance tracking.

In this example, we will demonstrate how to use structured prompts with context, answer formats, and answer options to create effective sales call evaluations with [LLM Gateway](/llm-gateway/quickstart). You can use the concepts in this guide to create custom specifications to evaluate your sales representatives.

## Quickstart

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```python expandable theme={null}
    import requests
    import time

    base_url = "https://api.assemblyai.com"
    headers = {"authorization": "<YOUR_API_KEY>"}

    # Step 1: Transcribe the sales call
    with open("./sales-call.mp3", "rb") as f:
        response = requests.post(base_url + "/v2/upload", headers=headers, data=f)

    upload_url = response.json()["upload_url"]
    data = {"audio_url": upload_url}

    response = requests.post(base_url + "/v2/transcript", json=data, headers=headers)
    transcript_id = response.json()['id']
    polling_endpoint = base_url + "/v2/transcript/" + transcript_id

    while True:
        transcription_result = requests.get(polling_endpoint, headers=headers).json()
        if transcription_result['status'] == 'completed':
            break
        elif transcription_result['status'] == 'error':
            raise RuntimeError(f"Transcription failed: {transcription_result['error']}")
        else:
            time.sleep(3)

    # Step 2: Evaluate with LLM Gateway
    context = "There are sales interactions between a salesperson who is selling an internet plan to customers who are warm leads."
    answer_format = """
    Answer with JSON in the following format:
    {
        "Answer": "<answer_options>",
        "Reason": "<justification for the answer in one sentence including quotes>"
    }
    """

    questions = [
        {
            "question": "Did the salesperson start the conversation with a professional greeting?",
            "answer_options": ["Poor", "Satisfactory", "Excellent"]
        },
        {
            "question": "How well did the salesperson answer questions during the call?",
            "answer_options": ["Poor", "Good", "Excellent"]
        },
        {
            "question": "Did the salesperson discuss next steps clearly?",
            "answer_options": ["Yes", "No"]
        }
    ]

    for q in questions:
        prompt = f"""
    {q['question']}

    Context: {context}

    Answer Options: {', '.join(q['answer_options'])}

    {answer_format}
    """

        llm_gateway_data = {
            "model": "claude-sonnet-4-6",
            "messages": [
                {"role": "user", "content": f"{prompt}\n\n{{{{ transcript }}}}"}
            ],
            "transcript_id": transcript_id,
            "max_tokens": 500
        }

        response = requests.post(
            "https://llm-gateway.assemblyai.com/v1/chat/completions",
            headers=headers,
            json=llm_gateway_data
        )

        result = response.json()["choices"][0]["message"]["content"]
        print(f"Question: {q['question']}")
        print(f"Answer: {result}")
        print()
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```javascript expandable theme={null}
    import fs from "fs-extra";

    const baseUrl = "https://api.assemblyai.com";
    const headers = { authorization: "<YOUR_API_KEY>" };

    // Step 1: Transcribe the sales call
    const audioData = await fs.readFile("./sales-call.mp3");
    let res = await fetch(`${baseUrl}/v2/upload`, {
      method: "POST",
      headers,
      body: audioData,
    });
    if (!res.ok) throw new Error(`Error: ${res.status}`);
    const uploadResponse = await res.json();
    const uploadUrl = uploadResponse.upload_url;

    const data = { audio_url: uploadUrl };

    res = await fetch(`${baseUrl}/v2/transcript`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    if (!res.ok) throw new Error(`Error: ${res.status}`);
    const transcriptResponse = await res.json();
    const transcriptId = transcriptResponse.id;
    const pollingEndpoint = `${baseUrl}/v2/transcript/${transcriptId}`;

    let transcriptionResult;
    while (true) {
      res = await fetch(pollingEndpoint, { headers });
      if (!res.ok) throw new Error(`Error: ${res.status}`);
      transcriptionResult = await res.json();
      if (transcriptionResult.status === "completed") {
        break;
      } else if (transcriptionResult.status === "error") {
        throw new Error(`Transcription failed: ${transcriptionResult.error}`);
      } else {
        await new Promise((resolve) => setTimeout(resolve, 3000));
      }
    }

    // Step 2: Evaluate with LLM Gateway
    const context = "There are sales interactions between a salesperson who is selling an internet plan to customers who are warm leads.";
    const answerFormat = `
    Answer with JSON in the following format:
    {
        "Answer": "<answer_options>",
        "Reason": "<justification for the answer in one sentence including quotes>"
    }
    `;

    const questions = [
      {
        question: "Did the salesperson start the conversation with a professional greeting?",
        answerOptions: ["Poor", "Satisfactory", "Excellent"]
      },
      {
        question: "How well did the salesperson answer questions during the call?",
        answerOptions: ["Poor", "Good", "Excellent"]
      },
      {
        question: "Did the salesperson discuss next steps clearly?",
        answerOptions: ["Yes", "No"]
      }
    ];

    for (const q of questions) {
      const prompt = `
    ${q.question}

    Context: ${context}

    Answer Options: ${q.answerOptions.join(", ")}

    ${answerFormat}
    `;

      const llmGatewayData = {
        model: "claude-sonnet-4-6",
        messages: [
          { role: "user", content: `${prompt}\n\n{{ transcript }}` }
        ],
        transcript_id: transcriptId,
        max_tokens: 500
      };

      res = await fetch("https://llm-gateway.assemblyai.com/v1/chat/completions", {
        method: "POST",
        headers: { ...headers, "Content-Type": "application/json" },
        body: JSON.stringify(llmGatewayData),
      });
      if (!res.ok) throw new Error(`Error: ${res.status}`);
      const response = await res.json();

      const result = response.choices[0].message.content;
      console.log(`Question: ${q.question}`);
      console.log(`Answer: ${result}`);
      console.log();
    }
    ```
  </Tab>
</Tabs>

## Get Started

Before we begin, make sure you have an AssemblyAI account and an API key. You can [sign up for an AssemblyAI account](https://www.assemblyai.com/dashboard/home) and get your API key from your dashboard.

## Step-by-Step Instructions

In this guide, we will ask three questions evaluating the prospecting performance of the sales representative. Each question has slightly different parameters based on the use case but largely has a fixed `context` that we will apply to each question.

Install the required packages:

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```bash theme={null}
    pip install requests
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```bash theme={null}
    npm install fs-extra
    ```
  </Tab>
</Tabs>

Set up the API client:

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```python theme={null}
    import requests
    import time

    base_url = "https://api.assemblyai.com"
    headers = {"authorization": "<YOUR_API_KEY>"}
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```javascript theme={null}
    import fs from "fs-extra";

    const baseUrl = "https://api.assemblyai.com";
    const headers = { authorization: "<YOUR_API_KEY>" };
    ```
  </Tab>
</Tabs>

Transcribe the sales call audio file:

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```python theme={null}
    with open("./sales-call.mp3", "rb") as f:
        response = requests.post(base_url + "/v2/upload", headers=headers, data=f)

    upload_url = response.json()["upload_url"]
    data = {"audio_url": upload_url}  # You can also use a URL to an audio or video file on the web

    response = requests.post(base_url + "/v2/transcript", json=data, headers=headers)
    transcript_id = response.json()['id']
    polling_endpoint = base_url + "/v2/transcript/" + transcript_id

    while True:
        transcription_result = requests.get(polling_endpoint, headers=headers).json()

        if transcription_result['status'] == 'completed':
            print(f"Transcription completed: {transcript_id}")
            break
        elif transcription_result['status'] == 'error':
            raise RuntimeError(f"Transcription failed: {transcription_result['error']}")
        else:
            time.sleep(3)
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```javascript expandable theme={null}
    const audioData = await fs.readFile("./sales-call.mp3");
    let res = await fetch(`${baseUrl}/v2/upload`, {
      method: "POST",
      headers,
      body: audioData,
    });
    if (!res.ok) throw new Error(`Error: ${res.status}`);
    const uploadResponse = await res.json();
    const uploadUrl = uploadResponse.upload_url;

    const data = { audio_url: uploadUrl }; // You can also use a URL to an audio or video file on the web

    res = await fetch(`${baseUrl}/v2/transcript`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    if (!res.ok) throw new Error(`Error: ${res.status}`);
    const transcriptResponse = await res.json();
    const transcriptId = transcriptResponse.id;
    const pollingEndpoint = `${baseUrl}/v2/transcript/${transcriptId}`;

    let transcriptionResult;
    while (true) {
      res = await fetch(pollingEndpoint, { headers });
      if (!res.ok) throw new Error(`Error: ${res.status}`);
      transcriptionResult = await res.json();

      if (transcriptionResult.status === "completed") {
        console.log(`Transcription completed: ${transcriptId}`);
        break;
      } else if (transcriptionResult.status === "error") {
        throw new Error(`Transcription failed: ${transcriptionResult.error}`);
      } else {
        await new Promise((resolve) => setTimeout(resolve, 3000));
      }
    }
    ```
  </Tab>
</Tabs>

Define your evaluation context and answer format for structured responses:

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```python theme={null}
    context = "There are sales interactions between a salesperson who is selling an internet plan to customers who are warm leads."
    answer_format = """
    Answer with JSON in the following format:
    {
        "Answer": "<answer_options>",
        "Reason": "<justification for the answer in one sentence including quotes>"
    }
    """
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```javascript theme={null}
    const context = "There are sales interactions between a salesperson who is selling an internet plan to customers who are warm leads.";
    const answerFormat = `
    Answer with JSON in the following format:
    {
        "Answer": "<answer_options>",
        "Reason": "<justification for the answer in one sentence including quotes>"
    }
    `;
    ```
  </Tab>
</Tabs>

Next, define your evaluation questions for your sales playbook processes. Note: You can edit the questions and answer options to provide custom evaluations for each aspect of the sales call.

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```python theme={null}
    questions = [
        {
            "question": "Did the salesperson start the conversation with a professional greeting?",
            "answer_options": ["Poor", "Satisfactory", "Excellent"]
        },
        {
            "question": "How well did the salesperson answer questions during the call?",
            "answer_options": ["Poor", "Good", "Excellent"]
        },
        {
            "question": "Did the salesperson discuss next steps clearly?",
            "answer_options": ["Yes", "No"]
        }
    ]
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```javascript theme={null}
    const questions = [
      {
        question: "Did the salesperson start the conversation with a professional greeting?",
        answerOptions: ["Poor", "Satisfactory", "Excellent"]
      },
      {
        question: "How well did the salesperson answer questions during the call?",
        answerOptions: ["Poor", "Good", "Excellent"]
      },
      {
        question: "Did the salesperson discuss next steps clearly?",
        answerOptions: ["Yes", "No"]
      }
    ];
    ```
  </Tab>
</Tabs>

Evaluate each question using LLM Gateway and print the results:

<Tabs groupId="language">
  <Tab language="python" title="Python" default>
    ```python expandable theme={null}
    for q in questions:
        prompt = f"""
    {q['question']}

    Context: {context}

    Answer Options: {', '.join(q['answer_options'])}

    {answer_format}
    """

        llm_gateway_data = {
            "model": "claude-sonnet-4-6",
            "messages": [
                {"role": "user", "content": f"{prompt}\n\n{{{{ transcript }}}}"}
            ],
            "transcript_id": transcript_id,
            "max_tokens": 500
        }

        response = requests.post(
            "https://llm-gateway.assemblyai.com/v1/chat/completions",
            headers=headers,
            json=llm_gateway_data
        )

        result = response.json()["choices"][0]["message"]["content"]
        print(f"Question: {q['question']}")
        print(f"Answer: {result}")
        print()
    ```
  </Tab>

  <Tab language="javascript" title="JavaScript">
    ```javascript expandable theme={null}
    for (const q of questions) {
      const prompt = `
    ${q.question}

    Context: ${context}

    Answer Options: ${q.answerOptions.join(", ")}

    ${answerFormat}
    `;

      const llmGatewayData = {
        model: "claude-sonnet-4-6",
        messages: [
          { role: "user", content: `${prompt}\n\n{{ transcript }}` }
        ],
        transcript_id: transcriptId,
        max_tokens: 500
      };

      let res = await fetch("https://llm-gateway.assemblyai.com/v1/chat/completions", {
        method: "POST",
        headers: { ...headers, "Content-Type": "application/json" },
        body: JSON.stringify(llmGatewayData),
      });
      if (!res.ok) throw new Error(`Error: ${res.status}`);
      const response = await res.json();

      const result = response.choices[0].message.content;
      console.log(`Question: ${q.question}`);
      console.log(`Answer: ${result}`);
      console.log();
    }
    ```
  </Tab>
</Tabs>
